From ed75fe54cc06380361cdb0e3b2ce704e4eb64531 Mon Sep 17 00:00:00 2001 From: Alexander Rose <alex.rose@rcsb.org> Date: Wed, 12 Dec 2018 16:08:33 -0800 Subject: [PATCH] structure animation tweaks --- package-lock.json | Bin 485094 -> 485088 bytes src/mol-plugin/behavior/dynamic/animation.ts | 71 ++++++++++++------- src/mol-plugin/index.ts | 2 +- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4d591a55215d505271ecf6a6c0714d886142aa28..8dd941ab943fd2727d03938f79af7d152d4c532c 100644 GIT binary patch delta 326 zcmaEMR`$VJ*@i8Qrz0jCbc;>?vz>GM>j*}(u*nDb#HZgWW|5kHSc+9+d*ymY&-c?4 z4zr3+w`XEuonD~CCN%lMtF6-~m@!MV@0-uGecya$j(O7^QrX0}-?L@$WCAg#OrG#Y zV*3>bmMLanz1thgS=t3a7ER}mW#rqg)4>uY1eQUVy7|GY4UE$TxEcATzq-xL+uksT zWqZRM)@@86ZQFh4vu<TV(=qwMtAo=|C9(5QpJ&g`IXzE}No4wgxvb{XU)i(EOn=nN zs<D0MV%D$x5N+{F%$(cTZ)TOqn4X}<CcWLypIw7-x`PNC`*s0YHd$$qHSI1IY};Kd e*vpte!La>;6?;A}T(u_S_9jpEO{{Q%8R7taV|C;J delta 285 zcmaEGR`%Ih*@i8Qrz56s@L`mk{BJw^_E!;%W?_>Jy2Ym7EM}3KEVNT&d*ymY&-c?e zd}WoK?hwxYxP9+@rtN#@Gjq(FuHeKXx&5v!iwD#650Na|+x;C_#LTB3*vBlfy{4R{ zT>xaP#B}~xM&9imGAv1q(`&@p)wgfxWVt8+H}CXxg{zD_?FF-0winE1J-|F&VIzyg zcK7+LTbR()Y=5<gb&deYc*W`e-m?g7-?o{RBLnQ#{qGnRw&!`U^Ds_t6=mb!E+ES$ uDm{HdD4RsPjRo6w8w>VQCXmAIC#=}>c|ok{FfIGpP`JE|+Y1BO^ThzMacrUh diff --git a/src/mol-plugin/behavior/dynamic/animation.ts b/src/mol-plugin/behavior/dynamic/animation.ts index b3696db3f..e79562ce6 100644 --- a/src/mol-plugin/behavior/dynamic/animation.ts +++ b/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 }); \ No newline at end of file diff --git a/src/mol-plugin/index.ts b/src/mol-plugin/index.ts index cf3507b2a..a22b53ddb 100644 --- a/src/mol-plugin/index.ts +++ b/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 }), ] -- GitLab