Bladeren bron

added debug bounding sphere helper

Alexander Rose 6 jaren geleden
bovenliggende
commit
b29428e430

+ 14 - 0
src/mol-canvas3d/canvas3d.ts

@@ -27,6 +27,7 @@ import { Loci, EmptyLoci, isEmptyLoci } from 'mol-model/loci';
 import { Color } from 'mol-util/color';
 import { Camera } from './camera';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
+import { BoundingSphereHelper } from './helper/bounding-sphere-helper';
 
 export const Canvas3DParams = {
     // TODO: FPS cap?
@@ -35,6 +36,9 @@ export const Canvas3DParams = {
     cameraMode: PD.Select('perspective', [['perspective', 'Perspective'], ['orthographic', 'Orthographic']]),
     backgroundColor: PD.Color(Color(0x000000)),
     pickingAlphaThreshold: PD.Numeric(0.5, { min: 0.0, max: 1.0, step: 0.01 }, { description: 'The minimum opacity value needed for an object to be pickable.' }),
+    debug: PD.Group({
+        showBoundingSpheres: PD.Boolean(true, { description: 'Show bounding spheres of render objects.' }),
+    })
 }
 export type Canvas3DParams = typeof Canvas3DParams
 
@@ -122,6 +126,8 @@ namespace Canvas3D {
         let drawPending = false
         let lastRenderTime = -1
 
+        const boundingSphereHelper = new BoundingSphereHelper(scene, p.debug.showBoundingSpheres)
+
         function getLoci(pickingId: PickingId) {
             let loci: Loci = EmptyLoci
             let repr: Representation.Any = Representation.Empty
@@ -292,6 +298,7 @@ namespace Canvas3D {
             }
             reprRenderObjects.set(repr, newRO)
             reprCount.next(reprRenderObjects.size)
+            boundingSphereHelper.update()
             scene.update()
             requestDraw(true)
         }
@@ -324,6 +331,7 @@ namespace Canvas3D {
                     renderObjects.forEach(o => scene.remove(o))
                     reprRenderObjects.delete(repr)
                     reprCount.next(reprRenderObjects.size)
+                    boundingSphereHelper.update()
                     scene.update()
                 }
             },
@@ -369,6 +377,9 @@ namespace Canvas3D {
                 if (props.pickingAlphaThreshold !== undefined && props.pickingAlphaThreshold !== renderer.props.pickingAlphaThreshold) {
                     renderer.setPickingAlphaThreshold(props.pickingAlphaThreshold)
                 }
+                if (props.debug && props.debug.showBoundingSpheres) {
+                    boundingSphereHelper.visible = props.debug.showBoundingSpheres
+                }
                 requestDraw(true)
             },
 
@@ -378,6 +389,9 @@ namespace Canvas3D {
                     cameraMode: camera.state.mode,
                     backgroundColor: renderer.props.clearColor,
                     pickingAlphaThreshold: renderer.props.pickingAlphaThreshold,
+                    debug: {
+                        showBoundingSpheres: boundingSphereHelper.visible
+                    }
                 }
             },
             get input() {

+ 43 - 0
src/mol-canvas3d/helper/bounding-sphere-helper.ts

@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { createMeshRenderObject, MeshRenderObject } from 'mol-gl/render-object'
+import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder';
+import { addSphere } from 'mol-geo/geometry/mesh/builder/sphere';
+import { Mesh } from 'mol-geo/geometry/mesh/mesh';
+import { Geometry } from 'mol-geo/geometry/geometry';
+import { ValueCell } from 'mol-util';
+import Scene from 'mol-gl/scene';
+
+export class BoundingSphereHelper {
+    private mesh: Mesh
+    private renderObject: MeshRenderObject
+
+    constructor(private scene: Scene, visible: boolean) {
+        const builder = MeshBuilder.create(1024, 512)
+        this.mesh = builder.getMesh()
+        const values = Mesh.createValuesSimple(this.mesh, { alpha: 0.1 })
+        this.renderObject = createMeshRenderObject(values, { visible, pickable: false })
+        scene.add(this.renderObject)
+    }
+
+    update() {
+        const builder = MeshBuilder.create(1024, 512, this.mesh)
+        if (this.scene.boundingSphere.radius) {
+            addSphere(builder, this.scene.boundingSphere.center, this.scene.boundingSphere.radius, 3)
+        }
+        this.scene.forEach(r => {
+            if (r.boundingSphere.radius) {
+                addSphere(builder, r.boundingSphere.center, r.boundingSphere.radius, 3)
+            }
+        })
+        this.mesh = builder.getMesh()
+        ValueCell.update(this.renderObject.values.drawCount, Geometry.getDrawCount(this.mesh))
+    }
+
+    get visible() { return this.renderObject.state.visible }
+    set visible(value: boolean) { this.renderObject.state.visible = value }
+}

+ 1 - 1
src/mol-geo/geometry/geometry.ts

@@ -108,7 +108,7 @@ export function createRenderableState(props: PD.Values<Geometry.Params>): Render
 }
 
 export function updateRenderableState(state: RenderableState, props: PD.Values<Geometry.Params>) {
-    
+
 }
 
 //

+ 34 - 2
src/mol-geo/geometry/mesh/mesh.ts

@@ -11,14 +11,16 @@ import { Sphere3D } from 'mol-math/geometry'
 import { transformPositionArray/* , transformDirectionArray, getNormalMatrix */ } from '../../util';
 import { Geometry } from '../geometry';
 import { createMarkers } from '../marker-data';
-import { TransformData } from '../transform-data';
+import { TransformData, createIdentityTransform } from '../transform-data';
 import { LocationIterator } from '../../util/location-iterator';
-import { createColors } from '../color-data';
+import { createColors, createValueColor } from '../color-data';
 import { ChunkedArray } from 'mol-data/util';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
 import { calculateBoundingSphere } from 'mol-gl/renderable/util';
 import { Theme } from 'mol-theme/theme';
 import { MeshValues } from 'mol-gl/renderable/mesh';
+import { ColorTheme } from 'mol-theme/color';
+import { NullLocation } from 'mol-model/location';
 
 export interface Mesh {
     readonly kind: 'mesh',
@@ -376,6 +378,36 @@ export namespace Mesh {
         }
     }
 
+    export function createValuesSimple(mesh: Mesh, props: Partial<PD.Values<Params>>): MeshValues {
+        const p = { ...PD.getDefaultValues(Params), ...props }
+        const transform = createIdentityTransform()
+        const color = createValueColor(ColorTheme.Empty.color(NullLocation, false))
+        const marker = createMarkers(1)
+
+        const counts = { drawCount: mesh.triangleCount * 3, groupCount: 1, instanceCount: 1 }
+
+        const boundingSphere = calculateBoundingSphere(
+            mesh.vertexBuffer.ref.value, mesh.vertexCount,
+            transform.aTransform.ref.value, transform.instanceCount.ref.value
+        )
+
+        return {
+            aPosition: mesh.vertexBuffer,
+            aNormal: mesh.normalBuffer,
+            aGroup: mesh.groupBuffer,
+            elements: mesh.indexBuffer,
+            boundingSphere: ValueCell.create(boundingSphere),
+            ...color,
+            ...marker,
+            ...transform,
+
+            ...Geometry.createValues(p, counts),
+            dDoubleSided: ValueCell.create(p.doubleSided),
+            dFlatShaded: ValueCell.create(p.flatShaded),
+            dFlipSided: ValueCell.create(p.flipSided),
+        }
+    }
+
     export function updateValues(values: MeshValues, props: PD.Values<Params>) {
         const boundingSphere = calculateBoundingSphere(
             values.aPosition.ref.value, Math.floor(values.aPosition.ref.value.length / 3),

+ 5 - 4
src/mol-theme/theme.ts

@@ -30,10 +30,7 @@ export interface Theme {
 type Props = { [k: string]: any }
 
 export function createTheme(ctx: ThemeRegistryContext, data: ThemeDataContext, props: Props, theme?: Theme) {
-    theme = theme || {
-        color: ColorTheme.Empty,
-        size: SizeTheme.Empty
-    }
+    theme = theme || createEmptyTheme()
 
     const colorProps = props.colorTheme as PD.NamedParams
     const sizeProps = props.sizeTheme as PD.NamedParams
@@ -42,4 +39,8 @@ export function createTheme(ctx: ThemeRegistryContext, data: ThemeDataContext, p
     theme.size = ctx.sizeThemeRegistry.create(sizeProps.name, data, sizeProps.params)
 
     return theme
+}
+
+export function createEmptyTheme() {
+    return { color: ColorTheme.Empty, size: SizeTheme.Empty }
 }