Skip to content

Commit e80ca60

Browse files
authored
Merge pull request #91 from spacesvr/dev
v2.0.2
2 parents 542fff4 + 293cc89 commit e80ca60

File tree

6 files changed

+68
-29
lines changed

6 files changed

+68
-29
lines changed

examples/worlds/Multiplayer/index.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ export default function Multiplayer() {
55
return (
66
<StandardReality
77
playerProps={{ pos: [5, 1, 0], rot: Math.PI }}
8-
networkProps={{
9-
host: "https://muse-web-pr-49.onrender.com",
10-
autoconnect: true,
11-
}}
8+
networkProps={{ autoconnect: true }}
129
>
1310
<Background color={0xffffff} />
1411
<fog attach="fog" args={[0xffffff, 10, 90]} />

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "spacesvr",
3-
"version": "2.0.1",
3+
"version": "2.0.2",
44
"private": true,
55
"description": "A standardized reality for future of the 3D Web",
66
"keywords": [
@@ -46,6 +46,7 @@
4646
"dependencies": {
4747
"@emotion/react": "^11.4.0",
4848
"@emotion/styled": "^11.3.0",
49+
"@geckos.io/snapshot-interpolation": "^1.1.0",
4950
"@juggle/resize-observer": "^3.2.0",
5051
"@react-spring/three": "^9.4.5",
5152
"@react-three/cannon": "^6.3.0",

src/layers/Environment/ui/PauseMenu/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export default function PauseMenu(props: PauseMenuProps) {
4848
const PAUSE_ITEMS: PauseItem[] = [
4949
...pauseMenuItems,
5050
{
51-
text: "v2.0.1",
51+
text: "v2.0.2",
5252
link: "https://www.npmjs.com/package/spacesvr",
5353
},
5454
...menuItems,

src/layers/Network/ideas/NetworkedEntities.tsx

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
import { useMemo, useRef, useState } from "react";
2-
import { useFrame } from "@react-three/fiber";
32
import {
43
CylinderBufferGeometry,
54
InstancedMesh,
65
MeshNormalMaterial,
76
Object3D,
87
} from "three";
98
import { useNetwork } from "../logic/network";
10-
import { useLimitedFrame, useLimiter } from "../../../logic/limiter";
9+
import { useLimitedFrame } from "../../../logic/limiter";
10+
import { SnapshotInterpolation } from "@geckos.io/snapshot-interpolation";
11+
import {
12+
Snapshot,
13+
Entity as EntityState,
14+
Quat,
15+
} from "@geckos.io/snapshot-interpolation/lib/types";
1116

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

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

38+
const NETWORK_FPS = 12;
3339
type Entity = { pos: number[]; rot: number[] };
40+
const SI = useMemo(() => new SnapshotInterpolation(NETWORK_FPS), []);
3441
const entityChannel = useChannel<Entity, { [key in string]: Entity }>(
3542
"player",
3643
"stream",
3744
(m, s) => {
3845
if (!m.conn) return;
3946
s[m.conn.peer] = m.data;
47+
48+
const state: EntityState[] = Object.keys(s).map((key) => ({
49+
id: key,
50+
x: s[key].pos[0],
51+
y: s[key].pos[1],
52+
z: s[key].pos[2],
53+
q: {
54+
x: s[key].rot[0],
55+
y: s[key].rot[1],
56+
z: s[key].rot[2],
57+
w: s[key].rot[3],
58+
},
59+
}));
60+
61+
const snapshot: Snapshot = {
62+
id: Math.random().toString(),
63+
time: new Date().getTime(),
64+
state,
65+
};
66+
67+
SI.vault.add(snapshot);
4068
}
4169
);
4270

4371
// send own player data
44-
useLimitedFrame(15, ({ camera }) => {
72+
useLimitedFrame(NETWORK_FPS, ({ camera }) => {
4573
if (!connected) return;
4674
entityChannel.send({
47-
pos: camera.position.toArray().map((p) => parseFloat(p.toPrecision(3))),
48-
rot: camera.rotation
49-
.toArray()
50-
.slice(0, 3)
51-
.map((r) => parseFloat(r.toPrecision(3))),
75+
pos: camera.position.toArray(),
76+
rot: camera.quaternion.toArray(),
5277
});
5378
});
5479

5580
// receive player data
56-
useLimitedFrame(50, () => {
81+
useLimitedFrame(55, () => {
5782
if (!mesh.current) return;
58-
for (const id of Object.keys(entityChannel.state)) {
59-
const index = entityIds.indexOf(id);
60-
if (index < 0) return;
61-
const { pos, rot } = entityChannel.state[id];
62-
obj.position.fromArray(pos);
63-
obj.rotation.fromArray(rot);
83+
84+
const snapshot = SI.calcInterpolation("x y z q(quat)");
85+
if (!snapshot) return;
86+
87+
let i = 0;
88+
for (const entityState of snapshot.state) {
89+
const { x, y, z, q } = entityState;
90+
obj.position.x = x as number;
91+
obj.position.y = y as number;
92+
obj.position.z = z as number;
93+
obj.position.y -= 0.2; // they were floating before, idk where the constant comes from really
94+
const quat = q as Quat;
95+
obj.quaternion.x = quat.x;
96+
obj.quaternion.y = quat.y;
97+
obj.quaternion.z = quat.z;
98+
obj.quaternion.w = quat.w;
6499
obj.updateMatrix();
65-
mesh.current?.setMatrixAt(index, obj.matrix);
100+
mesh.current.setMatrixAt(i, obj.matrix);
101+
i++;
66102
}
67-
});
68103

69-
const renderLimiter = useLimiter(40);
70-
useFrame(({ clock }) => {
71-
if (!mesh.current || !renderLimiter.isReady(clock)) return;
72104
mesh.current.instanceMatrix.needsUpdate = true;
73105
});
74106

src/layers/Network/index.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import NetworkedEntities from "./ideas/NetworkedEntities";
2-
import { ReactNode, useEffect } from "react";
2+
import { ReactNode, useEffect, useRef } from "react";
33
import { ConnectionConfig, useConnection } from "./logic/connection";
44
import { NetworkContext } from "./logic/network";
55
export * from "./logic/network";
@@ -23,8 +23,12 @@ export function Network(props: NetworkLayerProps) {
2323
}, [autoconnect, connected]);
2424

2525
// log status on changes
26+
const lastVal = useRef(false);
2627
useEffect(() => {
27-
console.info(`network ${connected ? "connected" : "disconnected"}`);
28+
if (lastVal.current !== connected) {
29+
console.info(`network ${connected ? "connected" : "disconnected"}`);
30+
lastVal.current = connected;
31+
}
2832
}, [connected]);
2933

3034
// disconnect on the way out (i hope it works)

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,11 @@
11431143
minimatch "^3.0.4"
11441144
strip-json-comments "^3.1.1"
11451145

1146+
"@geckos.io/snapshot-interpolation@^1.1.0":
1147+
version "1.1.0"
1148+
resolved "https://registry.yarnpkg.com/@geckos.io/snapshot-interpolation/-/snapshot-interpolation-1.1.0.tgz#d89a29930b859838b8403eeebc7683f343efa752"
1149+
integrity sha512-Hu+tZuMpBZTyPMgqHkgv78fIzCrTpz5DeyaAktwaGL8tyYaNTGrtR9TrtKzBKgpt0YNlpHYJrT0TAfGzrl1XVw==
1150+
11461151
"@humanwhocodes/config-array@^0.5.0":
11471152
version "0.5.0"
11481153
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9"

0 commit comments

Comments
 (0)