Bladeren bron

bounding sphere helper and transform data fixes and tweaks

Alexander Rose 6 jaren geleden
bovenliggende
commit
8dc4d45093
3 gewijzigde bestanden met toevoegingen van 37 en 23 verwijderingen
  1. 30 21
      src/mol-canvas3d/helper/bounding-sphere-helper.ts
  2. 2 1
      src/mol-geo/geometry/transform-data.ts
  3. 5 1
      src/mol-gl/scene.ts

+ 30 - 21
src/mol-canvas3d/helper/bounding-sphere-helper.ts

@@ -15,6 +15,9 @@ import { Sphere3D } from 'mol-math/geometry';
 import { Color } from 'mol-util/color';
 import { ColorNames } from 'mol-util/color/tables';
 import { TransformData } from 'mol-geo/geometry/transform-data';
+import { sphereVertexCount } from 'mol-geo/primitive/sphere';
+import { ValueCell } from 'mol-util';
+import { Geometry } from 'mol-geo/geometry/geometry';
 
 export const DebugHelperParams = {
     sceneBoundingSpheres: PD.Boolean(false, { description: 'Show scene bounding spheres.' }),
@@ -24,10 +27,11 @@ export const DebugHelperParams = {
 export type DebugHelperParams = typeof DebugHelperParams
 export type DebugHelperProps = PD.Values<DebugHelperParams>
 
-type BoundingSphereData = { boundingSphere: Sphere3D, renderObject: RenderObject }
+type BoundingSphereData = { boundingSphere: Sphere3D, renderObject: RenderObject, mesh: Mesh }
 
 export class BoundingSphereHelper {
     readonly scene: Scene
+
     private readonly parent: Scene
     private _props: DebugHelperProps
     private objectsData = new Map<RenderObject, BoundingSphereData>()
@@ -44,9 +48,6 @@ export class BoundingSphereHelper {
         const newSceneData = updateBoundingSphereData(this.scene, this.parent.boundingSphere, this.sceneData, ColorNames.grey)
         if (newSceneData) this.sceneData = newSceneData
 
-        const oldRO = new Set<RenderObject>()
-        this.objectsData.forEach((_, ro) => oldRO.add(ro))
-        this.instancesData.forEach((_, ro) => oldRO.add(ro))
         this.parent.forEach((r, ro) => {
             const objectData = this.objectsData.get(ro)
             const newObjectData = updateBoundingSphereData(this.scene, r.boundingSphere, objectData, ColorNames.tomato)
@@ -63,17 +64,16 @@ export class BoundingSphereHelper {
                 })
                 if (newInstanceData) this.instancesData.set(ro, newInstanceData)
             }
-
-            oldRO.delete(ro)
         })
-        oldRO.forEach(ro => {
-            const objectData = this.objectsData.get(ro)
-            if (objectData) {
+
+        this.objectsData.forEach((objectData, ro) => {
+            if (!this.parent.has(ro)) {
                 this.scene.remove(objectData.renderObject)
                 this.objectsData.delete(ro)
             }
-            const instanceData = this.instancesData.get(ro)
-            if (instanceData) {
+        })
+        this.instancesData.forEach((instanceData, ro) => {
+            if (!this.parent.has(ro)) {
                 this.scene.remove(instanceData.renderObject)
                 this.instancesData.delete(ro)
             }
@@ -83,7 +83,7 @@ export class BoundingSphereHelper {
     }
 
     syncVisibility() {
-        if(this.sceneData) {
+        if (this.sceneData) {
             this.sceneData.renderObject.state.visible = this._props.sceneBoundingSpheres
         }
 
@@ -114,18 +114,27 @@ export class BoundingSphereHelper {
 }
 
 function updateBoundingSphereData(scene: Scene, boundingSphere: Sphere3D, data: BoundingSphereData | undefined, color: Color, transform?: TransformData) {
-    if (!data || !Sphere3D.exactEquals(data.boundingSphere, boundingSphere)) {
-        if (data) scene.remove(data.renderObject)
-        const renderObject = createBoundingSphereRenderObject(boundingSphere, color, transform)
-        scene.add(renderObject)
-        return { boundingSphere: Sphere3D.clone(boundingSphere), renderObject }
+    if (!data || !Sphere3D.equals(data.boundingSphere, boundingSphere)) {
+        const mesh = createBoundingSphereMesh(boundingSphere, data && data.mesh)
+        const renderObject = data ? data.renderObject : createBoundingSphereRenderObject(mesh, color, transform)
+        if (data) {
+            ValueCell.update(renderObject.values.drawCount, Geometry.getDrawCount(mesh))
+        } else {
+            scene.add(renderObject)
+        }
+        return { boundingSphere: Sphere3D.clone(boundingSphere), renderObject, mesh }
     }
 }
 
-function createBoundingSphereRenderObject(boundingSphere: Sphere3D, color: Color, transform?: TransformData) {
-    const builderState = MeshBuilder.createState(1024, 512)
-    if (boundingSphere.radius) addSphere(builderState, boundingSphere.center, boundingSphere.radius, 2)
-    const mesh = MeshBuilder.getMesh(builderState)
+function createBoundingSphereMesh(boundingSphere: Sphere3D, mesh?: Mesh) {
+    const detail = 2
+    const vertexCount = sphereVertexCount(detail)
+    const builderState = MeshBuilder.createState(vertexCount, vertexCount / 2, mesh)
+    if (boundingSphere.radius) addSphere(builderState, boundingSphere.center, boundingSphere.radius, detail)
+    return MeshBuilder.getMesh(builderState)
+}
+
+function createBoundingSphereRenderObject(mesh: Mesh, color: Color, transform?: TransformData) {
     const values = Mesh.createValuesSimple(mesh, { alpha: 0.1, doubleSided: false }, color, transform)
     return createMeshRenderObject(values, { visible: true, pickable: false, opaque: false })
 }

+ 2 - 1
src/mol-geo/geometry/transform-data.ts

@@ -19,6 +19,7 @@ export type TransformData = {
 export function createTransform(transformArray: Float32Array, instanceCount: number, transformData?: TransformData): TransformData {
     if (transformData) {
         ValueCell.update(transformData.aTransform, transformArray)
+        ValueCell.update(transformData.transform, new Float32Array(transformArray))
         ValueCell.update(transformData.uInstanceCount, instanceCount)
         ValueCell.update(transformData.instanceCount, instanceCount)
         const aInstance = transformData.aInstance.ref.value.length >= instanceCount ? transformData.aInstance.ref.value : new Float32Array(instanceCount)
@@ -38,7 +39,7 @@ export function createTransform(transformArray: Float32Array, instanceCount: num
 const identityTransform = new Float32Array(16)
 Mat4.toArray(Mat4.identity(), identityTransform, 0)
 export function createIdentityTransform(transformData?: TransformData): TransformData {
-    return createTransform(identityTransform, 1, transformData)
+    return createTransform(new Float32Array(identityTransform), 1, transformData)
 }
 
 const tmpTransformMat4 = Mat4.identity()

+ 5 - 1
src/mol-gl/scene.ts

@@ -27,7 +27,7 @@ function calculateBoundingSphere(renderables: Renderable<RenderableValues & Base
         const r = renderables[i]
         if (!r.boundingSphere.radius) continue;
         boundaryHelper.extendStep(r.boundingSphere.center, r.boundingSphere.radius);
-    };
+    }
 
     Vec3.copy(boundingSphere.center, boundaryHelper.center);
     boundingSphere.radius = boundaryHelper.radius;
@@ -43,6 +43,7 @@ interface Scene extends Object3D {
     update: (keepBoundingSphere?: boolean) => void
     add: (o: RenderObject) => void
     remove: (o: RenderObject) => void
+    has: (o: RenderObject) => boolean
     clear: () => void
     forEach: (callbackFn: (value: Renderable<any>, key: RenderObject) => void) => void
 }
@@ -89,6 +90,9 @@ namespace Scene {
                     boundingSphereDirty = true
                 }
             },
+            has: (o: RenderObject) => {
+                return renderableMap.has(o)
+            },
             clear: () => {
                 for (let i = 0, il = renderables.length; i < il; ++i) {
                     renderables[i].dispose()