rayHelper.ts 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. module BABYLON {
  2. /**
  3. * As raycast might be hard to debug, the RayHelper can help rendering the different rays
  4. * in order to better appreciate the issue one might have.
  5. * @see http://doc.babylonjs.com/babylon101/raycasts#debugging
  6. */
  7. export class RayHelper {
  8. /**
  9. * Defines the ray we are currently tryin to visualize.
  10. */
  11. public ray: Nullable<Ray>;
  12. private _renderPoints: Vector3[];
  13. private _renderLine: Nullable<LinesMesh>;
  14. private _renderFunction: Nullable<() => void>;
  15. private _scene: Nullable<Scene>;
  16. private _updateToMeshFunction: Nullable<() => void>;
  17. private _attachedToMesh: Nullable<AbstractMesh>;
  18. private _meshSpaceDirection: Vector3;
  19. private _meshSpaceOrigin: Vector3;
  20. /**
  21. * Helper function to create a colored helper in a scene in one line.
  22. * @param ray Defines the ray we are currently tryin to visualize
  23. * @param scene Defines the scene the ray is used in
  24. * @param color Defines the color we want to see the ray in
  25. * @returns The newly created ray helper.
  26. */
  27. public static CreateAndShow(ray: Ray, scene: Scene, color: Color3): RayHelper {
  28. var helper = new RayHelper(ray);
  29. helper.show(scene, color);
  30. return helper;
  31. }
  32. /**
  33. * Instantiate a new ray helper.
  34. * As raycast might be hard to debug, the RayHelper can help rendering the different rays
  35. * in order to better appreciate the issue one might have.
  36. * @see http://doc.babylonjs.com/babylon101/raycasts#debugging
  37. * @param ray Defines the ray we are currently tryin to visualize
  38. */
  39. constructor(ray: Ray) {
  40. this.ray = ray;
  41. }
  42. /**
  43. * Shows the ray we are willing to debug.
  44. * @param scene Defines the scene the ray needs to be rendered in
  45. * @param color Defines the color the ray needs to be rendered in
  46. */
  47. public show(scene: Scene, color?: Color3): void {
  48. if (!this._renderFunction && this.ray) {
  49. var ray = this.ray;
  50. this._renderFunction = this._render.bind(this);
  51. this._scene = scene;
  52. this._renderPoints = [ray.origin, ray.origin.add(ray.direction.scale(ray.length))];
  53. this._renderLine = Mesh.CreateLines("ray", this._renderPoints, scene, true);
  54. if (this._renderFunction) {
  55. this._scene.registerBeforeRender(this._renderFunction);
  56. }
  57. }
  58. if (color && this._renderLine) {
  59. this._renderLine.color.copyFrom(color);
  60. }
  61. }
  62. /**
  63. * Hides the ray we are debugging.
  64. */
  65. public hide(): void {
  66. if (this._renderFunction && this._scene) {
  67. this._scene.unregisterBeforeRender(this._renderFunction);
  68. this._scene = null;
  69. this._renderFunction = null;
  70. if (this._renderLine) {
  71. this._renderLine.dispose();
  72. this._renderLine = null;
  73. }
  74. this._renderPoints = [];
  75. }
  76. }
  77. private _render(): void {
  78. var ray = this.ray;
  79. if (!ray) {
  80. return;
  81. }
  82. var point = this._renderPoints[1];
  83. var len = Math.min(ray.length, 1000000);
  84. point.copyFrom(ray.direction);
  85. point.scaleInPlace(len);
  86. point.addInPlace(ray.origin);
  87. Mesh.CreateLines("ray", this._renderPoints, this._scene, true, this._renderLine);
  88. }
  89. /**
  90. * Attach a ray helper to a mesh so that we can easily see its orientation for instance or information like its normals.
  91. * @param mesh Defines the mesh we want the helper attached to
  92. * @param meshSpaceDirection Defines the direction of the Ray in mesh space (local space of the mesh node)
  93. * @param meshSpaceOrigin Defines the origin of the Ray in mesh space (local space of the mesh node)
  94. * @param length Defines the length of the ray
  95. */
  96. public attachToMesh(mesh: AbstractMesh, meshSpaceDirection?: Vector3, meshSpaceOrigin?: Vector3, length?: number): void {
  97. this._attachedToMesh = mesh;
  98. var ray = this.ray;
  99. if (!ray) {
  100. return;
  101. }
  102. if (!ray.direction) {
  103. ray.direction = Vector3.Zero();
  104. }
  105. if (!ray.origin) {
  106. ray.origin = Vector3.Zero();
  107. }
  108. if (length) {
  109. ray.length = length;
  110. }
  111. if (!meshSpaceOrigin) {
  112. meshSpaceOrigin = Vector3.Zero();
  113. }
  114. if (!meshSpaceDirection) {
  115. // -1 so that this will work with Mesh.lookAt
  116. meshSpaceDirection = new Vector3(0, 0, -1);
  117. }
  118. if (!this._meshSpaceDirection) {
  119. this._meshSpaceDirection = meshSpaceDirection.clone();
  120. this._meshSpaceOrigin = meshSpaceOrigin.clone();
  121. } else {
  122. this._meshSpaceDirection.copyFrom(meshSpaceDirection);
  123. this._meshSpaceOrigin.copyFrom(meshSpaceOrigin);
  124. }
  125. if (!this._updateToMeshFunction) {
  126. this._updateToMeshFunction = (<() => void>this._updateToMesh.bind(this));
  127. this._attachedToMesh.getScene().registerBeforeRender(this._updateToMeshFunction);
  128. }
  129. this._updateToMesh();
  130. }
  131. /**
  132. * Detach the ray helper from the mesh it has previously been attached to.
  133. */
  134. public detachFromMesh(): void {
  135. if (this._attachedToMesh) {
  136. if (this._updateToMeshFunction) {
  137. this._attachedToMesh.getScene().unregisterBeforeRender(this._updateToMeshFunction);
  138. }
  139. this._attachedToMesh = null;
  140. this._updateToMeshFunction = null;
  141. }
  142. }
  143. private _updateToMesh(): void {
  144. var ray = this.ray;
  145. if (!this._attachedToMesh || !ray) {
  146. return;
  147. }
  148. if (this._attachedToMesh._isDisposed) {
  149. this.detachFromMesh();
  150. return;
  151. }
  152. this._attachedToMesh.getDirectionToRef(this._meshSpaceDirection, ray.direction);
  153. Vector3.TransformCoordinatesToRef(this._meshSpaceOrigin, this._attachedToMesh.getWorldMatrix(), ray.origin);
  154. }
  155. /**
  156. * Dispose the helper and release its associated resources.
  157. */
  158. public dispose(): void {
  159. this.hide();
  160. this.detachFromMesh();
  161. this.ray = null;
  162. }
  163. }
  164. }