animation.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { PluginContext } from 'mol-plugin/context';
  7. import { PluginBehavior } from '../behavior';
  8. import { ParamDefinition as PD } from 'mol-util/param-definition'
  9. import { degToRad } from 'mol-math/misc';
  10. import { Mat4, Vec3 } from 'mol-math/linear-algebra';
  11. import { PluginStateObject as SO, PluginStateObject } from '../../state/objects';
  12. import { StateSelection } from 'mol-state/state/selection';
  13. // TODO this is just for testing purposes
  14. export const Animation = PluginBehavior.create<{ play: boolean }>({
  15. name: 'animation',
  16. display: { name: 'Animation', group: 'Animation' },
  17. ctor: class extends PluginBehavior.Handler<{ play: boolean }> {
  18. private tmpMat = Mat4.identity()
  19. private rotMat = Mat4.identity()
  20. private transMat = Mat4.identity()
  21. private animMat = Mat4.identity()
  22. private transVec = Vec3.zero()
  23. private rotVec = Vec3.create(0, 1, 0)
  24. private animHandle = -1
  25. constructor(protected ctx: PluginContext, protected params: { play: boolean }) {
  26. super(ctx, params)
  27. this.update(params)
  28. }
  29. animate(play: boolean) {
  30. if (play) {
  31. const state = this.ctx.state.dataState
  32. const reprs = state.select(q => q.rootsOfType(PluginStateObject.Molecule.Representation3D));
  33. const anim = (t: number) => {
  34. const rad = degToRad((t / 10) % 360)
  35. Mat4.rotate(this.rotMat, this.tmpMat, rad, this.rotVec)
  36. for (const r of reprs) {
  37. if (!SO.isRepresentation3D(r.obj)) return
  38. const parent = StateSelection.findAncestorOfType(state.tree, state.cells, r.transform.ref, [PluginStateObject.Molecule.Structure])
  39. if (!parent || !parent.obj) continue
  40. const structure = parent.obj as PluginStateObject.Molecule.Structure
  41. Vec3.negate(this.transVec, Vec3.copy(this.transVec, structure.data.boundary.sphere.center))
  42. Mat4.fromTranslation(this.transMat, this.transVec)
  43. Mat4.mul(this.animMat, this.rotMat, this.transMat)
  44. Vec3.copy(this.transVec, structure.data.boundary.sphere.center)
  45. Mat4.fromTranslation(this.transMat, this.transVec)
  46. Mat4.mul(this.animMat, this.transMat, this.animMat)
  47. r.obj.data.setState({ transform: this.animMat })
  48. this.ctx.canvas3d.add(r.obj.data)
  49. this.ctx.canvas3d.requestDraw(true)
  50. }
  51. this.animHandle = requestAnimationFrame(anim)
  52. }
  53. this.animHandle = requestAnimationFrame(anim)
  54. } else {
  55. cancelAnimationFrame(this.animHandle)
  56. }
  57. }
  58. register(): void { }
  59. update(p: { play: boolean }) {
  60. let updated = this.params.play !== p.play
  61. this.params.play = p.play
  62. if (updated) {
  63. this.animate(this.params.play)
  64. }
  65. return updated;
  66. }
  67. unregister() {
  68. cancelAnimationFrame(this.animHandle)
  69. }
  70. },
  71. params: () => ({
  72. play: PD.Boolean(false)
  73. })
  74. });