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

wip, structure animation

parent d4d81410
No related branches found
No related tags found
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.
Finish editing this message first!
Please register or to comment