Browse Source

fix camera.radius = 0 (leads to NaNs)

David Sehnal 5 years ago
parent
commit
95c43d0864
3 changed files with 13 additions and 7 deletions
  1. 5 3
      src/mol-canvas3d/camera.ts
  2. 7 3
      src/mol-canvas3d/canvas3d.ts
  3. 1 1
      src/mol-plugin-ui/viewport.tsx

+ 5 - 3
src/mol-canvas3d/camera.ts

@@ -86,11 +86,12 @@ class Camera {
     }
 
     getFocus(target: Vec3, radius: number, up?: Vec3, dir?: Vec3): Partial<Camera.Snapshot> {
+        const r = Math.max(radius, 0.01)
         const { fov } = this.state
         const { width, height } = this.viewport
         const aspect = width / height
         const aspectFactor = (height < width ? 1 : aspect)
-        const targetDistance = Math.abs((radius / aspectFactor) / Math.sin(fov / 2))
+        const targetDistance = Math.abs((r / aspectFactor) / Math.sin(fov / 2))
 
         Vec3.sub(this.deltaDirection, this.target, this.position)
         if (dir) Vec3.matchDirection(this.deltaDirection, dir, this.deltaDirection)
@@ -99,7 +100,7 @@ class Camera {
 
         const state = Camera.copySnapshot(Camera.createDefaultSnapshot(), this.state)
         state.target = Vec3.clone(target)
-        state.radius = radius
+        state.radius = r
         state.position = Vec3.clone(this.newPosition)
         if (up) Vec3.matchDirection(state.up, up, state.up)
 
@@ -264,7 +265,8 @@ function updatePers(camera: Camera) {
 }
 
 function updateClip(camera: Camera) {
-    const { radius, radiusMax, mode, fog, clipFar } = camera.state
+    let { radius, radiusMax, mode, fog, clipFar } = camera.state
+    if (radius < 0.01) radius = 0.01
 
     const normalizedFar = clipFar ? radius : radiusMax
     const cameraDistance = Vec3.distance(camera.position, camera.target)

+ 7 - 3
src/mol-canvas3d/canvas3d.ts

@@ -45,7 +45,7 @@ export const Canvas3DParams = {
         off: PD.Group({})
     }, { cycle: true, description: 'Show fog in the distance' }),
     cameraClipping: PD.Group({
-        radius: PD.Numeric(100, { min: 0, max: 100, step: 1 }, { label: 'Clipping', description: 'How much of the scene to show.' }),
+        radius: PD.Numeric(100, { min: 0, max: 99, step: 1 }, { label: 'Clipping', description: 'How much of the scene to show.' }),
         far: PD.Boolean(true, { description: 'Hide scene in the distance' }),
     }, { pivot: 'radius' }),
 
@@ -441,8 +441,11 @@ namespace Canvas3D {
                         cameraState.clipFar = props.cameraClipping.far
                     }
                     if (props.cameraClipping.radius !== undefined) {
-                        const radius = (scene.boundingSphere.radius / 100) * (100 - props.cameraClipping.radius)
-                        if (radius !== cameraState.radius) cameraState.radius = radius
+                        const radius = (scene.boundingSphere.radius / 100) * (100 - props.cameraClipping.radius)                        
+                        if (radius > 0 && radius !== cameraState.radius) {
+                            // if radius = 0, NaNs happen
+                            cameraState.radius = Math.max(radius, 0.01)
+                        }
                     }
                 }
                 if (Object.keys(cameraState).length > 0) camera.setState(cameraState)
@@ -455,6 +458,7 @@ namespace Canvas3D {
                 if (props.renderer) renderer.setProps(props.renderer)
                 if (props.trackball) controls.setProps(props.trackball)
                 if (props.debug) debugHelper.setProps(props.debug)
+
                 requestDraw(true)
             },
             getImagePass: (props: Partial<ImageProps> = {}) => {

+ 1 - 1
src/mol-plugin-ui/viewport.tsx

@@ -103,7 +103,7 @@ export class ViewportControls extends PluginUIComponent<ViewportControlsProps, V
                 </ControlGroup>
             </div>}
             {this.state.isSettingsExpanded && <div className='msp-viewport-controls-panel'>
-                <ControlGroup header='Settings' initialExpanded={true} hideExpander={true} hideOffset={true} onHeaderClick={this.toggleSettingsExpanded} topRightIcon='off'>
+                <ControlGroup header='Settings / Controls Info' initialExpanded={true} hideExpander={true} hideOffset={true} onHeaderClick={this.toggleSettingsExpanded} topRightIcon='off'>
                     <SimpleSettingsControl />
                 </ControlGroup>
             </div>}