Skip to content

Network Improvements #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions examples/worlds/Multiplayer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ export default function Multiplayer() {
return (
<StandardReality
playerProps={{ pos: [5, 1, 0], rot: Math.PI }}
networkProps={{
host: "https://muse-web-pr-49.onrender.com",
autoconnect: true,
}}
networkProps={{ autoconnect: true }}
>
<Background color={0xffffff} />
<fog attach="fog" args={[0xffffff, 10, 90]} />
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"dependencies": {
"@emotion/react": "^11.4.0",
"@emotion/styled": "^11.3.0",
"@geckos.io/snapshot-interpolation": "^1.1.0",
"@juggle/resize-observer": "^3.2.0",
"@react-spring/three": "^9.4.5",
"@react-three/cannon": "^6.3.0",
Expand Down
74 changes: 53 additions & 21 deletions src/layers/Network/ideas/NetworkedEntities.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
import { useMemo, useRef, useState } from "react";
import { useFrame } from "@react-three/fiber";
import {
CylinderBufferGeometry,
InstancedMesh,
MeshNormalMaterial,
Object3D,
} from "three";
import { useNetwork } from "../logic/network";
import { useLimitedFrame, useLimiter } from "../../../logic/limiter";
import { useLimitedFrame } from "../../../logic/limiter";
import { SnapshotInterpolation } from "@geckos.io/snapshot-interpolation";
import {
Snapshot,
Entity as EntityState,
Quat,
} from "@geckos.io/snapshot-interpolation/lib/types";

export default function NetworkedEntities() {
const { connections, connected, useChannel } = useNetwork();

const mesh = useRef<InstancedMesh>(null);
const geo = useMemo(() => new CylinderBufferGeometry(0.3, 0.3, 1, 30), []);
const geo = useMemo(() => new CylinderBufferGeometry(0.3, 0.3, 1, 32), []);
const mat = useMemo(() => new MeshNormalMaterial(), []);
const obj = useMemo(() => {
const o = new Object3D();
Expand All @@ -30,45 +35,72 @@ export default function NetworkedEntities() {
if (!sameIds) setEntityIds(ids);
});

const NETWORK_FPS = 12;
type Entity = { pos: number[]; rot: number[] };
const SI = useMemo(() => new SnapshotInterpolation(NETWORK_FPS), []);
const entityChannel = useChannel<Entity, { [key in string]: Entity }>(
"player",
"stream",
(m, s) => {
if (!m.conn) return;
s[m.conn.peer] = m.data;

const state: EntityState[] = Object.keys(s).map((key) => ({
id: key,
x: s[key].pos[0],
y: s[key].pos[1],
z: s[key].pos[2],
q: {
x: s[key].rot[0],
y: s[key].rot[1],
z: s[key].rot[2],
w: s[key].rot[3],
},
}));

const snapshot: Snapshot = {
id: Math.random().toString(),
time: new Date().getTime(),
state,
};

SI.vault.add(snapshot);
}
);

// send own player data
useLimitedFrame(15, ({ camera }) => {
useLimitedFrame(NETWORK_FPS, ({ camera }) => {
if (!connected) return;
entityChannel.send({
pos: camera.position.toArray().map((p) => parseFloat(p.toPrecision(3))),
rot: camera.rotation
.toArray()
.slice(0, 3)
.map((r) => parseFloat(r.toPrecision(3))),
pos: camera.position.toArray(),
rot: camera.quaternion.toArray(),
});
});

// receive player data
useLimitedFrame(50, () => {
useLimitedFrame(55, () => {
if (!mesh.current) return;
for (const id of Object.keys(entityChannel.state)) {
const index = entityIds.indexOf(id);
if (index < 0) return;
const { pos, rot } = entityChannel.state[id];
obj.position.fromArray(pos);
obj.rotation.fromArray(rot);

const snapshot = SI.calcInterpolation("x y z q(quat)");
if (!snapshot) return;

let i = 0;
for (const entityState of snapshot.state) {
const { x, y, z, q } = entityState;
obj.position.x = x as number;
obj.position.y = y as number;
obj.position.z = z as number;
obj.position.y -= 0.2; // they were floating before, idk where the constant comes from really
const quat = q as Quat;
obj.quaternion.x = quat.x;
obj.quaternion.y = quat.y;
obj.quaternion.z = quat.z;
obj.quaternion.w = quat.w;
obj.updateMatrix();
mesh.current?.setMatrixAt(index, obj.matrix);
mesh.current.setMatrixAt(i, obj.matrix);
i++;
}
});

const renderLimiter = useLimiter(40);
useFrame(({ clock }) => {
if (!mesh.current || !renderLimiter.isReady(clock)) return;
mesh.current.instanceMatrix.needsUpdate = true;
});

Expand Down
8 changes: 6 additions & 2 deletions src/layers/Network/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import NetworkedEntities from "./ideas/NetworkedEntities";
import { ReactNode, useEffect } from "react";
import { ReactNode, useEffect, useRef } from "react";
import { ConnectionConfig, useConnection } from "./logic/connection";
import { NetworkContext } from "./logic/network";
export * from "./logic/network";
Expand All @@ -23,8 +23,12 @@ export function Network(props: NetworkLayerProps) {
}, [autoconnect, connected]);

// log status on changes
const lastVal = useRef(false);
useEffect(() => {
console.info(`network ${connected ? "connected" : "disconnected"}`);
if (lastVal.current !== connected) {
console.info(`network ${connected ? "connected" : "disconnected"}`);
lastVal.current = connected;
}
}, [connected]);

// disconnect on the way out (i hope it works)
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,11 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"

"@geckos.io/snapshot-interpolation@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@geckos.io/snapshot-interpolation/-/snapshot-interpolation-1.1.0.tgz#d89a29930b859838b8403eeebc7683f343efa752"
integrity sha512-Hu+tZuMpBZTyPMgqHkgv78fIzCrTpz5DeyaAktwaGL8tyYaNTGrtR9TrtKzBKgpt0YNlpHYJrT0TAfGzrl1XVw==

"@humanwhocodes/config-array@^0.5.0":
version "0.5.0"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9"
Expand Down