From 9f10af3ba669cff49cdd74631c149c46bf193afe Mon Sep 17 00:00:00 2001
From: David Sehnal <david.sehnal@gmail.com>
Date: Wed, 26 Jun 2019 13:41:53 +0200
Subject: [PATCH] proteopedia-wrapper: clipping commands; mol-canvas3d:
 camera.getFocus optional direction

---
 src/examples/proteopedia-wrapper/changelog.md |  4 +++
 src/examples/proteopedia-wrapper/index.html   |  6 +++-
 src/examples/proteopedia-wrapper/index.ts     | 35 ++++++++++++++++++-
 src/mol-canvas3d/camera.ts                    | 19 ++++++----
 src/mol-canvas3d/canvas3d.ts                  |  7 ++--
 5 files changed, 59 insertions(+), 12 deletions(-)

diff --git a/src/examples/proteopedia-wrapper/changelog.md b/src/examples/proteopedia-wrapper/changelog.md
index b9d8bd109..e8e8cb5a3 100644
--- a/src/examples/proteopedia-wrapper/changelog.md
+++ b/src/examples/proteopedia-wrapper/changelog.md
@@ -1,3 +1,7 @@
+== v3.3 ==
+
+* Camera Clipping.
+
 == v3.2 ==
 
 * Fixed assembly loading.
diff --git a/src/examples/proteopedia-wrapper/index.html b/src/examples/proteopedia-wrapper/index.html
index 632496100..b73831739 100644
--- a/src/examples/proteopedia-wrapper/index.html
+++ b/src/examples/proteopedia-wrapper/index.html
@@ -130,7 +130,11 @@
             addSeparator();
 
             addHeader('Camera');
-            addControl('Toggle Spin', () => PluginWrapper.toggleSpin());
+            addControl('Reset Position', () => PluginWrapper.camera.resetPosition());
+            addControl('Toggle Spin', () => PluginWrapper.camera.toggleSpin());
+            // Same as "wheel icon" and Viewport options
+            addControl('Clip', () => PluginWrapper.viewport.setSettings({ clip: [33, 66] }));
+            addControl('Reset Clip', () => PluginWrapper.viewport.setSettings({ clip: [1, 100] }));
             
             addSeparator();
 
diff --git a/src/examples/proteopedia-wrapper/index.ts b/src/examples/proteopedia-wrapper/index.ts
index 750503e5e..1aa4f7c2a 100644
--- a/src/examples/proteopedia-wrapper/index.ts
+++ b/src/examples/proteopedia-wrapper/index.ts
@@ -29,6 +29,7 @@ import { BuiltInSizeThemes } from '../../mol-theme/size';
 import { ColorNames } from '../../mol-util/color/tables';
 import { InitVolumeStreaming, CreateVolumeStreamingInfo } from '../../mol-plugin/behavior/dynamic/volume-streaming/transformers';
 import { ParamDefinition } from '../../mol-util/param-definition';
+import { DefaultCanvas3DParams, Canvas3DProps } from '../../mol-canvas3d/canvas3d';
 // import { Vec3 } from 'mol-math/linear-algebra';
 // import { ParamDefinition } from 'mol-util/param-definition';
 // import { Text } from 'mol-geo/geometry/text/text';
@@ -36,7 +37,7 @@ require('../../mol-plugin/skin/light.scss')
 
 class MolStarProteopediaWrapper {
     static VERSION_MAJOR = 3;
-    static VERSION_MINOR = 2;
+    static VERSION_MINOR = 3;
 
     private _ev = RxEventHelper.create();
 
@@ -241,6 +242,38 @@ class MolStarProteopediaWrapper {
         if (!spinning) PluginCommands.Camera.Reset.dispatch(this.plugin, { });
     }
 
+    viewport = {
+        setSettings: (settings?: Canvas3DProps) => {
+            PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, {
+                settings: settings || DefaultCanvas3DParams
+            });
+        }
+    };
+
+    camera = {
+        toggleSpin: () => this.toggleSpin(),
+        resetPosition: () => PluginCommands.Camera.Reset.dispatch(this.plugin, { }),
+        // setClip: (options?: { distance?: number, near?: number, far?: number }) => {
+        //     if (!options) {
+        //         PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, {
+        //             settings: {
+        //                 cameraClipDistance: DefaultCanvas3DParams.cameraClipDistance,
+        //                 clip: DefaultCanvas3DParams.clip
+        //             }
+        //         });
+        //         return;
+        //     }
+
+        //     options = options || { };
+        //     const props = this.plugin.canvas3d.props;
+        //     const clipNear = typeof options.near === 'undefined' ? props.clip[0] : options.near;
+        //     const clipFar = typeof options.far === 'undefined' ? props.clip[1] : options.far;
+        //     PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, {
+        //         settings: { cameraClipDistance: options.distance, clip: [clipNear, clipFar] }
+        //     });
+        // }
+    }
+
     animate = {
         modelIndex: {
             maxFPS: 8,
diff --git a/src/mol-canvas3d/camera.ts b/src/mol-canvas3d/camera.ts
index 21c300e59..5975c83ed 100644
--- a/src/mol-canvas3d/camera.ts
+++ b/src/mol-canvas3d/camera.ts
@@ -90,25 +90,30 @@ class Camera implements Object3D {
         return ret;
     }
 
-    getFocus(target: Vec3, radius: number): Partial<Camera.Snapshot> {
+    getFocus(target: Vec3, radius: number, dir?: Vec3): Partial<Camera.Snapshot> {
         const fov = this.state.fov
         const { width, height } = this.viewport
         const aspect = width / height
         const aspectFactor = (height < width ? 1 : aspect)
         const currentDistance = Vec3.distance(this.state.position, target)
         const targetDistance = Math.abs((radius / aspectFactor) / Math.sin(fov / 2))
+
         const deltaDistance = Math.abs(currentDistance - targetDistance)
 
-        Vec3.sub(this.deltaDirection, this.state.position, target)
-        Vec3.setMagnitude(this.deltaDirection, this.state.direction, deltaDistance)
-        if (currentDistance < targetDistance) Vec3.negate(this.deltaDirection, this.deltaDirection)
-        Vec3.add(this.newPosition, this.state.position, this.deltaDirection)
+        if (dir) {
+            Vec3.setMagnitude(this.deltaDirection, dir, targetDistance)
+            Vec3.add(this.newPosition, target, this.deltaDirection)
+        } else {
+            Vec3.setMagnitude(this.deltaDirection, this.state.direction, deltaDistance)
+            if (currentDistance < targetDistance) Vec3.negate(this.deltaDirection, this.deltaDirection)
+            Vec3.add(this.newPosition, this.state.position, this.deltaDirection)
+        }
 
         return { target, position: Vec3.clone(this.newPosition) };
     }
 
-    focus(target: Vec3, radius: number) {
-        this.setState(this.getFocus(target, radius));
+    focus(target: Vec3, radius: number, dir?: Vec3) {
+        this.setState(this.getFocus(target, radius, dir));
     }
 
     // lookAt(target: Vec3) {
diff --git a/src/mol-canvas3d/canvas3d.ts b/src/mol-canvas3d/canvas3d.ts
index d34f8a656..ac6e086b5 100644
--- a/src/mol-canvas3d/canvas3d.ts
+++ b/src/mol-canvas3d/canvas3d.ts
@@ -46,6 +46,7 @@ export const Canvas3DParams = {
     trackball: PD.Group(TrackballControlsParams),
     debug: PD.Group(DebugHelperParams)
 }
+export const DefaultCanvas3DParams = PD.getDefaultValues(Canvas3DParams);
 export type Canvas3DProps = PD.Values<typeof Canvas3DParams>
 
 export { Canvas3D }
@@ -103,7 +104,7 @@ namespace Canvas3D {
     }
 
     export function create(gl: GLRenderingContext, input: InputObserver, props: Partial<Canvas3DProps> = {}): Canvas3D {
-        const p = { ...PD.getDefaultValues(Canvas3DParams), ...props }
+        const p = { ...DefaultCanvas3DParams, ...props }
 
         const reprRenderObjects = new Map<Representation.Any, Set<GraphicsRenderObject>>()
         const reprUpdatedSubscriptions = new Map<Representation.Any, Subscription>()
@@ -333,8 +334,8 @@ namespace Canvas3D {
             getLoci,
 
             handleResize,
-            resetCamera: () => {
-                camera.focus(scene.boundingSphere.center, scene.boundingSphere.radius)
+            resetCamera: (dir?: Vec3) => {
+                camera.focus(scene.boundingSphere.center, scene.boundingSphere.radius, dir);
                 requestDraw(true);
             },
             camera,
-- 
GitLab