diff --git a/src/viewer/scene/model/SceneModel.js b/src/viewer/scene/model/SceneModel.js index 38f0ddbfa9..6b0900ccdd 100644 --- a/src/viewer/scene/model/SceneModel.js +++ b/src/viewer/scene/model/SceneModel.js @@ -1449,7 +1449,7 @@ export class SceneModel extends Component { set position(value) { this._position.set(value || [0, 0, 0]); this._setWorldMatrixDirty(); - this._setWorldAABBDirty(); + this._sceneModelDirty(); this.glRedraw(); } @@ -1475,7 +1475,7 @@ export class SceneModel extends Component { this._rotation.set(value || [0, 0, 0]); math.eulerToQuaternion(this._rotation, "XYZ", this._quaternion); this._setWorldMatrixDirty(); - this._setWorldAABBDirty(); + this._sceneModelDirty(); this.glRedraw(); } @@ -1501,7 +1501,7 @@ export class SceneModel extends Component { this._quaternion.set(value || [0, 0, 0, 1]); math.quaternionToEuler(this._quaternion, "XYZ", this._rotation); this._setWorldMatrixDirty(); - this._setWorldAABBDirty(); + this._sceneModelDirty(); this.glRedraw(); } @@ -1558,7 +1558,7 @@ export class SceneModel extends Component { this._matrixDirty = false; this._setWorldMatrixDirty(); - this._setWorldAABBDirty(); + this._sceneModelDirty(); this.glRedraw(); } @@ -1617,18 +1617,16 @@ export class SceneModel extends Component { this._matrixDirty = true; } - _setLocalAABBDirty() { - for (let i = 0, len = this._entityList.length; i < len; i++) { - this._entityList[i]._setLocalAABBDirty(); // Entities need to rebuild their Local AABBs from their Mesh's local AABBs - } + _transformDirty() { + this._matrixDirty = true; } - _setWorldAABBDirty() { + _sceneModelDirty() { this._aabbDirty = true; this.scene._aabbDirty = true; this._matrixDirty = true; for (let i = 0, len = this._entityList.length; i < len; i++) { - this._entityList[i]._setWorldAABBDirty(); // Entities need to retransform their World AABBs by SceneModel's worldMatrix + this._entityList[i]._sceneModelDirty(); // Entities need to retransform their World AABBs by SceneModel's worldMatrix } } @@ -3436,7 +3434,7 @@ export class SceneModel extends Component { this._aabbDirty = true; this._setWorldMatrixDirty(); - this._setWorldAABBDirty(); + this._sceneModelDirty(); this.position = this._position; } @@ -3930,7 +3928,7 @@ createGeometryOBB(geometry) { math.AABB3ToOBB3(localAABB, geometry.obb); } else if (geometry.buckets) { const localAABB = math.collapseAABB3(); - for (let i = 0, len = geometry.buckets.length; i , len; i++) { + for (let i = 0, len = geometry.buckets.length; i < len; i++) { const bucket = geometry.buckets[i]; math.expandAABB3Points3(localAABB, bucket.positionsCompressed); } diff --git a/src/viewer/scene/model/SceneModelEntity.js b/src/viewer/scene/model/SceneModelEntity.js index 94cc682e9d..ea3f399dbb 100644 --- a/src/viewer/scene/model/SceneModelEntity.js +++ b/src/viewer/scene/model/SceneModelEntity.js @@ -52,8 +52,7 @@ export class SceneModelEntity { this._aabb = aabb; this._worldAABB = math.AABB3(aabb); // Computed from Meshes and SceneModel.matrix this._offsetAABB = math.AABB3(aabb); // TODO - only used for offsets, current disabled - this._localAABBDirty = true; - this._worldAABBDirty = true; + this._aabbDirty = true; this._offset = math.vec3(); this._colorizeUpdated = false; @@ -69,36 +68,40 @@ export class SceneModelEntity { } } - _setLocalAABBDirty() { // Called when mesh AABBs updated - this._localAABBDirty = true; + _transformDirty() { + this._aabbDirty = true; + this.model._transformDirty(); } - _setWorldAABBDirty() { // called when SceneModel world transform updated - this._worldAABBDirty = true; + _sceneModelDirty() { + this._aabbDirty = true; + for (let i = 0, len = this.meshes.length; i < len; i++) { + this.meshes[i]._sceneModelDirty(); + } } get aabb() { - if (this._localAABBDirty) { + if (this._aabbDirty) { math.collapseAABB3(this._aabb); for (let i = 0, len = this.meshes.length; i < len; i++) { math.expandAABB3(this._aabb, this.meshes[i].aabb); } - this._localAABBDirty = false; - this._worldAABBDirty = true; - } - if (this._worldAABBDirty) { - math.AABB3ToOBB3(this._aabb, tempOBB3a); - math.transformOBB3(this.model.matrix, tempOBB3a); - math.OBB3ToAABB3(tempOBB3a, this._worldAABB); - this._worldAABB[0] += this._offset[0]; - this._worldAABB[1] += this._offset[1]; - this._worldAABB[2] += this._offset[2]; - this._worldAABB[3] += this._offset[0]; - this._worldAABB[4] += this._offset[1]; - this._worldAABB[5] += this._offset[2]; - this._worldAABBDirty = false; - } - return this._worldAABB; + this._aabbDirty = false; + this._aabbDirty = true; + } + // if (this._aabbDirty) { + // math.AABB3ToOBB3(this._aabb, tempOBB3a); + // math.transformOBB3(this.model.matrix, tempOBB3a); + // math.OBB3ToAABB3(tempOBB3a, this._worldAABB); + // this._worldAABB[0] += this._offset[0]; + // this._worldAABB[1] += this._offset[1]; + // this._worldAABB[2] += this._offset[2]; + // this._worldAABB[3] += this._offset[0]; + // this._worldAABB[4] += this._offset[1]; + // this._worldAABB[5] += this._offset[2]; + // this._aabbDirty = false; + // } + return this._aabb; } get isEntity() { @@ -417,7 +420,7 @@ export class SceneModelEntity { for (let i = 0, len = this.meshes.length; i < len; i++) { this.meshes[i]._setOffset(this._offset); } - this._worldAABBDirty = true; + this._aabbDirty = true; this.model._aabbDirty = true; this.scene._aabbDirty = true; this.scene._objectOffsetUpdated(this, offset); diff --git a/src/viewer/scene/model/SceneModelMesh.js b/src/viewer/scene/model/SceneModelMesh.js index d4d9036ce8..4fab1f308e 100644 --- a/src/viewer/scene/model/SceneModelMesh.js +++ b/src/viewer/scene/model/SceneModelMesh.js @@ -1,6 +1,7 @@ import {math} from "../math/math.js"; const tempOBB3 = math.OBB3(); +const tempOBB3b = math.OBB3(); /** * A mesh within a {@link SceneModel}. @@ -103,14 +104,18 @@ export class SceneModelMesh { } } - _setMatrixDirty() { + _sceneModelDirty() { + this._aabbDirty = true; + } + + _transformDirty() { if (!this._matrixDirty && !this._matrixUpdateScheduled) { this.model._meshMatrixDirty(this); this._matrixDirty = true; this._aabbDirty = true; this._matrixUpdateScheduled = true; if (this.entity) { - this.entity._setLocalAABBDirty(); + this.entity._transformDirty(); } } } @@ -289,8 +294,9 @@ export class SceneModelMesh { get aabb() { // called by SceneModelEntity if (this._aabbDirty) { if (this.obb && this.transform) { - math.transformOBB3(this.transform.worldMatrix, this.obb, tempOBB3); - math.OBB3ToAABB3(tempOBB3, this._aabb); + math.transformOBB3(this.transform.worldMatrix, this.obb, tempOBB3); + math.transformOBB3(this.model.worldMatrix, tempOBB3, tempOBB3b); + math.OBB3ToAABB3(tempOBB3b, this._aabb); } } this._aabbDirty = false; diff --git a/src/viewer/scene/model/SceneModelTransform.js b/src/viewer/scene/model/SceneModelTransform.js index e3b4fc61ca..12d355193e 100644 --- a/src/viewer/scene/model/SceneModelTransform.js +++ b/src/viewer/scene/model/SceneModelTransform.js @@ -207,7 +207,7 @@ export class SceneModelTransform { this._localMatrix.set(value || identityMat); math.decomposeMat4(this._localMatrix, this._position, this._quaternion, this._scale); this._localMatrixDirty = false; - this._setWorldMatrixDirty(); + this._transformDirty(); this._model.glRedraw(); } @@ -358,25 +358,25 @@ export class SceneModelTransform { _setLocalMatrixDirty() { this._localMatrixDirty = true; - this._setWorldMatrixDirty(); + this._transformDirty(); } - _setWorldMatrixDirty() { + _transformDirty() { this._worldMatrixDirty = true; for (let i = 0, len = this._childTransforms.length; i < len; i++) { const childTransform = this._childTransforms[i]; - childTransform._setWorldMatrixDirty(); + childTransform._transformDirty(); if (childTransform._meshes && childTransform._meshes.length > 0) { const meshes = childTransform._meshes; for (let j =0, lenj = meshes.length; j < lenj; j++) { - meshes[j]._setMatrixDirty(); + meshes[j]._transformDirty(); } } } if (this._meshes && this._meshes.length > 0) { const meshes = this._meshes; for (let j =0, lenj = meshes.length; j < lenj; j++) { - meshes[j]._setMatrixDirty(); + meshes[j]._transformDirty(); } } } diff --git a/src/viewer/scene/model/vbo/linesInstancing/LinesInstancingLayer.js b/src/viewer/scene/model/vbo/linesInstancing/LinesInstancingLayer.js index 22a357cc1b..e0c58c7a8f 100644 --- a/src/viewer/scene/model/vbo/linesInstancing/LinesInstancingLayer.js +++ b/src/viewer/scene/model/vbo/linesInstancing/LinesInstancingLayer.js @@ -15,6 +15,8 @@ const tempVec4c = math.vec4([0, 0, 0, 1]); const tempVec3fa = new Float32Array(3); +const tempFloat32Vec4 = new Float32Array(4); + /** * @private */ @@ -519,6 +521,34 @@ class LinesInstancingLayer { this._state.offsetsBuf.setData(tempVec3fa, portionId * 3, 3); } + setMatrix(portionId, matrix) { + if (!this._finalized) { + throw "Not finalized"; + } + const offset = portionId * 4; + + tempFloat32Vec4[0] = matrix[0]; + tempFloat32Vec4[1] = matrix[4]; + tempFloat32Vec4[2] = matrix[8]; + tempFloat32Vec4[3] = matrix[12]; + + this._state.modelMatrixCol0Buf.setData(tempFloat32Vec4, offset); + + tempFloat32Vec4[0] = matrix[1]; + tempFloat32Vec4[1] = matrix[5]; + tempFloat32Vec4[2] = matrix[9]; + tempFloat32Vec4[3] = matrix[13]; + + this._state.modelMatrixCol1Buf.setData(tempFloat32Vec4, offset); + + tempFloat32Vec4[0] = matrix[2]; + tempFloat32Vec4[1] = matrix[6]; + tempFloat32Vec4[2] = matrix[10]; + tempFloat32Vec4[3] = matrix[14]; + + this._state.modelMatrixCol2Buf.setData(tempFloat32Vec4, offset); + } + // ---------------------- NORMAL RENDERING ----------------------------------- drawColorOpaque(renderFlags, frameCtx) { diff --git a/src/viewer/scene/model/vbo/pointsInstancing/PointsInstancingLayer.js b/src/viewer/scene/model/vbo/pointsInstancing/PointsInstancingLayer.js index 5cfd117c0a..27fd1ab313 100644 --- a/src/viewer/scene/model/vbo/pointsInstancing/PointsInstancingLayer.js +++ b/src/viewer/scene/model/vbo/pointsInstancing/PointsInstancingLayer.js @@ -13,6 +13,8 @@ const tempVec4b = math.vec4([0, 0, 0, 1]); const tempVec4c = math.vec4([0, 0, 0, 1]); const tempVec3fa = new Float32Array(3); +const tempFloat32Vec4 = new Float32Array(4); + /** * @private */ @@ -546,6 +548,34 @@ class PointsInstancingLayer { this._state.offsetsBuf.setData(tempVec3fa, portionId * 3); } + setMatrix(portionId, matrix) { + if (!this._finalized) { + throw "Not finalized"; + } + const offset = portionId * 4; + + tempFloat32Vec4[0] = matrix[0]; + tempFloat32Vec4[1] = matrix[4]; + tempFloat32Vec4[2] = matrix[8]; + tempFloat32Vec4[3] = matrix[12]; + + this._state.modelMatrixCol0Buf.setData(tempFloat32Vec4, offset); + + tempFloat32Vec4[0] = matrix[1]; + tempFloat32Vec4[1] = matrix[5]; + tempFloat32Vec4[2] = matrix[9]; + tempFloat32Vec4[3] = matrix[13]; + + this._state.modelMatrixCol1Buf.setData(tempFloat32Vec4, offset); + + tempFloat32Vec4[0] = matrix[2]; + tempFloat32Vec4[1] = matrix[6]; + tempFloat32Vec4[2] = matrix[10]; + tempFloat32Vec4[3] = matrix[14]; + + this._state.modelMatrixCol2Buf.setData(tempFloat32Vec4, offset); + } + // ---------------------- NORMAL RENDERING ----------------------------------- drawColorOpaque(renderFlags, frameCtx) {