Browse Source

camera helper tweaks

- add highlighting
- improved axes alignment
Alexander Rose 4 years ago
parent
commit
9264987817

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

@@ -331,11 +331,13 @@ namespace Canvas3D {
                 changed = repr.mark(loci, action);
             } else {
                 changed = helper.handle.mark(loci, action);
+                changed = helper.camera.mark(loci, action) || changed;
                 reprRenderObjects.forEach((_, _repr) => { changed = _repr.mark(loci, action) || changed; });
             }
             if (changed) {
                 scene.update(void 0, true);
                 helper.handle.scene.update(void 0, true);
+                helper.camera.scene.update(void 0, true);
                 const prevPickDirty = pickHelper.dirty;
                 draw(true);
                 pickHelper.dirty = prevPickDirty; // marking does not change picking buffers

+ 24 - 1
src/mol-canvas3d/helper/camera-helper.ts

@@ -1,10 +1,11 @@
 /**
- * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2020-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
 import produce from 'immer';
+import { Interval } from '../../mol-data/int/interval';
 import { addCylinder } from '../../mol-geo/geometry/mesh/builder/cylinder';
 import { addSphere } from '../../mol-geo/geometry/mesh/builder/sphere';
 import { Mesh } from '../../mol-geo/geometry/mesh/mesh';
@@ -17,7 +18,9 @@ import { Sphere3D } from '../../mol-math/geometry';
 import { Mat4, Vec3 } from '../../mol-math/linear-algebra';
 import { DataLoci, EmptyLoci, Loci } from '../../mol-model/loci';
 import { Shape } from '../../mol-model/shape';
+import { Visual } from '../../mol-repr/visual';
 import { ColorNames } from '../../mol-util/color/names';
+import { MarkerAction, MarkerActions } from '../../mol-util/marker-action';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { Camera, ICamera } from '../camera';
 import { Viewport } from '../camera/util';
@@ -95,6 +98,26 @@ export class CameraHelper {
         return CameraAxesLoci(this, groupId, instanceId);
     }
 
+    private eachGroup = (loci: Loci, apply: (interval: Interval) => boolean): boolean => {
+        if (!this.renderObject) return false;
+        if (!isCameraAxesLoci(loci)) return false;
+        let changed = false;
+        const groupCount = this.renderObject.values.uGroupCount.ref.value;
+        const { elements } = loci;
+        for (const { groupId, instanceId } of elements) {
+            const idx = instanceId * groupCount + groupId;
+            if (apply(Interval.ofSingleton(idx))) changed = true;
+        }
+        return changed;
+    }
+
+    mark(loci: Loci, action: MarkerAction) {
+        if (!MarkerActions.is(MarkerActions.Highlighting, action)) return false;
+        if (!isCameraAxesLoci(loci)) return false;
+        if (loci.data !== this) return false;
+        return Visual.mark(this.renderObject, loci, action, this.eachGroup);
+    }
+
     update(camera: ICamera) {
         if (!this.renderObject) return;
 

+ 18 - 9
src/mol-plugin/behavior/dynamic/camera.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -83,12 +83,22 @@ export const CameraAxisHelper = PluginBehavior.create<{}>({
                     lastPlane = CameraHelperAxis.None;
                     state = 0;
                     return;
-                } else if (axis >= CameraHelperAxis.X && axis <= CameraHelperAxis.Z) {
+                }
+
+                const { camera } = this.ctx.canvas3d;
+                let dir: Vec3, up: Vec3;
+
+                if (axis >= CameraHelperAxis.X && axis <= CameraHelperAxis.Z) {
                     lastPlane = CameraHelperAxis.None;
                     state = 0;
-                    const up = Vec3();
+
+                    const d = Vec3.sub(Vec3(), camera.target, camera.position);
+                    const c = Vec3.cross(Vec3(), d, camera.up);
+
+                    up = Vec3();
                     up[axis - 1] = 1;
-                    this.ctx.canvas3d.requestCameraReset({ snapshot: { up } });
+                    dir = Vec3.cross(Vec3(), up, c);
+                    if (Vec3.magnitude(dir) === 0) dir = d;
                 } else {
                     if (lastPlane === axis) {
                         state = (state + 1) % 2;
@@ -97,7 +107,6 @@ export const CameraAxisHelper = PluginBehavior.create<{}>({
                         state = 0;
                     }
 
-                    let up: Vec3, dir: Vec3;
                     if (axis === CameraHelperAxis.XY) {
                         up = state ? Vec3.unitX : Vec3.unitY;
                         dir = Vec3.negUnitZ;
@@ -108,11 +117,11 @@ export const CameraAxisHelper = PluginBehavior.create<{}>({
                         up = state ? Vec3.unitY : Vec3.unitZ;
                         dir = Vec3.negUnitX;
                     }
-
-                    this.ctx.canvas3d.requestCameraReset({
-                        snapshot: (scene, camera) => camera.getInvariantFocus(scene.boundingSphereVisible.center, scene.boundingSphereVisible.radius, up, dir)
-                    });
                 }
+
+                this.ctx.canvas3d.requestCameraReset({
+                    snapshot: (scene, camera) => camera.getInvariantFocus(scene.boundingSphereVisible.center, scene.boundingSphereVisible.radius, up, dir)
+                });
             });
         }
     },