babylon.groundMesh.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. var __extends = (this && this.__extends) || function (d, b) {
  2. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  3. function __() { this.constructor = d; }
  4. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  5. };
  6. var BABYLON;
  7. (function (BABYLON) {
  8. var GroundMesh = (function (_super) {
  9. __extends(GroundMesh, _super);
  10. function GroundMesh(name, scene) {
  11. _super.call(this, name, scene);
  12. this.generateOctree = false;
  13. this._worldInverse = new BABYLON.Matrix();
  14. }
  15. Object.defineProperty(GroundMesh.prototype, "subdivisions", {
  16. get: function () {
  17. return this._subdivisions;
  18. },
  19. enumerable: true,
  20. configurable: true
  21. });
  22. GroundMesh.prototype.optimize = function (chunksCount, octreeBlocksSize) {
  23. if (octreeBlocksSize === void 0) { octreeBlocksSize = 32; }
  24. this._subdivisions = chunksCount;
  25. this.subdivide(this._subdivisions);
  26. this.createOrUpdateSubmeshesOctree(octreeBlocksSize);
  27. };
  28. /**
  29. * Returns a height (y) value in the Worl system :
  30. * the ground altitude at the coordinates (x, z) expressed in the World system.
  31. * Returns the ground y position if (x, z) are outside the ground surface.
  32. * Not pertinent if the ground is rotated.
  33. */
  34. GroundMesh.prototype.getHeightAtCoordinates = function (x, z) {
  35. // express x and y in the ground local system
  36. x -= this.position.x;
  37. z -= this.position.z;
  38. x /= this.scaling.x;
  39. z /= this.scaling.z;
  40. if (x < this._minX || x > this._maxX || z < this._minZ || z > this._maxZ) {
  41. return this.position.y;
  42. }
  43. if (!this._heightQuads || this._heightQuads.length == 0) {
  44. this._computeHeightQuads();
  45. }
  46. var facet = this._getFacetAt(x, z);
  47. var y = -(facet.x * x + facet.z * z + facet.w) / facet.y;
  48. // return y in the World system
  49. return y * this.scaling.y + this.position.y;
  50. };
  51. /**
  52. * Returns a normalized vector (Vector3) orthogonal to the ground
  53. * at the ground coordinates (x, z) expressed in the World system.
  54. * Returns Vector3(0, 1, 0) if (x, z) are outside the ground surface.
  55. * Not pertinent if the ground is rotated.
  56. */
  57. GroundMesh.prototype.getNormalAtCoordinates = function (x, z) {
  58. var normal = new BABYLON.Vector3(0, 1, 0);
  59. this.getNormalAtCoordinatesToRef(x, z, normal);
  60. return normal;
  61. };
  62. /**
  63. * Updates the Vector3 passed a reference with a normalized vector orthogonal to the ground
  64. * at the ground coordinates (x, z) expressed in the World system.
  65. * Doesn't uptade the reference Vector3 if (x, z) are outside the ground surface.
  66. * Not pertinent if the ground is rotated.
  67. */
  68. GroundMesh.prototype.getNormalAtCoordinatesToRef = function (x, z, ref) {
  69. // express x and y in the ground local system
  70. x -= this.position.x;
  71. z -= this.position.z;
  72. x /= this.scaling.x;
  73. z /= this.scaling.z;
  74. if (x < this._minX || x > this._maxX || z < this._minZ || z > this._maxZ) {
  75. return;
  76. }
  77. if (!this._heightQuads || this._heightQuads.length == 0) {
  78. this._computeHeightQuads();
  79. }
  80. var facet = this._getFacetAt(x, z);
  81. ref.x = facet.x;
  82. ref.y = facet.y;
  83. ref.z = facet.z;
  84. };
  85. // Returns the element "facet" from the heightQuads array relative to (x, z) local coordinates
  86. GroundMesh.prototype._getFacetAt = function (x, z) {
  87. // retrieve col and row from x, z coordinates in the ground local system
  88. var col = Math.floor((x + this._maxX) * this._subdivisions / this._width);
  89. var row = Math.floor(-(z + this._maxZ) * this._subdivisions / this._height + this._subdivisions);
  90. var quad = this._heightQuads[row * this._subdivisions + col];
  91. var facet;
  92. if (z < quad.slope.x * x + quad.slope.y) {
  93. facet = quad.facet1;
  94. }
  95. else {
  96. facet = quad.facet2;
  97. }
  98. return facet;
  99. };
  100. // Populates the heightMap array with "facet" elements :
  101. // a quad is two triangular facets separated by a slope, so a "facet" element is 1 slope + 2 facets
  102. // slope : Vector2(c, h) = 2D diagonal line equation setting appart two triangular facets in a quad : z = cx + h
  103. // facet1 : Vector4(a, b, c, d) = first facet 3D plane equation : ax + by + cz + d = 0
  104. // facet2 : Vector4(a, b, c, d) = second facet 3D plane equation : ax + by + cz + d = 0
  105. GroundMesh.prototype._computeHeightQuads = function () {
  106. this._heightQuads = new Array();
  107. var positions = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  108. var v1 = BABYLON.Vector3.Zero();
  109. var v2 = BABYLON.Vector3.Zero();
  110. var v3 = BABYLON.Vector3.Zero();
  111. var v4 = BABYLON.Vector3.Zero();
  112. var v1v2 = BABYLON.Vector3.Zero();
  113. var v1v3 = BABYLON.Vector3.Zero();
  114. var v1v4 = BABYLON.Vector3.Zero();
  115. var norm1 = BABYLON.Vector3.Zero();
  116. var norm2 = BABYLON.Vector3.Zero();
  117. var i = 0;
  118. var j = 0;
  119. var k = 0;
  120. var cd = 0; // 2D slope coefficient : z = cd * x + h
  121. var h = 0;
  122. var d1 = 0; // facet plane equation : ax + by + cz + d = 0
  123. var d2 = 0;
  124. for (var row = 0; row < this._subdivisions; row++) {
  125. for (var col = 0; col < this._subdivisions; col++) {
  126. i = col * 3;
  127. j = row * (this._subdivisions + 1) * 3;
  128. k = (row + 1) * (this._subdivisions + 1) * 3;
  129. v1.x = positions[j + i];
  130. v1.y = positions[j + i + 1];
  131. v1.z = positions[j + i + 2];
  132. v2.x = positions[j + i + 3];
  133. v2.y = positions[j + i + 4];
  134. v2.z = positions[j + i + 5];
  135. v3.x = positions[k + i];
  136. v3.y = positions[k + i + 1];
  137. v3.z = positions[k + i + 2];
  138. v4.x = positions[k + i + 3];
  139. v4.y = positions[k + i + 4];
  140. v4.z = positions[k + i + 5];
  141. // 2D slope V1V4
  142. cd = (v4.z - v1.z) / (v4.x - v1.x);
  143. h = v1.z - cd * v1.x; // v1 belongs to the slope
  144. var slope = new BABYLON.Vector2(cd, h);
  145. // facet equations :
  146. // we compute each facet normal vector
  147. // the equation of the facet plane is : norm.x * x + norm.y * y + norm.z * z + d = 0
  148. // we compute the value d by applying the equation to v1 which belongs to the plane
  149. // then we store the facet equation in a Vector4
  150. v2.subtractToRef(v1, v1v2);
  151. v3.subtractToRef(v1, v1v3);
  152. v4.subtractToRef(v1, v1v4);
  153. BABYLON.Vector3.CrossToRef(v1v4, v1v3, norm1);
  154. BABYLON.Vector3.CrossToRef(v1v2, v1v4, norm2);
  155. norm1.normalize();
  156. norm2.normalize();
  157. d1 = -(norm1.x * v1.x + norm1.y * v1.y + norm1.z * v1.z);
  158. d2 = -(norm2.x * v2.x + norm2.y * v2.y + norm2.z * v2.z);
  159. var facet1 = new BABYLON.Vector4(norm1.x, norm1.y, norm1.z, d1);
  160. var facet2 = new BABYLON.Vector4(norm2.x, norm2.y, norm2.z, d2);
  161. var quad = { slope: slope, facet1: facet1, facet2: facet2 };
  162. this._heightQuads.push(quad);
  163. }
  164. }
  165. };
  166. return GroundMesh;
  167. })(BABYLON.Mesh);
  168. BABYLON.GroundMesh = GroundMesh;
  169. })(BABYLON || (BABYLON = {}));
  170. //# sourceMappingURL=babylon.groundMesh.js.map