BoxBufferGeometry.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /**
  2. * @author Mugen87 / https://github.com/Mugen87
  3. */
  4. THREE.BoxBufferGeometry = function ( width, height, depth, widthSegments, heightSegments, depthSegments ) {
  5. THREE.BufferGeometry.call( this );
  6. this.type = 'BoxBufferGeometry';
  7. this.parameters = {
  8. width: width,
  9. height: height,
  10. depth: depth,
  11. widthSegments: widthSegments,
  12. heightSegments: heightSegments,
  13. depthSegments: depthSegments
  14. };
  15. var scope = this;
  16. // segments
  17. widthSegments = Math.floor( widthSegments ) || 1;
  18. heightSegments = Math.floor( heightSegments ) || 1;
  19. depthSegments = Math.floor( depthSegments ) || 1;
  20. // these are used to calculate buffer length
  21. var vertexCount = calculateVertexCount( widthSegments, heightSegments, depthSegments );
  22. var indexCount = calculateIndexCount( widthSegments, heightSegments, depthSegments );
  23. // buffers
  24. var indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount );
  25. var vertices = new Float32Array( vertexCount * 3 );
  26. var normals = new Float32Array( vertexCount * 3 );
  27. var uvs = new Float32Array( vertexCount * 2 );
  28. // offset variables
  29. var vertexBufferOffset = 0;
  30. var uvBufferOffset = 0;
  31. var indexBufferOffset = 0;
  32. var numberOfVertices = 0;
  33. // group variables
  34. var groupStart = 0;
  35. // build each side of the box geometry
  36. buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px
  37. buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx
  38. buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py
  39. buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny
  40. buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz
  41. buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz
  42. // build geometry
  43. this.setIndex( new THREE.BufferAttribute( indices, 1 ) );
  44. this.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
  45. this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
  46. this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) );
  47. // helper functions
  48. function calculateVertexCount ( w, h, d ) {
  49. var vertices = 0;
  50. // calculate the amount of vertices for each side (plane)
  51. vertices += (w + 1) * (h + 1) * 2; // xy
  52. vertices += (w + 1) * (d + 1) * 2; // xz
  53. vertices += (d + 1) * (h + 1) * 2; // zy
  54. return vertices;
  55. }
  56. function calculateIndexCount ( w, h, d ) {
  57. var index = 0;
  58. // calculate the amount of squares for each side
  59. index += w * h * 2; // xy
  60. index += w * d * 2; // xz
  61. index += d * h * 2; // zy
  62. return index * 6; // two triangles per square => six vertices per square
  63. }
  64. function buildPlane ( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {
  65. var segmentWidth = width / gridX;
  66. var segmentHeight = height / gridY;
  67. var widthHalf = width / 2;
  68. var heightHalf = height / 2;
  69. var depthHalf = depth / 2;
  70. var gridX1 = gridX + 1;
  71. var gridY1 = gridY + 1;
  72. var vertexCounter = 0;
  73. var groupCount = 0;
  74. var vector = new THREE.Vector3();
  75. // generate vertices, normals and uvs
  76. for ( var iy = 0; iy < gridY1; iy ++ ) {
  77. var y = iy * segmentHeight - heightHalf;
  78. for ( var ix = 0; ix < gridX1; ix ++ ) {
  79. var x = ix * segmentWidth - widthHalf;
  80. // set values to correct vector component
  81. vector[ u ] = x * udir;
  82. vector[ v ] = y * vdir;
  83. vector[ w ] = depthHalf;
  84. // now apply vector to vertex buffer
  85. vertices[ vertexBufferOffset ] = vector.x;
  86. vertices[ vertexBufferOffset + 1 ] = vector.y;
  87. vertices[ vertexBufferOffset + 2 ] = vector.z;
  88. // set values to correct vector component
  89. vector[ u ] = 0;
  90. vector[ v ] = 0;
  91. vector[ w ] = depth > 0 ? 1 : - 1;
  92. // now apply vector to normal buffer
  93. normals[ vertexBufferOffset ] = vector.x;
  94. normals[ vertexBufferOffset + 1 ] = vector.y;
  95. normals[ vertexBufferOffset + 2 ] = vector.z;
  96. // uvs
  97. uvs[ uvBufferOffset ] = ix / gridX;
  98. uvs[ uvBufferOffset + 1 ] = 1 - ( iy / gridY );
  99. // update offsets and counters
  100. vertexBufferOffset += 3;
  101. uvBufferOffset += 2;
  102. vertexCounter += 1;
  103. }
  104. }
  105. // 1. you need three indices to draw a single face
  106. // 2. a single segment consists of two faces
  107. // 3. so we need to generate six (2*3) indices per segment
  108. for ( iy = 0; iy < gridY; iy ++ ) {
  109. for ( ix = 0; ix < gridX; ix ++ ) {
  110. // indices
  111. var a = numberOfVertices + ix + gridX1 * iy;
  112. var b = numberOfVertices + ix + gridX1 * ( iy + 1 );
  113. var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );
  114. var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;
  115. // face one
  116. indices[ indexBufferOffset ] = a;
  117. indices[ indexBufferOffset + 1 ] = b;
  118. indices[ indexBufferOffset + 2 ] = d;
  119. // face two
  120. indices[ indexBufferOffset + 3 ] = b;
  121. indices[ indexBufferOffset + 4 ] = c;
  122. indices[ indexBufferOffset + 5 ] = d;
  123. // update offsets and counters
  124. indexBufferOffset += 6;
  125. groupCount += 6;
  126. }
  127. }
  128. // add a group to the geometry. this will ensure multi material support
  129. scope.addGroup( groupStart, groupCount, materialIndex );
  130. // calculate new start value for groups
  131. groupStart += groupCount;
  132. // update total number of vertices
  133. numberOfVertices += vertexCounter;
  134. }
  135. };
  136. THREE.BoxBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
  137. THREE.BoxBufferGeometry.prototype.constructor = THREE.BoxBufferGeometry;
粤ICP备19079148号