ソースを参照

structure animation tweaks

Alexander Rose 6 年 前
コミット
ed75fe54cc
3 ファイル変更62 行追加43 行削除
  1. 16 16
      package-lock.json
  2. 45 26
      src/mol-plugin/behavior/dynamic/animation.ts
  3. 1 1
      src/mol-plugin/index.ts

+ 16 - 16
package-lock.json

@@ -2163,7 +2163,7 @@
     },
     "camelcase-keys": {
       "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+      "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
       "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
       "dev": true,
       "requires": {
@@ -2767,7 +2767,7 @@
       "dependencies": {
         "node-fetch": {
           "version": "2.1.2",
-          "resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
+          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
           "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=",
           "dev": true
         }
@@ -4595,7 +4595,7 @@
         },
         "strip-ansi": {
           "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
           "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
           "dev": true,
           "requires": {
@@ -7458,7 +7458,7 @@
     },
     "meow": {
       "version": "3.7.0",
-      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+      "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
       "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
       "dev": true,
       "requires": {
@@ -7476,7 +7476,7 @@
       "dependencies": {
         "minimist": {
           "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
           "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
           "dev": true
         }
@@ -7847,7 +7847,7 @@
       "dependencies": {
         "semver": {
           "version": "5.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+          "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
           "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
           "dev": true
         }
@@ -7963,7 +7963,7 @@
         },
         "chalk": {
           "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+          "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
           "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
           "dev": true,
           "requires": {
@@ -8075,7 +8075,7 @@
         },
         "strip-ansi": {
           "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
           "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
           "dev": true,
           "requires": {
@@ -9887,7 +9887,7 @@
         },
         "os-locale": {
           "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+          "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
           "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
           "dev": true,
           "requires": {
@@ -9907,7 +9907,7 @@
         },
         "strip-ansi": {
           "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
           "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
           "dev": true,
           "requires": {
@@ -10031,7 +10031,7 @@
       "dependencies": {
         "source-map": {
           "version": "0.4.4",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+          "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
           "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
           "dev": true,
           "requires": {
@@ -10738,7 +10738,7 @@
         },
         "string_decoder": {
           "version": "1.1.1",
-          "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
           "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
           "dev": true,
           "requires": {
@@ -10935,7 +10935,7 @@
     },
     "tar": {
       "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+      "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
       "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
       "dev": true,
       "requires": {
@@ -12656,7 +12656,7 @@
     },
     "whatwg-fetch": {
       "version": "2.0.4",
-      "resolved": "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
+      "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
       "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==",
       "dev": true
     },
@@ -12741,7 +12741,7 @@
         },
         "string_decoder": {
           "version": "1.1.1",
-          "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
           "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
           "dev": true,
           "requires": {
@@ -12783,7 +12783,7 @@
         },
         "string_decoder": {
           "version": "1.1.1",
-          "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
           "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
           "dev": true,
           "requires": {

+ 45 - 26
src/mol-plugin/behavior/dynamic/animation.ts

@@ -11,74 +11,93 @@ import { degToRad } from 'mol-math/misc';
 import { Mat4, Vec3 } from 'mol-math/linear-algebra';
 import { PluginStateObject as SO, PluginStateObject } from '../../state/objects';
 import { StateSelection } from 'mol-state/state/selection';
+import { StateObjectCell, State } from 'mol-state';
+
+const StructureAnimationParams = {
+    rotate: PD.Boolean(false)
+}
+type StructureAnimationProps = PD.Values<typeof StructureAnimationParams>
+
+function getRootStructure(root: StateObjectCell, state: State) {
+    let parent: StateObjectCell | undefined
+    while (true) {
+        const _parent = StateSelection.findAncestorOfType(state.tree, state.cells, root.transform.ref, [PluginStateObject.Molecule.Structure])
+        if (_parent) {
+            parent = _parent
+            root = _parent
+        } else {
+            break
+        }
+    }
+    if (!parent || !parent.obj) return
+    return parent.obj as PluginStateObject.Molecule.Structure
+}
 
 // TODO this is just for testing purposes
-export const Animation = PluginBehavior.create<{ play: boolean }>({
-    name: 'animation',
-    display: { name: 'Animation', group: 'Animation' },
-    ctor: class extends PluginBehavior.Handler<{ play: boolean }> {
+export const StructureAnimation = PluginBehavior.create<StructureAnimationProps>({
+    name: 'structure-animation',
+    display: { name: 'Structure Animation', group: 'Animation' },
+    ctor: class extends PluginBehavior.Handler<StructureAnimationProps> {
         private tmpMat = Mat4.identity()
         private rotMat = Mat4.identity()
         private transMat = Mat4.identity()
-        private animMat = Mat4.identity()
+        private rotAnimMat = Mat4.identity()
         private transVec = Vec3.zero()
         private rotVec = Vec3.create(0, 1, 0)
-        private animHandle = -1
 
-        constructor(protected ctx: PluginContext, protected params: { play: boolean }) {
+        private rotateAnimHandle = -1
+
+        constructor(protected ctx: PluginContext, protected params: StructureAnimationProps) {
             super(ctx, params)
             this.update(params)
         }
 
-        animate(play: boolean) {
+        rotate(play: boolean) {
             if (play) {
                 const state = this.ctx.state.dataState
                 const reprs = state.select(q => q.rootsOfType(PluginStateObject.Molecule.Representation3D));
-                const anim = (t: number) => {
+                const rotate = (t: number) => {
                     const rad = degToRad((t / 10) % 360)
                     Mat4.rotate(this.rotMat, this.tmpMat, rad, this.rotVec)
                     for (const r of reprs) {
                         if (!SO.isRepresentation3D(r.obj)) return
-                        const parent = StateSelection.findAncestorOfType(state.tree, state.cells, r.transform.ref, [PluginStateObject.Molecule.Structure])
-                        if (!parent || !parent.obj) continue
-                        const structure = parent.obj as PluginStateObject.Molecule.Structure
+                        const structure = getRootStructure(r, state)
+                        if (!structure) continue
 
                         Vec3.negate(this.transVec, Vec3.copy(this.transVec, structure.data.boundary.sphere.center))
                         Mat4.fromTranslation(this.transMat, this.transVec)
-                        Mat4.mul(this.animMat, this.rotMat, this.transMat)
+                        Mat4.mul(this.rotAnimMat, this.rotMat, this.transMat)
 
                         Vec3.copy(this.transVec, structure.data.boundary.sphere.center)
                         Mat4.fromTranslation(this.transMat, this.transVec)
-                        Mat4.mul(this.animMat, this.transMat, this.animMat)
+                        Mat4.mul(this.rotAnimMat, this.transMat, this.rotAnimMat)
 
-                        r.obj.data.setState({ transform: this.animMat })
+                        r.obj.data.setState({ transform: this.rotAnimMat })
                         this.ctx.canvas3d.add(r.obj.data)
                         this.ctx.canvas3d.requestDraw(true)
                     }
-                    this.animHandle = requestAnimationFrame(anim)
+                    this.rotateAnimHandle = requestAnimationFrame(rotate)
                 }
-                this.animHandle = requestAnimationFrame(anim)
+                this.rotateAnimHandle = requestAnimationFrame(rotate)
             } else {
-                cancelAnimationFrame(this.animHandle)
+                cancelAnimationFrame(this.rotateAnimHandle)
             }
         }
 
         register(): void { }
 
-        update(p: { play: boolean }) {
-            let updated = this.params.play !== p.play
-            this.params.play = p.play
+        update(p: StructureAnimationProps) {
+            let updated = this.params.rotate !== p.rotate
+            this.params.rotate = p.rotate
             if (updated) {
-                this.animate(this.params.play)
+                this.rotate(this.params.rotate)
             }
             return updated;
         }
 
         unregister() {
-            cancelAnimationFrame(this.animHandle)
+            cancelAnimationFrame(this.rotateAnimHandle)
         }
     },
-    params: () => ({
-        play: PD.Boolean(false)
-    })
+    params: () => StructureAnimationParams
 });

+ 1 - 1
src/mol-plugin/index.ts

@@ -37,7 +37,7 @@ const DefaultSpec: PluginSpec = {
         PluginSpec.Behavior(PluginBehaviors.Representation.SelectLoci),
         PluginSpec.Behavior(PluginBehaviors.Representation.DefaultLociLabelProvider),
         PluginSpec.Behavior(PluginBehaviors.Camera.FocusLociOnSelect, { minRadius: 20, extraRadius: 4 }),
-        PluginSpec.Behavior(PluginBehaviors.Animation.Animation, { play: false }),
+        PluginSpec.Behavior(PluginBehaviors.Animation.StructureAnimation, { rotate: false }),
         PluginSpec.Behavior(PluginBehaviors.CustomProps.PDBeStructureQualityReport, { autoAttach: true }),
         PluginSpec.Behavior(PluginBehaviors.CustomProps.RCSBAssemblySymmetry, { autoAttach: true }),
     ]