From 242afdb2fb945e603f194dac0c6ce1494c2596fe Mon Sep 17 00:00:00 2001 From: Jack Z Date: Thu, 28 Jul 2022 06:19:48 +0800 Subject: [PATCH 1/5] Physics code integrated onto new api. (Test code) --- metaverse_modules/spawner/index.js | 4 +- metaversefile-api.js | 6 +- mob-manager.js | 183 +++++++++++++++++++---------- 3 files changed, 129 insertions(+), 64 deletions(-) diff --git a/metaverse_modules/spawner/index.js b/metaverse_modules/spawner/index.js index 9fa3111819..85483ab2b2 100644 --- a/metaverse_modules/spawner/index.js +++ b/metaverse_modules/spawner/index.js @@ -29,7 +29,7 @@ export default e => { live = false; }); - const mobData = await mobManager.loadData(appUrls); + const mobData = await mobManager.loadData(app, appUrls); if (!live) return; const procGenInstance = procGenManager.getInstance(seed, range); @@ -59,5 +59,7 @@ export default e => { } }); + app.getPhysicsObjects = () => mobManager.getPhysicsObjects(); + return app; }; \ No newline at end of file diff --git a/metaversefile-api.js b/metaversefile-api.js index af4074be76..3f7268f7da 100644 --- a/metaversefile-api.js +++ b/metaversefile-api.js @@ -1038,7 +1038,7 @@ export default () => { } // mob - for (const mob of mobManager.mobs) { + for (const mob of mobManager.getMobs()) { const mobPhysicsObjects = mob.getPhysicsObjects(); for (const mobPhysicsObject of mobPhysicsObjects) { if (mobPhysicsObject.physicsId === physicsId) { @@ -1074,7 +1074,7 @@ export default () => { } // mob - for (const mob of mobManager.mobs) { + for (const mob of mobManager.getMobs()) { const mobPhysicsObjects = mob.getPhysicsObjects(); for (const mobPhysicsObject of mobPhysicsObjects) { if (mobPhysicsObject.physicsId === physicsId) { @@ -1113,7 +1113,7 @@ export default () => { } // mob - for (const mob of mobManager.mobs) { + for (const mob of mobManager.getMobs()) { const mobPhysicsObjects = mob.getPhysicsObjects(); for (const mobPhysicsObject of mobPhysicsObjects) { if (mobPhysicsObject.physicsId === physicsId) { diff --git a/mob-manager.js b/mob-manager.js index ddc282c77c..a74eadf396 100644 --- a/mob-manager.js +++ b/mob-manager.js @@ -41,6 +41,8 @@ const maxAnimationFrameLength = 512; let unifiedBoneTextureSize = 1024; +const physicsScene = physicsManager.getScene(); + // window.THREE = THREE; const _zeroY = v => { @@ -97,7 +99,7 @@ function makeCharacterController(app, { .applyQuaternion(localQuaternion) ); - const characterController = physicsManager.createCharacterController( + const characterController = physicsScene.createCharacterController( radius - contactOffset, innerHeight, contactOffset, @@ -108,8 +110,11 @@ function makeCharacterController(app, { } class Mob { - constructor(app = null, srcUrl = '') { + constructor(app = null, srcUrl = '', position = null, quaternion = null) { + console.log('Mob constructor', srcUrl, position, quaternion, app); this.app = app; + this.position = position; + this.quaternion = quaternion; this.subApp = null; this.name = this.app.name + '@' + this.app.position.toArray().join(','); @@ -119,7 +124,9 @@ class Mob { if (srcUrl) { (async () => { - await this.loadApp(srcUrl); + const m = await metaversefile.import(srcUrl); + const mobJsonUrl = m.srcUrl; + await this.loadApp(mobJsonUrl); })(); } } @@ -157,8 +164,8 @@ class Mob { const subApp = await metaversefile.createAppAsync({ start_url: mobUrl, - position: this.app.position, - quaternion: this.app.quaternion, + position: this.app.position.clone() + + this.position, + quaternion: this.app.quaternion.clone().multiply(this.quaternion), scale: this.app.scale, }); if (!live) return; @@ -171,13 +178,13 @@ class Mob { this.app.add(subApp); this.subApp = subApp; - this.app.position.set(0, 0, 0); - this.app.quaternion.identity(); - this.app.scale.set(1, 1, 1); - this.app.updateMatrixWorld(); + //this.app.position.set(0, 0, 0); + //this.app.quaternion.identity(); + //this.app.scale.set(1, 1, 1); + //this.app.updateMatrixWorld(); this.cleanupFns.push(() => { - this.app.clear(); + // this.app.clear(); }); }; _attachToApp(); @@ -217,6 +224,7 @@ class Mob { } else { idleAnimation = []; } + // console.log('idleAnimation', idleAnimation, subApp, mobComponent); const characterController = makeCharacterController(subApp, { radius, @@ -248,7 +256,8 @@ class Mob { halfHeight, } = spec; _getPhysicsExtraPositionQuaternion(spec, localVector, localQuaternion, localVector2, localMatrix); - const physicsObject = physicsManager.addCapsuleGeometry(localVector, localQuaternion, radius, halfHeight); + console.log('localVector', localVector); + const physicsObject = physicsScene.addCapsuleGeometry(localVector, localQuaternion, radius, halfHeight); physicsObject.spec = spec; return physicsObject; }); @@ -256,9 +265,9 @@ class Mob { subApp.getPhysicsObjects = () => physicsObjects; this.cleanupFns.push(() => { - physicsManager.destroyCharacterController(characterController); + physicsScene.destroyCharacterController(characterController); for (const extraPhysicsObject of extraPhysicsObjects) { - physicsManager.removeGeometry(extraPhysicsObject); + physicsScene.removeGeometry(extraPhysicsObject); } }); @@ -290,17 +299,18 @@ class Mob { let animation = null; let velocity = new THREE.Vector3(0, 0, 0); this.updateFns.push((timestamp, timeDiff) => { + return; const localPlayer = getLocalPlayer(); const timeDiffS = timeDiff / 1000; if (animation) { mesh.position.add(localVector.copy(animation.velocity).multiplyScalar(timeDiff/1000)); - animation.velocity.add(localVector.copy(physicsManager.getGravity()).multiplyScalar(timeDiff/1000)); + animation.velocity.add(localVector.copy(physicsScene.getGravity()).multiplyScalar(timeDiff/1000)); if (mesh.position.y < 0) { animation = null; } - physicsManager.setCharacterControllerPosition(characterController, mesh.position); + physicsScene.setCharacterControllerPosition(characterController, mesh.position); mesh.updateMatrixWorld(); @@ -334,16 +344,16 @@ class Mob { const popExtraGeometry = (() => { for (const extraPhysicsObject of extraPhysicsObjects) { - physicsManager.disableActor(extraPhysicsObject); + physicsScene.disableActor(extraPhysicsObject); } return () => { for (const extraPhysicsObject of extraPhysicsObjects) { - physicsManager.enableActor(extraPhysicsObject); + physicsScene.enableActor(extraPhysicsObject); } }; })(); - const flags = physicsManager.moveCharacterController( + const flags = physicsScene.moveCharacterController( characterController, moveDelta, minDist, @@ -356,7 +366,7 @@ class Mob { let grounded = !!(flags & 0x1); if (!grounded) { velocity.add( - localVector.copy(physicsManager.getGravity()) + localVector.copy(physicsScene.getGravity()) .multiplyScalar(timeDiffS) ); } else { @@ -413,7 +423,7 @@ class Mob { extraPhysicsObject.position.copy(localVector); extraPhysicsObject.quaternion.copy(localQuaternion); extraPhysicsObject.updateMatrixWorld(); - physicsManager.setTransform(extraPhysicsObject); + physicsScene.setTransform(extraPhysicsObject); } }; _updateExtraPhysics(); @@ -449,6 +459,7 @@ class Mob { } } destroy() { + console.log('Mob.destroy'); for (const fn of this.cleanupFns) { fn(); } @@ -456,7 +467,8 @@ class Mob { } class MobInstance { - constructor() { + constructor(mob) { + this.mob = mob; } } @@ -473,7 +485,7 @@ class InstancedSkeleton extends THREE.Skeleton { unifiedBoneTextureSize = boneTexture.image.width; // console.log('boneTextureSize', unifiedBoneTextureSize); } - bakeFrame(skeleton, drawCallIndex, frameIndex) { + bakeFrame(glb, skeleton, drawCallIndex, frameIndex) { const boneMatrices = this.unifiedBoneMatrices; const drawCall = this.parent.drawCalls[drawCallIndex]; @@ -502,6 +514,11 @@ class InstancedSkeleton extends THREE.Skeleton { const scale = new THREE.Vector3(); localMatrix.decompose(translation, rotation, scale); rotation.invert(); + // check if scale is uniform + var tolerance = 1.192092896e-07 * 1000; + if ( !(Math.abs(scale.x - scale.y) < tolerance && Math.abs(scale.x - scale.z) < tolerance) ) { + console.log('Non-uniform scale bone matrix', glb, scale); + } const pos = new THREE.Vector4( localMatrix.elements[12], localMatrix.elements[13], @@ -522,6 +539,8 @@ class MobBatchedMesh extends InstancedBatchedMesh { const { glbs, skinnedMeshes: meshes, + app, + appUrls, } = mobData; const { // atlas, @@ -870,6 +889,8 @@ gl_Position = projectionMatrix * mvPosition; super(geometry, material, allocator); this.frustumCulled = false; + this.app = app; + this.appUrls = appUrls; this.procGenInstance = procGenInstance; { @@ -906,6 +927,7 @@ gl_Position = projectionMatrix * mvPosition; this.glbs = glbs; this.meshes = meshes; + this.mobs = []; // this.rootBones = rootBones; this.drawCalls = Array(meshes.length).fill(null); @@ -950,7 +972,7 @@ gl_Position = projectionMatrix * mvPosition; mixer.update(1. / bakeFps); mixer.updateMatrixWorld(); - this.skeleton.bakeFrame(skeleton2, i, t); + this.skeleton.bakeFrame(glb, skeleton2, i, t); } } this.skeleton.unifiedBoneTexture.needsUpdate = true; @@ -965,7 +987,7 @@ gl_Position = projectionMatrix * mvPosition; } return drawCall; } - drawChunk(chunk, renderData, tracker) { + drawChunk(chunk, renderData, tracker, mob) { const mobData = renderData; if (!renderData.instances) return; @@ -1014,7 +1036,7 @@ gl_Position = projectionMatrix * mvPosition; drawCall.updateTexture('timeOffset', timeOffsetOffset + instanceIndex, 1); - const instance = new MobInstance(); + const instance = new MobInstance(mob); drawCall.instances.push(instance); // physics @@ -1079,9 +1101,24 @@ gl_Position = projectionMatrix * mvPosition; const geometryNoise = mobData.instances[i]; // console.log('got noise', geometryNoise); const geometryIndex = Math.floor(geometryNoise * this.meshes.length); + + const px = mobData.ps[i * 3]; + const py = mobData.ps[i * 3 + 1]; + const pz = mobData.ps[i * 3 + 2]; + + const qx = mobData.qs[i * 4]; + const qy = mobData.qs[i * 4 + 1]; + const qz = mobData.qs[i * 4 + 2]; + const qw = mobData.qs[i * 4 + 3]; + + const position = new THREE.Vector3(px, py, pz); + const quaternion = new THREE.Quaternion(qx, qy, qz, qw); + + mob = this.addMobApp(this.app, this.appUrls[geometryIndex], position, quaternion); const drawCall = this.getDrawCall(geometryIndex); - const mobInstance = _renderMobGeometry(drawCall, mobData.ps, mobData.qs, i); + const mobInstance = _renderMobGeometry(drawCall, mobData.ps, mobData.qs, i, mob); + mobInstances.push(mobInstance); } @@ -1096,7 +1133,9 @@ gl_Position = projectionMatrix * mvPosition; const mobInstance = mobInstances[i]; + this.removeMobApp(mobInstance.mob.subApp); _unrenderMobGeometry(drawCall, mobInstance); + // } tracker.offChunkRemove(chunk, onchunkremove); @@ -1111,13 +1150,51 @@ gl_Position = projectionMatrix * mvPosition; const frameIndex = timestamp * bakeFps / 1000; shader.uniforms.uTime.value = frameIndex; } + + for (const mob of this.mobs) { + mob.update(timestamp, timeDiff); + } + } + getPhysicsObjects() { + let results = []; + for (const mob of this.mobs) { + const physicsObjects = mob.getPhysicsObjects(); + results.push(physicsObjects); + } + results = results.flat(); + return results; + } + addMobApp(app, srcUrl, position, quaternion) { + /*if (app.appType !== 'mob') { + console.warn('not a mob app', app); + throw new Error('only mob apps can be mobs'); + }*/ + if (!srcUrl) { + console.warn('no srcUrl', app); + throw new Error('srcUrl is required'); + } + + const mob = new Mob(app, srcUrl, position, quaternion); + this.mobs.push(mob); + return mob; + } + removeMobApp(app) { + const index = this.mobs.findIndex(mob => mob.subApp === app); + if (index !== -1) { + const mob = this.mobs[index]; + mob.destroy(); + this.mobs.splice(index, 1); + } } } class MobsCompiledData { constructor({ + app = null, appUrls = [], } = {}) { + this.app = app; + this.appUrls = appUrls; this.glbs = null; this.skinnedMeshes = null; @@ -1206,9 +1283,6 @@ class Mobber { mobData, }); this.generator = generator; - /* this.tracker = new LodChunkTracker(this.generator, { - chunkWorldSize, - }); */ const numLods = 1; const tracker = procGenInstance.getChunkTracker({ numLods, @@ -1238,8 +1312,6 @@ class Mobber { const {renderData, chunk} = e; generator.mobBatchedMesh.drawChunk(chunk, renderData, tracker); }; - // tracker.addEventListener('chunkdatarequest', chunkdatarequest); - // tracker.addEventListener('chunkadd', chunkadd); tracker.onChunkDataRequest(chunkdatarequest); tracker.onChunkAdd(chunkadd); @@ -1262,6 +1334,12 @@ class Mobber { getChunks() { return this.generator.object; } + getPhysicsObjects() { + return this.generator.mobBatchedMesh.getPhysicsObjects(); + } + getMobs() { + return this.generator.mobBatchedMesh.mobs; + } update(timestamp, timeDiff) { const localPlayer = getLocalPlayer(); !this.procGenInstance.range && this.tracker.update(localPlayer.position); @@ -1276,7 +1354,6 @@ class Mobber { class MobManager { constructor() { this.mobbers = []; - this.mobs = []; } createMobber({ procGenInstance, @@ -1293,52 +1370,38 @@ class MobManager { mobber.destroy(); this.mobbers.splice(this.mobbers.indexOf(mobber), 1); } - async loadData(appUrls) { + async loadData(app, appUrls) { const mobData = new MobsCompiledData({ + app, appUrls, }); await mobData.waitForLoad(); return mobData; } - addMobApp(app, srcUrl) { - if (app.appType !== 'mob') { - console.warn('not a mob app', app); - throw new Error('only mob apps can be mobs'); - } - if (!srcUrl) { - console.warn('no srcUrl', app); - throw new Error('srcUrl is required'); - } - - const mob = new Mob(app, srcUrl); - this.mobs.push(mob); - } - removeMobApp(app) { - const index = this.mobs.findIndex(mob => mob.app === app); - if (index !== -1) { - const mob = this.mobs[index]; - mob.destroy(); - this.mobs.splice(index, 1); - } - } getPhysicsObjects() { let results = []; - for (const mob of this.mobs) { - const physicsObjects = mob.getPhysicsObjects(); + for (const mobber of this.mobbers) { + const physicsObjects = mobber.getPhysicsObjects(); results.push(physicsObjects); } results = results.flat(); return results; + // console.log('land getPhysicsObjects', app, subApps, result); + } + getMobs() { + let results = []; + for (const mobber of this.mobbers) { + const mobs = mobber.getMobs(); + results.push(mobs); + } + results = results.flat(); + return results; } update(timestamp, timeDiff) { // mobber is updated by the app that created it /* for (const mobber of this.mobbers) { mobber.update(timestamp, timeDiff); } */ - - for (const mob of this.mobs) { - mob.update(timestamp, timeDiff); - } } } const mobManager = new MobManager(); From c815606b2370623081442127ba6fbf11a3b6bacb Mon Sep 17 00:00:00 2001 From: Jack Z Date: Fri, 29 Jul 2022 02:19:54 +0800 Subject: [PATCH 2/5] Refactored mob-manager physx to sync the position with mob mesh --- mob-manager.js | 57 +++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/mob-manager.js b/mob-manager.js index a74eadf396..cd76933fb6 100644 --- a/mob-manager.js +++ b/mob-manager.js @@ -110,11 +110,16 @@ function makeCharacterController(app, { } class Mob { - constructor(app = null, srcUrl = '', position = null, quaternion = null) { - console.log('Mob constructor', srcUrl, position, quaternion, app); + constructor(app = null, srcUrl = '', spec = {}) { this.app = app; + const { + position, + quaternion, + timeOffset + } = spec; this.position = position; this.quaternion = quaternion; + this.timeOffset = timeOffset; this.subApp = null; this.name = this.app.name + '@' + this.app.position.toArray().join(','); @@ -163,8 +168,8 @@ class Mob { const modelPrerotation = new THREE.Quaternion().fromArray(modelQuaternion); const subApp = await metaversefile.createAppAsync({ - start_url: mobUrl, - position: this.app.position.clone() + + this.position, + start_url: '', + position: this.app.position.clone().add(this.position), quaternion: this.app.quaternion.clone().multiply(this.quaternion), scale: this.app.scale, }); @@ -215,7 +220,7 @@ class Mob { _bindHitTracker(); const mesh = subApp; - const animations = subApp.glb.animations; + //const animations = subApp.glb.animations; let {idleAnimation = ['idle'], aggroDistance, walkSpeed = 1} = mobComponent; if (idleAnimation) { if (!Array.isArray(idleAnimation)) { @@ -224,7 +229,6 @@ class Mob { } else { idleAnimation = []; } - // console.log('idleAnimation', idleAnimation, subApp, mobComponent); const characterController = makeCharacterController(subApp, { radius, @@ -256,7 +260,6 @@ class Mob { halfHeight, } = spec; _getPhysicsExtraPositionQuaternion(spec, localVector, localQuaternion, localVector2, localMatrix); - console.log('localVector', localVector); const physicsObject = physicsScene.addCapsuleGeometry(localVector, localQuaternion, radius, halfHeight); physicsObject.spec = spec; return physicsObject; @@ -272,13 +275,13 @@ class Mob { }); // rotation hacks - { + /* { mesh.position.y = 0; localEuler.setFromQuaternion(mesh.quaternion, 'YXZ'); localEuler.x = 0; localEuler.z = 0; mesh.quaternion.setFromEuler(localEuler); - } + } // initialize animation const idleAnimationClips = idleAnimation.map(name => animations.find(a => a.name === name)).filter(a => !!a); @@ -289,17 +292,17 @@ class Mob { idleAction.play(); } - this.updateFns.push((timestamp, timeDiff) => { - const deltaSeconds = timeDiff / 1000; - mixer.update(deltaSeconds); - }); - } + if (idleActions.length != 0) { + this.updateFns.push((timestamp, timeDiff) => { + mixer.setTime(timestamp / 1000 + this.timeOffset * idleActions[0].duration); + }); + } + } */ // set up frame loop let animation = null; let velocity = new THREE.Vector3(0, 0, 0); this.updateFns.push((timestamp, timeDiff) => { - return; const localPlayer = getLocalPlayer(); const timeDiffS = timeDiff / 1000; @@ -459,7 +462,6 @@ class Mob { } } destroy() { - console.log('Mob.destroy'); for (const fn of this.cleanupFns) { fn(); } @@ -952,6 +954,7 @@ gl_Position = projectionMatrix * mvPosition; // animations let mixer = null; + // const idleAnimation = animations.find(a => a.name === 'idle'); const clip = animations[0]; //{ mixer = new THREE.AnimationMixer(rootBone2); @@ -994,7 +997,7 @@ gl_Position = projectionMatrix * mvPosition; // mob geometry { - const _renderMobGeometry = (drawCall, ps, qs, index) => { + const _renderMobGeometry = (drawCall, ps, qs, to, index) => { // locals const instanceIndex = drawCall.getInstanceCount(); @@ -1030,8 +1033,7 @@ gl_Position = projectionMatrix * mvPosition; drawCall.updateTexture('q', qOffset + instanceIndex * 4, 4); // time offset - - timeOffsetTexture.image.data[timeOffsetOffset + instanceIndex] = Math.random(); + timeOffsetTexture.image.data[timeOffsetOffset + instanceIndex] = to; drawCall.updateTexture('timeOffset', timeOffsetOffset + instanceIndex, 1); @@ -1097,6 +1099,7 @@ gl_Position = projectionMatrix * mvPosition; } let mobInstances = []; + mobData.timeOffsets = []; for (let i = 0; i < mobData.instances.length; i++) { const geometryNoise = mobData.instances[i]; // console.log('got noise', geometryNoise); @@ -1111,14 +1114,18 @@ gl_Position = projectionMatrix * mvPosition; const qz = mobData.qs[i * 4 + 2]; const qw = mobData.qs[i * 4 + 3]; + const timeOffset = Math.random(); + mobData.timeOffsets[i] = timeOffset; // this can be generated when ps, qs are filled + const position = new THREE.Vector3(px, py, pz); const quaternion = new THREE.Quaternion(qx, qy, qz, qw); - mob = this.addMobApp(this.app, this.appUrls[geometryIndex], position, quaternion); + mob = this.addMobApp(this.app, this.appUrls[geometryIndex], + {position, quaternion, timeOffset} + ); const drawCall = this.getDrawCall(geometryIndex); - const mobInstance = _renderMobGeometry(drawCall, mobData.ps, mobData.qs, i, mob); - + const mobInstance = _renderMobGeometry(drawCall, mobData.ps, mobData.qs, timeOffset, i, mob); mobInstances.push(mobInstance); } @@ -1135,7 +1142,6 @@ gl_Position = projectionMatrix * mvPosition; this.removeMobApp(mobInstance.mob.subApp); _unrenderMobGeometry(drawCall, mobInstance); - // } tracker.offChunkRemove(chunk, onchunkremove); @@ -1164,7 +1170,7 @@ gl_Position = projectionMatrix * mvPosition; results = results.flat(); return results; } - addMobApp(app, srcUrl, position, quaternion) { + addMobApp(app, srcUrl, spec) { /*if (app.appType !== 'mob') { console.warn('not a mob app', app); throw new Error('only mob apps can be mobs'); @@ -1174,7 +1180,7 @@ gl_Position = projectionMatrix * mvPosition; throw new Error('srcUrl is required'); } - const mob = new Mob(app, srcUrl, position, quaternion); + const mob = new Mob(app, srcUrl, spec); this.mobs.push(mob); return mob; } @@ -1386,7 +1392,6 @@ class MobManager { } results = results.flat(); return results; - // console.log('land getPhysicsObjects', app, subApps, result); } getMobs() { let results = []; From 695fd5c23a312e382abc89156be836cda9897a9d Mon Sep 17 00:00:00 2001 From: Jack Z Date: Fri, 29 Jul 2022 05:12:41 +0800 Subject: [PATCH 3/5] Synchronized mobs rendering with physics --- mob-manager.js | 67 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 17 deletions(-) diff --git a/mob-manager.js b/mob-manager.js index cd76933fb6..6ad9737d02 100644 --- a/mob-manager.js +++ b/mob-manager.js @@ -115,14 +115,16 @@ class Mob { const { position, quaternion, - timeOffset + timeOffset, + updateMobGeometry } = spec; this.position = position; this.quaternion = quaternion; this.timeOffset = timeOffset; + this.updateMobGeometry = updateMobGeometry; this.subApp = null; - this.name = this.app.name + '@' + this.app.position.toArray().join(','); + this.name = this.app.name + '@' + this.position.toArray().join(','); this.updateFns = []; this.cleanupFns = []; @@ -173,6 +175,7 @@ class Mob { quaternion: this.app.quaternion.clone().multiply(this.quaternion), scale: this.app.scale, }); + subApp.visible = false; if (!live) return; const rng = this.#getRng(); @@ -212,7 +215,7 @@ class Mob { hitTracker.bind(subApp); subApp.dispatchEvent({type: 'hittrackeradded'}); const die = () => { - this.app.destroy(); + this.subApp.destroy(); _drop(); }; subApp.addEventListener('die', die, {once: true}); @@ -324,7 +327,7 @@ class Mob { const meshPosition = localVector2; const meshQuaternion = localQuaternion; const meshScale = localVector3; - + const meshPositionY0 = localVector4.copy(meshPosition); const characterPositionY0 = localVector5.copy(localPlayer.position) .add(localVector6.set(0, localPlayer.avatar ? -localPlayer.avatar.height : 0, 0)); @@ -397,10 +400,12 @@ class Mob { mesh.matrixWorld.compose(meshPosition, meshQuaternion, meshScale); mesh.matrix.copy(mesh.matrixWorld); - if (app.parent) { - mesh.matrix.premultiply(localMatrix.copy(app.parent.matrixWorld).invert()); + if (this.app.parent) { + mesh.matrix.premultiply(localMatrix.copy(this.app.parent.matrixWorld).invert()); } mesh.matrix.decompose(mesh.position, mesh.quaternion, mesh.scale); + + this.updateMobGeometry(mesh.position, mesh.quaternion); } } }; @@ -469,8 +474,8 @@ class Mob { } class MobInstance { - constructor(mob) { - this.mob = mob; + constructor() { + this.mob = null; } } @@ -990,7 +995,7 @@ gl_Position = projectionMatrix * mvPosition; } return drawCall; } - drawChunk(chunk, renderData, tracker, mob) { + drawChunk(chunk, renderData, tracker) { const mobData = renderData; if (!renderData.instances) return; @@ -1038,7 +1043,7 @@ gl_Position = projectionMatrix * mvPosition; drawCall.updateTexture('timeOffset', timeOffsetOffset + instanceIndex, 1); - const instance = new MobInstance(mob); + const instance = new MobInstance(); drawCall.instances.push(instance); // physics @@ -1108,24 +1113,52 @@ gl_Position = projectionMatrix * mvPosition; const px = mobData.ps[i * 3]; const py = mobData.ps[i * 3 + 1]; const pz = mobData.ps[i * 3 + 2]; + const position = new THREE.Vector3(px, py, pz); const qx = mobData.qs[i * 4]; const qy = mobData.qs[i * 4 + 1]; const qz = mobData.qs[i * 4 + 2]; const qw = mobData.qs[i * 4 + 3]; + const quaternion = new THREE.Quaternion(qx, qy, qz, qw); const timeOffset = Math.random(); mobData.timeOffsets[i] = timeOffset; // this can be generated when ps, qs are filled - const position = new THREE.Vector3(px, py, pz); - const quaternion = new THREE.Quaternion(qx, qy, qz, qw); + const drawCall = this.getDrawCall(geometryIndex); + const mobInstance = _renderMobGeometry(drawCall, mobData.ps, mobData.qs, timeOffset, i); + + const _updateMobGeometry = (position, quaternion) => { + const instanceIndex = drawCall.instances.indexOf(mobInstance); + if (instanceIndex >= 0) { + // locals + + const pTexture = drawCall.getTexture('p'); + const pOffset = drawCall.getTextureOffset('p'); + const qTexture = drawCall.getTexture('q'); + const qOffset = drawCall.getTextureOffset('q'); + + // update the texture + + pTexture.image.data[pOffset + instanceIndex * 3] = position.x; + pTexture.image.data[pOffset + instanceIndex * 3 + 1] = position.y; + pTexture.image.data[pOffset + instanceIndex * 3 + 2] = position.z; + + qTexture.image.data[qOffset + instanceIndex * 4] = quaternion.x; + qTexture.image.data[qOffset + instanceIndex * 4 + 1] = quaternion.y; + qTexture.image.data[qOffset + instanceIndex * 4 + 2] = quaternion.z; + qTexture.image.data[qOffset + instanceIndex * 4 + 3] = quaternion.w; + + + drawCall.updateTexture('p', pOffset + instanceIndex * 3, 3); + drawCall.updateTexture('q', qOffset + instanceIndex * 4, 4); + } + } - mob = this.addMobApp(this.app, this.appUrls[geometryIndex], - {position, quaternion, timeOffset} + const mob = this.addMobApp(this.app, this.appUrls[geometryIndex], + {position, quaternion, timeOffset, updateMobGeometry: _updateMobGeometry} ); - - const drawCall = this.getDrawCall(geometryIndex); - const mobInstance = _renderMobGeometry(drawCall, mobData.ps, mobData.qs, timeOffset, i, mob); + mobInstance.mob = mob; + mobInstances.push(mobInstance); } From 07f0a587d52927140766c8eff32358469c923e73 Mon Sep 17 00:00:00 2001 From: Jack Z Date: Sat, 30 Jul 2022 08:11:26 +0800 Subject: [PATCH 4/5] Updated totum reference --- packages/totum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/totum b/packages/totum index 61da3f8156..b64f966871 160000 --- a/packages/totum +++ b/packages/totum @@ -1 +1 @@ -Subproject commit 61da3f81567f6677f4b70685d85170d63d6a37fa +Subproject commit b64f966871a4bc57ccff2b53d58ed9edc1dbe248 From ca0df9026a481bdca52975b78ddd94d4e8f7ca12 Mon Sep 17 00:00:00 2001 From: Jack Z Date: Fri, 5 Aug 2022 03:37:26 +0800 Subject: [PATCH 5/5] Reverted totum submodule to main instead of wrong branch --- packages/totum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/totum b/packages/totum index b64f966871..61da3f8156 160000 --- a/packages/totum +++ b/packages/totum @@ -1 +1 @@ -Subproject commit b64f966871a4bc57ccff2b53d58ed9edc1dbe248 +Subproject commit 61da3f81567f6677f4b70685d85170d63d6a37fa