Skip to content

Commit cc1cabf

Browse files
committed
xr now networking hands
1 parent 9044813 commit cc1cabf

File tree

4 files changed

+134
-44
lines changed

4 files changed

+134
-44
lines changed

generator/html/js/index.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const viewportSettings = {
4848
ground: "0xcbcbcb"
4949
}
5050

51+
const representationManager = new WebSocketRepresentationManager();
5152
const viewportManager = new ViewportManager(viewportSettings);
5253
const updateLoop = new UpdateManager();
5354

@@ -58,6 +59,8 @@ const clock = new THREE.Clock();
5859
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
5960
camera.position.set(0, 2, 3);
6061

62+
representationManager.AddRepresentation("player", camera)
63+
6164
const scene = new THREE.Scene();
6265
scene.background = new THREE.Color(viewportSettings.background);
6366

@@ -150,7 +153,7 @@ const nodeManager = new NodeManager(App);
150153
const schemaManager = new SchemaManager(requestManager, nodeManager);
151154

152155
if (RenderingConfiguration.XrEnabled) {
153-
InitXR(scene, renderer);
156+
InitXR(scene, renderer, updateLoop, representationManager, groundMesh);
154157
}
155158

156159
nodeManager.subscribeToParameterChange((param) => {
@@ -517,8 +520,7 @@ function onWindowResize() {
517520
window.addEventListener('resize', onWindowResize);
518521

519522

520-
const representationManager = new WebSocketRepresentationManager();
521-
representationManager.addRepresentation("player", camera)
523+
522524

523525
const websocketManager = new WebSocketManager(
524526
representationManager,

generator/html/js/websocket.js

+103-27
Original file line numberDiff line numberDiff line change
@@ -6,37 +6,68 @@ export class WebSocketRepresentationManager {
66
this.rerpresentations = new Map();
77
}
88

9-
addRepresentation(key, threeObj) {
9+
AddRepresentation(key, threeObj) {
1010
if (this.rerpresentations.has(key)) {
11-
throw new Error("representation manager already has a rep for key: " + key)
11+
console.warn("representation manager already has a rep for key: " + key)
12+
// throw new Error("representation manager already has a rep for key: " + key)
1213
}
1314
this.rerpresentations.set(key, threeObj)
1415
}
1516

16-
removeRepresentation(key, threeObj) {
17-
if (this.rerpresentations.has(key)) {
18-
throw new Error("representation manager already has a rep for key: " + key)
17+
RemoveRepresentation(key, threeObj) {
18+
if (!this.rerpresentations.has(key)) {
19+
throw new Error("representation manager does not have a rep for key: " + key)
1920
}
2021
this.rerpresentations.set(key, threeObj)
2122
}
2223

23-
toMessage() {
24+
ToMessage() {
2425
const message = [];
26+
27+
let pos = new THREE.Vector3();
28+
let rot = new THREE.Quaternion();
29+
2530
this.rerpresentations.forEach((threeObj, key) => {
26-
message.push({
27-
type: key,
28-
"position": {
29-
"x": threeObj.position.x,
30-
"y": threeObj.position.y,
31-
"z": threeObj.position.z,
32-
},
33-
"rotation": {
34-
"x": threeObj.quaternion.x,
35-
"y": threeObj.quaternion.y,
36-
"z": threeObj.quaternion.z,
37-
"w": threeObj.quaternion.w,
31+
if (!threeObj) {
32+
return;
33+
}
34+
35+
if (!threeObj.matrixWorld) {
36+
return;
37+
}
38+
39+
// Somethings wrong with the matrix world, let's not include this
40+
// representation
41+
const eles = threeObj.matrixWorld.elements;
42+
for(let i = 0; i < eles.length; i ++) {
43+
if (isNaN(eles[i]) || !isFinite(eles[i])) {
44+
return;
3845
}
39-
})
46+
}
47+
48+
try {
49+
const worldMatrix = threeObj.matrixWorld;
50+
pos.setFromMatrixPosition(worldMatrix)
51+
rot.setFromRotationMatrix(worldMatrix)
52+
message.push({
53+
type: key,
54+
"position": {
55+
"x": pos.x,
56+
"y": pos.y,
57+
"z": pos.z,
58+
},
59+
"rotation": {
60+
"x": rot.x,
61+
"y": rot.y,
62+
"z": rot.z,
63+
"w": rot.w,
64+
}
65+
})
66+
} catch (error) {
67+
console.error(error);
68+
// Expected output: ReferenceError: nonExistentFunction is not defined
69+
// (Note: the exact output may be browser-dependent)
70+
}
4071
});
4172
return message;
4273
}
@@ -103,6 +134,7 @@ export class WebSocketManager {
103134

104135
createPlayerObject(name, playerData) {
105136
const newPlayer = new THREE.Group();
137+
newPlayer.name = "player";
106138

107139
const sphere = new THREE.Mesh(
108140
this.playerConfiguration.playerGeometry,
@@ -152,6 +184,8 @@ export class WebSocketManager {
152184
newPlayer.position.x = playerData.position.x;
153185
newPlayer.position.y = playerData.position.y;
154186
newPlayer.position.z = playerData.position.z;
187+
188+
newPlayer.scale.set(0.25, 0.25, 0.25)
155189
this.scene.add(newPlayer);
156190

157191
return {
@@ -165,18 +199,53 @@ export class WebSocketManager {
165199
};
166200
}
167201

202+
createHandObject(handData) {
203+
console.log("creating hand")
204+
const hand = new THREE.Group();
205+
hand.name = "hand";
206+
207+
const sphere = new THREE.Mesh(
208+
this.playerConfiguration.playerGeometry,
209+
this.playerConfiguration.playerMaterial
210+
);
211+
sphere.scale.set(0.1, 0.1, 0.1)
212+
hand.add(sphere);
213+
214+
hand.position.x = handData.position.x;
215+
hand.position.y = handData.position.y;
216+
hand.position.z = handData.position.z;
217+
218+
this.scene.add(hand);
219+
220+
return {
221+
desiredPosition: handData.position,
222+
desiredRotation: handData.rotation,
223+
obj: hand,
224+
cleanup: () => {
225+
this.scene.remove(hand);
226+
}
227+
};
228+
}
229+
230+
168231
setupPlayer(key, playerData) {
169232
const resps = []
170233

171-
console.log(playerData);
172-
173234
if (playerData.representation) {
174235
playerData.representation.forEach((rep) => {
175236
switch (rep.type) {
176237
case "player":
177238
resps.push(this.createPlayerObject(playerData.name, rep))
178239
break;
179240

241+
case "left-hand":
242+
resps.push(this.createHandObject(rep));
243+
break;
244+
245+
case "right-hand":
246+
resps.push(this.createHandObject(rep));
247+
break;
248+
180249
default:
181250
break;
182251
}
@@ -203,7 +272,7 @@ export class WebSocketManager {
203272

204273
const q = new THREE.Quaternion(dr.x, dr.y, dr.z, dr.w);
205274
if (!rep.obj.quaternion.equals(q)) {
206-
rep.obj.quaternion.rotateTowards(q, delta *2);
275+
rep.obj.quaternion.rotateTowards(q, delta * 2);
207276
}
208277

209278
const pp = rep.obj.position;
@@ -260,9 +329,9 @@ export class WebSocketManager {
260329
playersUpdated[playerID] = true;
261330

262331
if (playerID in this.connectedPlayers && this.connectedPlayers[playerID].representation.length === serverPlayer.representation.length) {
263-
console.log("updating...")
264332
const player = this.connectedPlayers[playerID];
265333
for (let i = 0; i < player.representation.length; i++) {
334+
console.log("updating " + serverPlayer.representation[i].type)
266335
player.representation[i].desiredPosition.x = serverPlayer.representation[i].position.x;
267336
player.representation[i].desiredPosition.y = serverPlayer.representation[i].position.y;
268337
player.representation[i].desiredPosition.z = serverPlayer.representation[i].position.z;
@@ -274,6 +343,10 @@ export class WebSocketManager {
274343
}
275344

276345
} else {
346+
if (playerID in this.connectedPlayers) {
347+
this.removePlayer(playerID);
348+
}
349+
277350
// Create a new Player!
278351
this.setupPlayer(playerID, serverPlayer);
279352
}
@@ -284,12 +357,15 @@ export class WebSocketManager {
284357
if (updated) {
285358
continue;
286359
}
287-
288-
this.connectedPlayers[playerID].representation.forEach(rep => rep.cleanup());
289-
delete this.connectedPlayers[playerID];
360+
this.removePlayer(playerID);
290361
}
291362
}
292363

364+
removePlayer(playerID) {
365+
this.connectedPlayers[playerID].representation.forEach(rep => rep.cleanup());
366+
delete this.connectedPlayers[playerID];
367+
}
368+
293369
onMessage(evt) {
294370
const message = JSON.parse(evt.data);
295371

@@ -317,7 +393,7 @@ export class WebSocketManager {
317393
this.conn.send(JSON.stringify({
318394
"type": "Client-SetOrientation",
319395
"data": {
320-
"representation": this.representationManager.toMessage(),
396+
"representation": this.representationManager.ToMessage(),
321397
}
322398
}));
323399
}

generator/html/js/xr.js

+25-13
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,27 @@ let INTERSECTION;
1111
const tempMatrix = new THREE.Matrix4();
1212

1313

14-
export const InitXR = (scene, renderer, updateManager) => {
14+
export const InitXR = (scene, renderer, updateManager, representationManager, ground) => {
1515

16+
floor = ground;
1617
raycaster = new THREE.Raycaster();
1718

1819
console.log(renderer.xr)
1920
renderer.xr.addEventListener('sessionstart', () => {
2021
baseReferenceSpace = renderer.xr.getReferenceSpace();
2122

22-
if(!marker) {
23+
if (!marker) {
2324
marker = new THREE.Mesh(
2425
new THREE.CircleGeometry(0.25, 32).rotateX(- Math.PI / 2),
2526
new THREE.MeshBasicMaterial({ color: 0xbcbcbc })
2627
);
2728
scene.add(marker);
2829
}
29-
updateManager.addToUpdate(render);
30+
updateManager.addToUpdate(intersectionUpdate);
3031
});
3132

3233
renderer.xr.addEventListener('sessionend', () => {
33-
updateManager.removeFromUpdate(render);
34+
updateManager.removeFromUpdate(intersectionUpdate);
3435
scene.remove(marker);
3536
marker = null;
3637
});
@@ -59,22 +60,28 @@ export const InitXR = (scene, renderer, updateManager) => {
5960
controller1 = renderer.xr.getController(0);
6061
controller1.addEventListener('selectstart', onSelectStart);
6162
controller1.addEventListener('selectend', onSelectEnd);
62-
controller1.addEventListener('connected', function (event) {
63-
this.add(buildController(event.data));
63+
controller1.addEventListener('connected', (event) => {
64+
const rep = buildController(event.data);
65+
representationManager.AddRepresentation("left-hand", controller1);
66+
controller1.add(rep);
6467
});
65-
controller1.addEventListener('disconnected', function () {
66-
this.remove(this.children[0]);
68+
controller1.addEventListener('disconnected', () => {
69+
representationManager.RemoveRepresentation("left-hand", controller1);
70+
controller1.remove(controller1.children[0]);
6771
});
6872
scene.add(controller1);
6973

7074
controller2 = renderer.xr.getController(1);
7175
controller2.addEventListener('selectstart', onSelectStart);
7276
controller2.addEventListener('selectend', onSelectEnd);
73-
controller2.addEventListener('connected', function (event) {
74-
this.add(buildController(event.data));
77+
controller2.addEventListener('connected', (event) => {
78+
const rep = buildController(event.data);
79+
representationManager.AddRepresentation("right-hand", controller2);
80+
controller2.add(rep);
7581
});
76-
controller2.addEventListener('disconnected', function () {
77-
this.remove(this.children[0]);
82+
controller2.addEventListener('disconnected', () => {
83+
representationManager.RemoveRepresentation("right-hand", controller2);
84+
controller2.remove(controller2.children[0]);
7885
});
7986
scene.add(controller2);
8087

@@ -97,6 +104,7 @@ export const InitXR = (scene, renderer, updateManager) => {
97104
function buildController(data) {
98105
let geometry, material;
99106

107+
console.log(data)
100108
switch (data.targetRayMode) {
101109
case 'tracked-pointer':
102110
geometry = new THREE.BufferGeometry();
@@ -111,10 +119,14 @@ function buildController(data) {
111119
geometry = new THREE.RingGeometry(0.02, 0.04, 32).translate(0, 0, - 1);
112120
material = new THREE.MeshBasicMaterial({ opacity: 0.5, transparent: true });
113121
return new THREE.Mesh(geometry, material);
122+
123+
default:
124+
console.warn("unrecognized target ray mode: " + data.targetRayMode);
125+
return new THREE.Group();
114126
}
115127
}
116128

117-
function render() {
129+
function intersectionUpdate() {
118130
INTERSECTION = undefined;
119131

120132
if (controller1.userData.isSelecting === true) {

generator/room/client.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const (
1919
pingPeriod = (pongWait * 9) / 10
2020

2121
// Maximum message size allowed from peer.
22-
maxMessageSize = 512
22+
maxMessageSize = 1024 * 10
2323
)
2424

2525
var (

0 commit comments

Comments
 (0)