scaleGizmo.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import { Logger } from "../Misc/logger";
  2. import { Observable } from "../Misc/observable";
  3. import { Nullable } from "../types";
  4. import { Vector3, Color3 } from "../Maths/math";
  5. import { AbstractMesh } from "../Meshes/abstractMesh";
  6. import { PolyhedronBuilder } from "../Meshes/Builders/polyhedronBuilder";
  7. import { Gizmo } from "./gizmo";
  8. import { AxisScaleGizmo } from "./axisScaleGizmo";
  9. import { UtilityLayerRenderer } from "../Rendering/utilityLayerRenderer";
  10. import { Mesh } from 'Meshes';
  11. /**
  12. * Gizmo that enables scaling a mesh along 3 axis
  13. */
  14. export class ScaleGizmo extends Gizmo {
  15. /**
  16. * Internal gizmo used for interactions on the x axis
  17. */
  18. public xGizmo: AxisScaleGizmo;
  19. /**
  20. * Internal gizmo used for interactions on the y axis
  21. */
  22. public yGizmo: AxisScaleGizmo;
  23. /**
  24. * Internal gizmo used for interactions on the z axis
  25. */
  26. public zGizmo: AxisScaleGizmo;
  27. /**
  28. * Internal gizmo used to scale all axis equally
  29. */
  30. public uniformScaleGizmo: AxisScaleGizmo;
  31. private _meshAttached: Nullable<AbstractMesh> = null;
  32. private _updateGizmoRotationToMatchAttachedMesh: boolean;
  33. private _snapDistance: number;
  34. private _scaleRatio: number;
  35. private _uniformScalingMesh: Mesh;
  36. private _octahedron: Mesh;
  37. /** Fires an event when any of it's sub gizmos are dragged */
  38. public onDragStartObservable = new Observable();
  39. /** Fires an event when any of it's sub gizmos are released from dragging */
  40. public onDragEndObservable = new Observable();
  41. public get attachedMesh() {
  42. return this._meshAttached;
  43. }
  44. public set attachedMesh(mesh: Nullable<AbstractMesh>) {
  45. this._meshAttached = mesh;
  46. [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo].forEach((gizmo) => {
  47. if (gizmo.isEnabled) {
  48. gizmo.attachedMesh = mesh;
  49. }
  50. else {
  51. gizmo.attachedMesh = null;
  52. }
  53. });
  54. }
  55. /**
  56. * Creates a ScaleGizmo
  57. * @param gizmoLayer The utility layer the gizmo will be added to
  58. */
  59. constructor(gizmoLayer: UtilityLayerRenderer = UtilityLayerRenderer.DefaultUtilityLayer) {
  60. super(gizmoLayer);
  61. this.xGizmo = new AxisScaleGizmo(new Vector3(1, 0, 0), Color3.Red().scale(0.5), gizmoLayer, this);
  62. this.yGizmo = new AxisScaleGizmo(new Vector3(0, 1, 0), Color3.Green().scale(0.5), gizmoLayer, this);
  63. this.zGizmo = new AxisScaleGizmo(new Vector3(0, 0, 1), Color3.Blue().scale(0.5), gizmoLayer, this);
  64. // Create uniform scale gizmo
  65. this.uniformScaleGizmo = new AxisScaleGizmo(new Vector3(0, 1, 0), Color3.Yellow().scale(0.5), gizmoLayer, this);
  66. this.uniformScaleGizmo.updateGizmoRotationToMatchAttachedMesh = false;
  67. this.uniformScaleGizmo.uniformScaling = true;
  68. this._uniformScalingMesh = PolyhedronBuilder.CreatePolyhedron("", { type: 1 }, this.uniformScaleGizmo.gizmoLayer.utilityLayerScene);
  69. this._uniformScalingMesh.scaling.scaleInPlace(0.02);
  70. this._uniformScalingMesh.visibility = 0;
  71. this._octahedron = PolyhedronBuilder.CreatePolyhedron("", { type: 1 }, this.uniformScaleGizmo.gizmoLayer.utilityLayerScene);
  72. this._octahedron.scaling.scaleInPlace(0.007);
  73. this._uniformScalingMesh.addChild(this._octahedron);
  74. this.uniformScaleGizmo.setCustomMesh(this._uniformScalingMesh, true);
  75. var light = gizmoLayer._getSharedGizmoLight();
  76. light.includedOnlyMeshes = light.includedOnlyMeshes.concat(this._octahedron);
  77. // Relay drag events
  78. [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo].forEach((gizmo) => {
  79. gizmo.dragBehavior.onDragStartObservable.add(() => {
  80. this.onDragStartObservable.notifyObservers({});
  81. });
  82. gizmo.dragBehavior.onDragEndObservable.add(() => {
  83. this.onDragEndObservable.notifyObservers({});
  84. });
  85. });
  86. this.attachedMesh = null;
  87. }
  88. public set updateGizmoRotationToMatchAttachedMesh(value: boolean) {
  89. if (!value) {
  90. Logger.Warn("Setting updateGizmoRotationToMatchAttachedMesh = false on scaling gizmo is not supported.");
  91. }
  92. else {
  93. this._updateGizmoRotationToMatchAttachedMesh = value;
  94. [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo].forEach((gizmo) => {
  95. if (gizmo) {
  96. gizmo.updateGizmoRotationToMatchAttachedMesh = value;
  97. }
  98. });
  99. }
  100. }
  101. public get updateGizmoRotationToMatchAttachedMesh() {
  102. return this._updateGizmoRotationToMatchAttachedMesh;
  103. }
  104. /**
  105. * Drag distance in babylon units that the gizmo will snap to when dragged (Default: 0)
  106. */
  107. public set snapDistance(value: number) {
  108. this._snapDistance = value;
  109. [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo].forEach((gizmo) => {
  110. if (gizmo) {
  111. gizmo.snapDistance = value;
  112. }
  113. });
  114. }
  115. public get snapDistance() {
  116. return this._snapDistance;
  117. }
  118. /**
  119. * Ratio for the scale of the gizmo (Default: 1)
  120. */
  121. public set scaleRatio(value: number) {
  122. this._scaleRatio = value;
  123. [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo].forEach((gizmo) => {
  124. if (gizmo) {
  125. gizmo.scaleRatio = value;
  126. }
  127. });
  128. }
  129. public get scaleRatio() {
  130. return this._scaleRatio;
  131. }
  132. /**
  133. * Disposes of the gizmo
  134. */
  135. public dispose() {
  136. [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo].forEach((gizmo) => {
  137. if (gizmo) {
  138. gizmo.dispose();
  139. }
  140. });
  141. this.onDragStartObservable.clear();
  142. this.onDragEndObservable.clear();
  143. [this._uniformScalingMesh, this._octahedron].forEach((msh) => {
  144. if (msh) {
  145. msh.dispose();
  146. }
  147. });
  148. }
  149. }