Skip to content
Snippets Groups Projects
Commit e41bb35f authored by Alexander Rose's avatar Alexander Rose
Browse files

wip, structure animation

parent d4d81410
Branches
Tags
No related merge requests found
...@@ -14,10 +14,16 @@ import { StateSelection } from 'mol-state/state/selection'; ...@@ -14,10 +14,16 @@ import { StateSelection } from 'mol-state/state/selection';
import { StateObjectCell, State } from 'mol-state'; import { StateObjectCell, State } from 'mol-state';
const StructureAnimationParams = { const StructureAnimationParams = {
rotate: PD.Boolean(false) rotate: PD.Boolean(false),
explode: PD.Boolean(false)
} }
type StructureAnimationProps = PD.Values<typeof StructureAnimationParams> type StructureAnimationProps = PD.Values<typeof StructureAnimationParams>
function getStructure(root: StateObjectCell, state: State) {
const parent = StateSelection.findAncestorOfType(state.tree, state.cells, root.transform.ref, [PluginStateObject.Molecule.Structure])
return parent && parent.obj ? parent.obj as PluginStateObject.Molecule.Structure : undefined
}
function getRootStructure(root: StateObjectCell, state: State) { function getRootStructure(root: StateObjectCell, state: State) {
let parent: StateObjectCell | undefined let parent: StateObjectCell | undefined
while (true) { while (true) {
...@@ -29,8 +35,7 @@ function getRootStructure(root: StateObjectCell, state: State) { ...@@ -29,8 +35,7 @@ function getRootStructure(root: StateObjectCell, state: State) {
break break
} }
} }
if (!parent || !parent.obj) return return parent && parent.obj ? parent.obj as PluginStateObject.Molecule.Structure : undefined
return parent.obj as PluginStateObject.Molecule.Structure
} }
// TODO this is just for testing purposes // TODO this is just for testing purposes
...@@ -41,11 +46,12 @@ export const StructureAnimation = PluginBehavior.create<StructureAnimationProps> ...@@ -41,11 +46,12 @@ export const StructureAnimation = PluginBehavior.create<StructureAnimationProps>
private tmpMat = Mat4.identity() private tmpMat = Mat4.identity()
private rotMat = Mat4.identity() private rotMat = Mat4.identity()
private transMat = Mat4.identity() private transMat = Mat4.identity()
private rotAnimMat = Mat4.identity() private animMat = Mat4.identity()
private transVec = Vec3.zero() private transVec = Vec3.zero()
private rotVec = Vec3.create(0, 1, 0) private rotVec = Vec3.create(0, 1, 0)
private rotateAnimHandle = -1 private rotateAnimHandle = -1
private explodeAnimHandle = -1
constructor(protected ctx: PluginContext, protected params: StructureAnimationProps) { constructor(protected ctx: PluginContext, protected params: StructureAnimationProps) {
super(ctx, params) super(ctx, params)
...@@ -66,13 +72,13 @@ export const StructureAnimation = PluginBehavior.create<StructureAnimationProps> ...@@ -66,13 +72,13 @@ export const StructureAnimation = PluginBehavior.create<StructureAnimationProps>
Vec3.negate(this.transVec, Vec3.copy(this.transVec, structure.data.boundary.sphere.center)) Vec3.negate(this.transVec, Vec3.copy(this.transVec, structure.data.boundary.sphere.center))
Mat4.fromTranslation(this.transMat, this.transVec) Mat4.fromTranslation(this.transMat, this.transVec)
Mat4.mul(this.rotAnimMat, this.rotMat, this.transMat) Mat4.mul(this.animMat, this.rotMat, this.transMat)
Vec3.copy(this.transVec, structure.data.boundary.sphere.center) Vec3.copy(this.transVec, structure.data.boundary.sphere.center)
Mat4.fromTranslation(this.transMat, this.transVec) Mat4.fromTranslation(this.transMat, this.transVec)
Mat4.mul(this.rotAnimMat, this.transMat, this.rotAnimMat) Mat4.mul(this.animMat, this.transMat, this.animMat)
r.obj.data.setState({ transform: this.rotAnimMat }) r.obj.data.setState({ transform: this.animMat })
this.ctx.canvas3d.add(r.obj.data) this.ctx.canvas3d.add(r.obj.data)
this.ctx.canvas3d.requestDraw(true) this.ctx.canvas3d.requestDraw(true)
} }
...@@ -84,19 +90,53 @@ export const StructureAnimation = PluginBehavior.create<StructureAnimationProps> ...@@ -84,19 +90,53 @@ export const StructureAnimation = PluginBehavior.create<StructureAnimationProps>
} }
} }
explode(play: boolean) {
if (play) {
const state = this.ctx.state.dataState
const reprs = state.select(q => q.rootsOfType(PluginStateObject.Molecule.Representation3D));
const explode = (t: number) => {
const d = (Math.sin(t * 0.001) + 1) * 5
for (const r of reprs) {
if (!SO.isRepresentation3D(r.obj)) return
const structure = getStructure(r, state)
if (!structure) continue
const rootStructure = getRootStructure(r, state)
if (!rootStructure) continue
Vec3.sub(this.transVec, structure.data.boundary.sphere.center, rootStructure.data.boundary.sphere.center)
Vec3.setMagnitude(this.transVec, this.transVec, d)
Mat4.fromTranslation(this.animMat, this.transVec)
r.obj.data.setState({ transform: this.animMat })
this.ctx.canvas3d.add(r.obj.data)
this.ctx.canvas3d.requestDraw(true)
}
this.explodeAnimHandle = requestAnimationFrame(explode)
}
this.explodeAnimHandle = requestAnimationFrame(explode)
} else {
cancelAnimationFrame(this.explodeAnimHandle)
}
}
register(): void { } register(): void { }
update(p: StructureAnimationProps) { update(p: StructureAnimationProps) {
let updated = this.params.rotate !== p.rotate let updated = PD.areEqual(StructureAnimationParams, this.params, p)
this.params.rotate = p.rotate if (this.params.rotate !== p.rotate) {
if (updated) { this.params.rotate = p.rotate
this.rotate(this.params.rotate) this.rotate(this.params.rotate)
} }
if (this.params.explode !== p.explode) {
this.params.explode = p.explode
this.explode(this.params.explode)
}
return updated; return updated;
} }
unregister() { unregister() {
cancelAnimationFrame(this.rotateAnimHandle) cancelAnimationFrame(this.rotateAnimHandle)
cancelAnimationFrame(this.explodeAnimHandle)
} }
}, },
params: () => StructureAnimationParams params: () => StructureAnimationParams
......
...@@ -37,7 +37,7 @@ const DefaultSpec: PluginSpec = { ...@@ -37,7 +37,7 @@ const DefaultSpec: PluginSpec = {
PluginSpec.Behavior(PluginBehaviors.Representation.SelectLoci), PluginSpec.Behavior(PluginBehaviors.Representation.SelectLoci),
PluginSpec.Behavior(PluginBehaviors.Representation.DefaultLociLabelProvider), PluginSpec.Behavior(PluginBehaviors.Representation.DefaultLociLabelProvider),
PluginSpec.Behavior(PluginBehaviors.Camera.FocusLociOnSelect, { minRadius: 20, extraRadius: 4 }), PluginSpec.Behavior(PluginBehaviors.Camera.FocusLociOnSelect, { minRadius: 20, extraRadius: 4 }),
PluginSpec.Behavior(PluginBehaviors.Animation.StructureAnimation, { rotate: false }), PluginSpec.Behavior(PluginBehaviors.Animation.StructureAnimation, { rotate: false, explode: false }),
PluginSpec.Behavior(PluginBehaviors.CustomProps.PDBeStructureQualityReport, { autoAttach: true }), PluginSpec.Behavior(PluginBehaviors.CustomProps.PDBeStructureQualityReport, { autoAttach: true }),
PluginSpec.Behavior(PluginBehaviors.CustomProps.RCSBAssemblySymmetry, { autoAttach: true }), PluginSpec.Behavior(PluginBehaviors.CustomProps.RCSBAssemblySymmetry, { autoAttach: true }),
] ]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment