From aea68309db8449ed67c49b33173b5dab0b359a4e Mon Sep 17 00:00:00 2001 From: Patrick Bozic Date: Fri, 16 Sep 2022 18:15:01 +0800 Subject: [PATCH 1/3] fix out of sync issue and collisions --- game.js | 57 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/game.js b/game.js index aead8b33ac..c08bbc5616 100644 --- a/game.js +++ b/game.js @@ -80,29 +80,55 @@ const _unwearAppIfHasSitComponent = (player) => { } // returns whether we actually snapped -function updateGrabbedObject(o, grabMatrix, offsetMatrix, {collisionEnabled, handSnapEnabled, physx, gridSnap}) { +function updateGrabbedObject( + o, + grabMatrix, + offsetMatrix, + { collisionEnabled, handSnapEnabled, physx, gridSnap } +) { grabMatrix.decompose(localVector, localQuaternion, localVector2); offsetMatrix.decompose(localVector3, localQuaternion2, localVector4); const offset = localVector3.length(); - localMatrix.multiplyMatrices(grabMatrix, offsetMatrix) + localMatrix + .multiplyMatrices(grabMatrix, offsetMatrix) .decompose(localVector5, localQuaternion3, localVector6); - let collision = collisionEnabled && physicsScene.raycast(localVector, localQuaternion); - if (collision) { - // console.log('got collision', collision); - const {point} = collision; - o.position.fromArray(point) - // .add(localVector2.set(0, 0.01, 0)); + const collision = + collisionEnabled && physicsScene.raycast(localVector, localQuaternion); + localQuaternion2.setFromAxisAngle(localVector2.set(1, 0, 0), -Math.PI * 0.5); + const downCollision = + collisionEnabled && physicsScene.raycast(localVector5, localQuaternion2); - if (o.position.distanceTo(localVector) > offset) { - collision = null; - } + if (!!collision) { + const { point } = collision; + localVector6.fromArray(point); } - if (!collision) { - o.position.copy(localVector5); + + if (!!downCollision) { + const { point } = downCollision; + localVector4.fromArray(point); + if (ioManager.keys.shift) { + o.position.copy(localVector5.setY(localVector4.y)); + } else { + // if collision point is closer to the player than the grab offset and collisionDown point + // is below collision point then place the object at collision point + if ( + localVector.distanceTo(localVector6) < offset && + localVector4.y < localVector6.y + ) + localVector5.copy(localVector6); + + // if grabbed object would go below another object then place object at downCollision point + if (localVector5.y < localVector4.y) localVector5.setY(localVector4.y); + o.position.copy(localVector5); + } } - const handSnap = !handSnapEnabled || offset >= maxGrabDistance || !!collision; + const handSnap = + !handSnapEnabled || + offset >= maxGrabDistance || + !!collision || + !!downCollision; if (handSnap) { snapPosition(o, gridSnap); o.quaternion.setFromEuler(o.savedRotation); @@ -110,6 +136,8 @@ function updateGrabbedObject(o, grabMatrix, offsetMatrix, {collisionEnabled, han o.quaternion.copy(localQuaternion3); } + o.updateMatrixWorld(); + return { handSnap, }; @@ -543,7 +571,6 @@ const _gameUpdate = (timestamp, timeDiff) => { if (grabbedObject && !_isWear(grabbedObject)) { const {position, quaternion} = renderer.xr.getSession() ? localPlayer[hand === 'left' ? 'leftHand' : 'rightHand'] : camera; localMatrix.compose(position, quaternion, localVector.set(1, 1, 1)); - grabbedObject.updateMatrixWorld(); updateGrabbedObject(grabbedObject, localMatrix, localMatrix3.fromArray(grabAction.matrix), { collisionEnabled: true, From 749f28e306c31a60fa4cc0b099106c2be6ed6afa Mon Sep 17 00:00:00 2001 From: Patrick Bozic Date: Fri, 16 Sep 2022 18:23:25 +0800 Subject: [PATCH 2/3] set avatar as pivot point for 3rd person mode --- character-controller.js | 56 +++++++++++++++++++++++------------------ game.js | 12 ++++++++- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/character-controller.js b/character-controller.js index 2f1b7b0048..5a72f0651a 100644 --- a/character-controller.js +++ b/character-controller.js @@ -1136,31 +1136,39 @@ class LocalPlayer extends UninterpolatedPlayer { }); } grab(app, hand = 'left') { - const {position, quaternion} = _getSession() ? - localPlayer[hand === 'left' ? 'leftHand' : 'rightHand'] - : - camera; - - app.updateMatrixWorld(); - app.savedRotation = app.rotation.clone(); - app.startQuaternion = quaternion.clone(); - - const grabAction = { - type: 'grab', - hand, - instanceId: app.instanceId, - matrix: localMatrix.copy(app.matrixWorld) - .premultiply(localMatrix2.compose(position, quaternion, localVector.set(1, 1, 1)).invert()) - .toArray() - }; - this.addAction(grabAction); - - physicsScene.disableAppPhysics(app) + if(this instanceof LocalPlayer) { + let position = null, quaternion = null; - app.dispatchEvent({ - type: 'grabupdate', - grab: true, - }); + if(_getSession()) { + const h = this[hand === 'left' ? 'leftHand' : 'rightHand']; + position = h.position; + quaternion = h.quaternion; + } else { + position = this.position; + quaternion = camera.quaternion; + } + + app.updateMatrixWorld(); + app.savedRotation = app.rotation.clone(); + app.startQuaternion = quaternion.clone(); + + const grabAction = { + type: 'grab', + hand, + instanceId: app.instanceId, + matrix: localMatrix.copy(app.matrixWorld) + .premultiply(localMatrix2.compose(position, quaternion, localVector.set(1, 1, 1)).invert()) + .toArray() + }; + this.addAction(grabAction); + + physicsScene.disableAppPhysics(app) + + app.dispatchEvent({ + type: 'grabupdate', + grab: true, + }); + } } ungrab() { const actions = Array.from(this.getActionsState()); diff --git a/game.js b/game.js index c08bbc5616..e69c82bb4d 100644 --- a/game.js +++ b/game.js @@ -569,7 +569,17 @@ const _gameUpdate = (timestamp, timeDiff) => { const grabAction = _getGrabAction(i); const grabbedObject = _getGrabbedObject(i); if (grabbedObject && !_isWear(grabbedObject)) { - const {position, quaternion} = renderer.xr.getSession() ? localPlayer[hand === 'left' ? 'leftHand' : 'rightHand'] : camera; + let position = null, + quaternion = null; + if (renderer.xr.getSession()) { + const h = localPlayer[hand === "left" ? "leftHand" : "rightHand"]; + position = h.position; + quaternion = h.quaternion; + } else { + position = localVector2.copy(localPlayer.position); + quaternion = camera.quaternion; + } + localMatrix.compose(position, quaternion, localVector.set(1, 1, 1)); updateGrabbedObject(grabbedObject, localMatrix, localMatrix3.fromArray(grabAction.matrix), { From a876096a124877e29247f3eab8c50261cf029364 Mon Sep 17 00:00:00 2001 From: Patrick Bozic Date: Fri, 16 Sep 2022 20:36:34 +0800 Subject: [PATCH 3/3] optimization --- character-controller.js | 58 ++++++++++++++++++++--------------------- game.js | 8 +++--- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/character-controller.js b/character-controller.js index 5a72f0651a..4c4a70465c 100644 --- a/character-controller.js +++ b/character-controller.js @@ -1136,39 +1136,37 @@ class LocalPlayer extends UninterpolatedPlayer { }); } grab(app, hand = 'left') { - if(this instanceof LocalPlayer) { - let position = null, quaternion = null; + let position = null, quaternion = null; - if(_getSession()) { - const h = this[hand === 'left' ? 'leftHand' : 'rightHand']; - position = h.position; - quaternion = h.quaternion; - } else { - position = this.position; - quaternion = camera.quaternion; - } + if(_getSession()) { + const h = this[hand === 'left' ? 'leftHand' : 'rightHand']; + position = h.position; + quaternion = h.quaternion; + } else { + position = this.position; + quaternion = camera.quaternion; + } - app.updateMatrixWorld(); - app.savedRotation = app.rotation.clone(); - app.startQuaternion = quaternion.clone(); - - const grabAction = { - type: 'grab', - hand, - instanceId: app.instanceId, - matrix: localMatrix.copy(app.matrixWorld) - .premultiply(localMatrix2.compose(position, quaternion, localVector.set(1, 1, 1)).invert()) - .toArray() - }; - this.addAction(grabAction); - - physicsScene.disableAppPhysics(app) + app.updateMatrixWorld(); + app.savedRotation = app.rotation.clone(); + app.startQuaternion = quaternion.clone(); + + const grabAction = { + type: 'grab', + hand, + instanceId: app.instanceId, + matrix: localMatrix.copy(app.matrixWorld) + .premultiply(localMatrix2.compose(position, quaternion, localVector.set(1, 1, 1)).invert()) + .toArray() + }; + this.addAction(grabAction); + + physicsScene.disableAppPhysics(app) - app.dispatchEvent({ - type: 'grabupdate', - grab: true, - }); - } + app.dispatchEvent({ + type: 'grabupdate', + grab: true, + }); } ungrab() { const actions = Array.from(this.getActionsState()); diff --git a/game.js b/game.js index e69c82bb4d..d3af25eaa8 100644 --- a/game.js +++ b/game.js @@ -93,11 +93,9 @@ function updateGrabbedObject( .multiplyMatrices(grabMatrix, offsetMatrix) .decompose(localVector5, localQuaternion3, localVector6); - const collision = - collisionEnabled && physicsScene.raycast(localVector, localQuaternion); - localQuaternion2.setFromAxisAngle(localVector2.set(1, 0, 0), -Math.PI * 0.5); - const downCollision = - collisionEnabled && physicsScene.raycast(localVector5, localQuaternion2); + const collision = collisionEnabled && physicsScene.raycast(localVector, localQuaternion); + localQuaternion2.setFromAxisAngle(localVector2.set(1, 0, 0), -Math.PI * 0.5); + const downCollision = collisionEnabled && physicsScene.raycast(localVector5, localQuaternion2); if (!!collision) { const { point } = collision;