babylon.axisScaleGizmo.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. module BABYLON {
  2. /**
  3. * Single axis scale gizmo
  4. */
  5. export class AxisScaleGizmo extends Gizmo {
  6. /**
  7. * Drag behavior responsible for the gizmos dragging interactions
  8. */
  9. public dragBehavior:PointerDragBehavior;
  10. private _pointerObserver:Nullable<Observer<PointerInfo>> = null;
  11. /**
  12. * Scale distance in babylon units that the gizmo will snap to when dragged (Default: 0)
  13. */
  14. public snapDistance = 0;
  15. /**
  16. * Event that fires each time the gizmo snaps to a new location.
  17. * * snapDistance is the the change in distance
  18. */
  19. public onSnapObservable = new Observable<{snapDistance:number}>();
  20. /**
  21. * Creates an AxisScaleGizmo
  22. * @param gizmoLayer The utility layer the gizmo will be added to
  23. * @param dragAxis The axis which the gizmo will be able to scale on
  24. * @param color The color of the gizmo
  25. */
  26. constructor(dragAxis:Vector3, color:Color3 = Color3.Gray(), gizmoLayer:UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer){
  27. super(gizmoLayer);
  28. // Create Material
  29. var coloredMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
  30. coloredMaterial.disableLighting = true;
  31. coloredMaterial.emissiveColor = color;
  32. var hoverMaterial = new BABYLON.StandardMaterial("", gizmoLayer.utilityLayerScene);
  33. hoverMaterial.disableLighting = true;
  34. hoverMaterial.emissiveColor = color.add(new Color3(0.2,0.2,0.2));
  35. // Build mesh on root node
  36. var arrow = new BABYLON.AbstractMesh("", gizmoLayer.utilityLayerScene)
  37. var arrowMesh = BABYLON.MeshBuilder.CreateBox("yPosMesh", {size: 0.5}, gizmoLayer.utilityLayerScene);
  38. var arrowTail = BABYLON.MeshBuilder.CreateCylinder("yPosMesh", {diameter:0.015, height: 0.3, tessellation: 96}, gizmoLayer.utilityLayerScene);
  39. arrow.addChild(arrowMesh);
  40. arrow.addChild(arrowTail);
  41. // Position arrow pointing in its drag axis
  42. arrowMesh.scaling.scaleInPlace(0.1);
  43. arrowMesh.material = coloredMaterial;
  44. arrowMesh.rotation.x = Math.PI/2;
  45. arrowMesh.position.z+=0.3;
  46. arrowTail.rotation.x = Math.PI/2;
  47. arrowTail.material = coloredMaterial;
  48. arrowTail.position.z+=0.15;
  49. arrow.lookAt(this._rootMesh.position.subtract(dragAxis));
  50. this._rootMesh.addChild(arrow);
  51. // Add drag behavior to handle events when the gizmo is dragged
  52. this.dragBehavior = new PointerDragBehavior({dragAxis: dragAxis});
  53. this.dragBehavior.moveAttached = false;
  54. this._rootMesh.addBehavior(this.dragBehavior);
  55. var currentSnapDragDistance = 0;
  56. var tmpVector = new Vector3();
  57. var tmpSnapEvent = {snapDistance: 0};
  58. this.dragBehavior.onDragObservable.add((event)=>{
  59. if(this.attachedMesh){
  60. // Snapping logic
  61. var snapped = false;
  62. var dragSteps = 0;
  63. if(this.snapDistance == 0){
  64. dragAxis.scaleToRef(event.dragDistance, tmpVector);
  65. }else{
  66. currentSnapDragDistance+=event.dragDistance;
  67. if(Math.abs(currentSnapDragDistance)>this.snapDistance){
  68. dragSteps = Math.floor(currentSnapDragDistance/this.snapDistance);
  69. currentSnapDragDistance = currentSnapDragDistance % this.snapDistance;
  70. dragAxis.scaleToRef(this.snapDistance*dragSteps, tmpVector);
  71. snapped = true;
  72. }else{
  73. tmpVector.scaleInPlace(0);
  74. }
  75. }
  76. this.attachedMesh.scaling.addInPlace(tmpVector);
  77. if(snapped){
  78. tmpSnapEvent.snapDistance = this.snapDistance*dragSteps;
  79. this.onSnapObservable.notifyObservers(tmpSnapEvent);
  80. }
  81. }
  82. })
  83. this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add((pointerInfo, eventState)=>{
  84. if(this._customMeshSet){
  85. return;
  86. }
  87. if(pointerInfo.pickInfo && (this._rootMesh.getChildMeshes().indexOf(<Mesh>pointerInfo.pickInfo.pickedMesh) != -1)){
  88. this._rootMesh.getChildMeshes().forEach((m)=>{
  89. m.material = hoverMaterial;
  90. });
  91. }else{
  92. this._rootMesh.getChildMeshes().forEach((m)=>{
  93. m.material = coloredMaterial;
  94. });
  95. }
  96. });
  97. }
  98. protected _attachedMeshChanged(value:Nullable<AbstractMesh>){
  99. if(this.dragBehavior){
  100. this.dragBehavior.enabled = value ? true : false;
  101. }
  102. }
  103. /**
  104. * Disposes of the gizmo
  105. */
  106. public dispose(){
  107. this.onSnapObservable.clear();
  108. this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
  109. this.dragBehavior.detach();
  110. super.dispose();
  111. }
  112. }
  113. }