babylon.rayHelper.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. module BABYLON {
  2. export class RayHelper {
  3. public ray: Nullable<Ray>;
  4. private _renderPoints: Vector3[];
  5. private _renderLine: Nullable<LinesMesh>;
  6. private _renderFunction: Nullable<() => void>;
  7. private _scene: Nullable<Scene>;
  8. private _updateToMeshFunction: Nullable<() => void>;
  9. private _attachedToMesh: Nullable<AbstractMesh>;
  10. private _meshSpaceDirection: Vector3;
  11. private _meshSpaceOrigin: Vector3;
  12. public static CreateAndShow(ray: Ray, scene: Scene, color: Color3): RayHelper {
  13. var helper = new RayHelper(ray);
  14. helper.show(scene, color);
  15. return helper;
  16. }
  17. constructor(ray: Ray) {
  18. this.ray = ray;
  19. }
  20. public show(scene: Scene, color: Color3): void {
  21. if (!this._renderFunction && this.ray) {
  22. var ray = this.ray;
  23. this._renderFunction = this._render.bind(this);
  24. this._scene = scene;
  25. this._renderPoints = [ray.origin, ray.origin.add(ray.direction.scale(ray.length))];
  26. this._renderLine = Mesh.CreateLines("ray", this._renderPoints, scene, true);
  27. if (this._renderFunction) {
  28. this._scene.registerBeforeRender(this._renderFunction);
  29. }
  30. }
  31. if (color && this._renderLine) {
  32. this._renderLine.color.copyFrom(color);
  33. }
  34. }
  35. public hide(): void {
  36. if (this._renderFunction && this._scene) {
  37. this._scene.unregisterBeforeRender(this._renderFunction);
  38. this._scene = null;
  39. this._renderFunction = null;
  40. if (this._renderLine) {
  41. this._renderLine.dispose();
  42. this._renderLine = null;
  43. }
  44. this._renderPoints = [];
  45. }
  46. }
  47. private _render(): void {
  48. var ray = this.ray;
  49. if (!ray) {
  50. return;
  51. }
  52. var point = this._renderPoints[1];
  53. var len = Math.min(ray.length, 1000000);
  54. point.copyFrom(ray.direction);
  55. point.scaleInPlace(len);
  56. point.addInPlace(ray.origin);
  57. Mesh.CreateLines("ray", this._renderPoints, this._scene, true, this._renderLine);
  58. }
  59. public attachToMesh(mesh: AbstractMesh, meshSpaceDirection?: Vector3, meshSpaceOrigin?: Vector3, length?: number): void {
  60. this._attachedToMesh = mesh;
  61. var ray = this.ray;
  62. if (!ray) {
  63. return;
  64. }
  65. if (!ray.direction) {
  66. ray.direction = Vector3.Zero();
  67. }
  68. if (!ray.origin) {
  69. ray.origin = Vector3.Zero();
  70. }
  71. if (length) {
  72. ray.length = length;
  73. }
  74. if (!meshSpaceOrigin) {
  75. meshSpaceOrigin = Vector3.Zero();
  76. }
  77. if (!meshSpaceDirection) {
  78. // -1 so that this will work with Mesh.lookAt
  79. meshSpaceDirection = new Vector3(0, 0, -1);
  80. }
  81. if (!this._meshSpaceDirection) {
  82. this._meshSpaceDirection = meshSpaceDirection.clone();
  83. this._meshSpaceOrigin = meshSpaceOrigin.clone();
  84. } else {
  85. this._meshSpaceDirection.copyFrom(meshSpaceDirection);
  86. this._meshSpaceOrigin.copyFrom(meshSpaceOrigin);
  87. }
  88. if (!this._updateToMeshFunction) {
  89. this._updateToMeshFunction = (<() => void>this._updateToMesh.bind(this));
  90. this._attachedToMesh.getScene().registerBeforeRender(this._updateToMeshFunction);
  91. }
  92. this._updateToMesh();
  93. }
  94. public detachFromMesh(): void {
  95. if (this._attachedToMesh) {
  96. if (this._updateToMeshFunction) {
  97. this._attachedToMesh.getScene().unregisterBeforeRender(this._updateToMeshFunction);
  98. }
  99. this._attachedToMesh = null;
  100. this._updateToMeshFunction = null;
  101. }
  102. }
  103. private _updateToMesh(): void {
  104. var ray = this.ray;
  105. if (!this._attachedToMesh || !ray) {
  106. return;
  107. }
  108. if (this._attachedToMesh._isDisposed) {
  109. this.detachFromMesh();
  110. return;
  111. }
  112. this._attachedToMesh.getDirectionToRef(this._meshSpaceDirection, ray.direction);
  113. Vector3.TransformCoordinatesToRef(this._meshSpaceOrigin, this._attachedToMesh.getWorldMatrix(), ray.origin);
  114. }
  115. public dispose(): void {
  116. this.hide();
  117. this.detachFromMesh();
  118. this.ray = null;
  119. }
  120. }
  121. }