babylon.gizmoManager.ts 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. module BABYLON {
  2. /**
  3. * Helps setup gizmo's in the scene to rotate/scale/position meshes
  4. */
  5. export class GizmoManager implements IDisposable{
  6. /**
  7. * Gizmo's created by the gizmo manager, gizmo will be null until gizmo has been enabled for the first time
  8. */
  9. public gizmos:{positionGizmo: Nullable<PositionGizmo>, rotationGizmo: Nullable<RotationGizmo>, scaleGizmo: Nullable<ScaleGizmo>, boundingBoxGizmo: Nullable<BoundingBoxGizmo>};
  10. private _gizmosEnabled = {positionGizmo: false, rotationGizmo: false, scaleGizmo: false, boundingBoxGizmo: false};
  11. private _pointerObserver:Nullable<Observer<PointerInfo>> = null;
  12. private _attachedMesh:Nullable<AbstractMesh> = null;
  13. private _boundingBoxColor = BABYLON.Color3.FromHexString("#0984e3");
  14. /**
  15. * When bounding box gizmo is enabled, this can be used to track drag/end events
  16. */
  17. public boundingBoxDragBehavior = new BABYLON.SixDofDragBehavior();
  18. /**
  19. * Array of meshes which will have the gizmo attached when a pointer selected them. If null, all meshes are attachable. (Default: null)
  20. */
  21. public attachableMeshes:Nullable<Array<AbstractMesh>> = null;
  22. /**
  23. * If pointer events should perform attaching/detaching a gizmo, if false this can be done manually via attachToMesh. (Default: true)
  24. */
  25. public usePointerToAttachGizmos = true;
  26. /**
  27. * Instatiates a gizmo manager
  28. * @param scene the scene to overlay the gizmos on top of
  29. */
  30. constructor(private scene:Scene){
  31. this.gizmos = {positionGizmo: null, rotationGizmo: null, scaleGizmo: null, boundingBoxGizmo: null};
  32. // Instatiate/dispose gizmos based on pointer actions
  33. this._pointerObserver = scene.onPointerObservable.add((pointerInfo, state)=>{
  34. if(!this.usePointerToAttachGizmos){
  35. return;
  36. }
  37. if(pointerInfo.type == BABYLON.PointerEventTypes.POINTERDOWN){
  38. if(pointerInfo.pickInfo && pointerInfo.pickInfo.pickedMesh){
  39. var node:Nullable<Node> = pointerInfo.pickInfo.pickedMesh;
  40. if(this.attachableMeshes == null){
  41. // Attach to the most parent node
  42. while(node && node.parent != null){
  43. node = node.parent;
  44. }
  45. }else{
  46. // Attach to the parent node that is an attachableMesh
  47. var found = false;
  48. this.attachableMeshes.forEach((mesh)=>{
  49. if(node && (node == mesh || node.isDescendantOf(mesh))){
  50. node = mesh;
  51. found = true;
  52. }
  53. })
  54. if(!found){
  55. node = null;
  56. }
  57. }
  58. if(node instanceof AbstractMesh){
  59. this.attachToMesh(node);
  60. }else{
  61. this.attachToMesh(null);
  62. }
  63. }else{
  64. this.attachToMesh(null);
  65. }
  66. }
  67. })
  68. }
  69. /**
  70. * Attaches a set of gizmos to the specified mesh
  71. * @param mesh The mesh the gizmo's should be attached to
  72. */
  73. public attachToMesh(mesh:Nullable<AbstractMesh>){
  74. if(this._attachedMesh){
  75. this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);
  76. }
  77. this._attachedMesh = mesh;
  78. for(var key in this.gizmos){
  79. var gizmo = <Nullable<Gizmo>>((<any>this.gizmos)[key]);
  80. if(gizmo && (<any>this._gizmosEnabled)[key]){
  81. gizmo.attachedMesh = mesh;
  82. }
  83. }
  84. if(this.boundingBoxGizmoEnabled && this._attachedMesh){
  85. this._attachedMesh.addBehavior(this.boundingBoxDragBehavior);
  86. }
  87. }
  88. /**
  89. * If the position gizmo is enabled
  90. */
  91. public set positionGizmoEnabled(value:boolean){
  92. if(value){
  93. if(!this.gizmos.positionGizmo){
  94. this.gizmos.positionGizmo = new PositionGizmo();
  95. this.gizmos.positionGizmo.updateGizmoRotationToMatchAttachedMesh = false;
  96. }
  97. this.gizmos.positionGizmo.attachedMesh = this._attachedMesh;
  98. }else if(this.gizmos.positionGizmo){
  99. this.gizmos.positionGizmo.attachedMesh = null;
  100. }
  101. this._gizmosEnabled.positionGizmo = value;
  102. }
  103. public get positionGizmoEnabled():boolean{
  104. return this._gizmosEnabled.positionGizmo;
  105. }
  106. /**
  107. * If the rotation gizmo is enabled
  108. */
  109. public set rotationGizmoEnabled(value:boolean){
  110. if(value){
  111. if(!this.gizmos.rotationGizmo){
  112. this.gizmos.rotationGizmo = new RotationGizmo();
  113. this.gizmos.rotationGizmo.updateGizmoRotationToMatchAttachedMesh = false;
  114. }
  115. this.gizmos.rotationGizmo.attachedMesh = this._attachedMesh;
  116. }else if(this.gizmos.rotationGizmo){
  117. this.gizmos.rotationGizmo.attachedMesh = null;
  118. }
  119. this._gizmosEnabled.rotationGizmo = value;
  120. }
  121. public get rotationGizmoEnabled():boolean{
  122. return this._gizmosEnabled.rotationGizmo;
  123. }
  124. /**
  125. * If the scale gizmo is enabled
  126. */
  127. public set scaleGizmoEnabled(value:boolean){
  128. if(value){
  129. this.gizmos.scaleGizmo = this.gizmos.scaleGizmo || new ScaleGizmo();
  130. this.gizmos.scaleGizmo.attachedMesh = this._attachedMesh;
  131. }else if(this.gizmos.scaleGizmo){
  132. this.gizmos.scaleGizmo.attachedMesh = null;
  133. }
  134. this._gizmosEnabled.scaleGizmo = value;
  135. }
  136. public get scaleGizmoEnabled():boolean{
  137. return this._gizmosEnabled.scaleGizmo;
  138. }
  139. /**
  140. * If the boundingBox gizmo is enabled
  141. */
  142. public set boundingBoxGizmoEnabled(value:boolean){
  143. if(value){
  144. this.gizmos.boundingBoxGizmo = this.gizmos.boundingBoxGizmo || new BoundingBoxGizmo(this._boundingBoxColor);
  145. this.gizmos.boundingBoxGizmo.attachedMesh = this._attachedMesh;
  146. if(this._attachedMesh){
  147. this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);
  148. this._attachedMesh.addBehavior(this.boundingBoxDragBehavior);
  149. }
  150. }else if(this.gizmos.boundingBoxGizmo){
  151. this.gizmos.boundingBoxGizmo.attachedMesh = null;
  152. }
  153. this._gizmosEnabled.boundingBoxGizmo = value;
  154. }
  155. public get boundingBoxGizmoEnabled():boolean{
  156. return this._gizmosEnabled.boundingBoxGizmo;
  157. }
  158. /**
  159. * Disposes of the gizmo manager
  160. */
  161. public dispose(){
  162. this.scene.onPointerObservable.remove(this._pointerObserver);
  163. for(var key in this.gizmos){
  164. var gizmo = <Nullable<Gizmo>>((<any>this.gizmos)[key]);
  165. if(gizmo){
  166. gizmo.dispose();
  167. }
  168. }
  169. this.boundingBoxDragBehavior.detach();
  170. }
  171. }
  172. }