SimpleInteractionHelper.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. module Sandbox {
  2. import Scene = BABYLON.Scene;
  3. import Observer = BABYLON.Observer;
  4. import PointerInfo = BABYLON.PointerInfo;
  5. import EventState = BABYLON.EventState;
  6. import PointerEventTypes = BABYLON.PointerEventTypes;
  7. import AbstractMesh = BABYLON.AbstractMesh;
  8. import Node = BABYLON.Node;
  9. export const enum SIHCurrentAction {
  10. None, Selector, Camerator
  11. }
  12. /**
  13. * The purpose of this class is to allow the camera manipulation, single node selection and manipulation.
  14. * You can use it as an example to create your more complexe/different interaction helper
  15. */
  16. export class SimpleInteractionHelper {
  17. constructor(scene: Scene) {
  18. this._actionStack = new Array<SIHCurrentAction>();
  19. this._scene = scene;
  20. this._pointerObserver = this._scene.onPointerObservable.add((p, s) => this.pointerCallback(p, s), -1, true);
  21. }
  22. get currentAction(): SIHCurrentAction {
  23. if (this._actionStack.length === 0) {
  24. return SIHCurrentAction.Selector;
  25. }
  26. return this._actionStack[this._actionStack.length - 1];
  27. }
  28. get manipulator(): ManipulatorInteractionHelper {
  29. if (!this._manipulator) {
  30. this._manipulator = new ManipulatorInteractionHelper(this._scene);
  31. }
  32. return this._manipulator;
  33. }
  34. private pointerCallback(p: PointerInfo, s: EventState) {
  35. this.detectActionChanged(p, s);
  36. switch (this.currentAction) {
  37. case SIHCurrentAction.Selector:
  38. this.doSelectorInteraction(p, s);
  39. break;
  40. case SIHCurrentAction.Camerator:
  41. if (p.type & (PointerEventTypes.POINTERUP | PointerEventTypes.POINTERWHEEL)) {
  42. this._actionStack.pop();
  43. }
  44. break;
  45. }
  46. }
  47. private doSelectorInteraction(p: PointerInfo, s: EventState) {
  48. s.skipNextObservers = true;
  49. // We want left button up.
  50. if (p.type !== PointerEventTypes.POINTERUP || p.event.button!==0) {
  51. return;
  52. }
  53. var selectedMesh: AbstractMesh;
  54. if (p.pickInfo.hit) {
  55. selectedMesh = p.pickInfo.pickedMesh;
  56. }
  57. // We selected the same mesh? nothing to do
  58. if (this._pickedNode === selectedMesh) {
  59. selectedMesh.showBoundingBox = !selectedMesh.showBoundingBox;
  60. if (selectedMesh.showBoundingBox===false) {
  61. this.manipulator.detachManipulatedNode(this._pickedNode);
  62. this._pickedNode = null;
  63. }
  64. return;
  65. }
  66. // Detach the manipulator to the current selected mesh
  67. if (this._pickedNode) {
  68. if (this._pickedNode instanceof AbstractMesh) {
  69. var mesh = <AbstractMesh>this._pickedNode;
  70. mesh.showBoundingBox = false;
  71. }
  72. this.manipulator.detachManipulatedNode(this._pickedNode);
  73. this._pickedNode = null;
  74. }
  75. // Nothing selected, our job's done
  76. if (!selectedMesh) {
  77. return;
  78. }
  79. this._pickedNode = selectedMesh;
  80. selectedMesh.showBoundingBox = true;
  81. this.manipulator.attachManipulatedNode(this._pickedNode);
  82. }
  83. private detectActionChanged(p: PointerInfo, s: EventState) {
  84. // Detect switch from selection to camerator
  85. if (this.currentAction === SIHCurrentAction.Selector) {
  86. if (p.type === PointerEventTypes.POINTERDOWN) {
  87. if (!p.pickInfo.hit) {
  88. this._actionStack.push(SIHCurrentAction.Camerator);
  89. return;
  90. }
  91. }
  92. if (p.type === PointerEventTypes.POINTERWHEEL) {
  93. this._actionStack.push(SIHCurrentAction.Camerator);
  94. return;
  95. }
  96. }
  97. }
  98. private static CameratorSwitchThreshold = 4.0;
  99. private _pickedNode: Node;
  100. private _actionStack: Array<SIHCurrentAction>;
  101. private _scene: Scene;
  102. private _pointerObserver: Observer<PointerInfo>;
  103. private _manipulator: ManipulatorInteractionHelper;
  104. }
  105. }