BoxGeometry.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as
  4. */
  5. import { Geometry } from '../core/Geometry';
  6. function BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {
  7. Geometry.call( this );
  8. this.type = 'BoxGeometry';
  9. this.parameters = {
  10. width: width,
  11. height: height,
  12. depth: depth,
  13. widthSegments: widthSegments,
  14. heightSegments: heightSegments,
  15. depthSegments: depthSegments
  16. };
  17. this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );
  18. this.mergeVertices();
  19. }
  20. BoxGeometry.prototype = Object.create( Geometry.prototype );
  21. BoxGeometry.prototype.constructor = BoxGeometry;
  22. /**
  23. * @author Mugen87 / https://github.com/Mugen87
  24. */
  25. import { Float32BufferAttribute } from '../core/BufferAttribute';
  26. import { BufferGeometry } from '../core/BufferGeometry';
  27. import { Vector3 } from '../math/Vector3';
  28. function BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {
  29. BufferGeometry.call( this );
  30. this.type = 'BoxBufferGeometry';
  31. this.parameters = {
  32. width: width,
  33. height: height,
  34. depth: depth,
  35. widthSegments: widthSegments,
  36. heightSegments: heightSegments,
  37. depthSegments: depthSegments
  38. };
  39. var scope = this;
  40. // segments
  41. widthSegments = Math.floor( widthSegments ) || 1;
  42. heightSegments = Math.floor( heightSegments ) || 1;
  43. depthSegments = Math.floor( depthSegments ) || 1;
  44. // buffers
  45. var indices = [];
  46. var vertices = [];
  47. var normals = [];
  48. var uvs = [];
  49. // helper variables
  50. var numberOfVertices = 0;
  51. var groupStart = 0;
  52. // build each side of the box geometry
  53. buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px
  54. buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx
  55. buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py
  56. buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny
  57. buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz
  58. buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz
  59. // build geometry
  60. this.setIndex( indices );
  61. this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
  62. this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
  63. this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
  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 ix, iy;
  75. var vector = new Vector3();
  76. // generate vertices, normals and uvs
  77. for ( iy = 0; iy < gridY1; iy ++ ) {
  78. var y = iy * segmentHeight - heightHalf;
  79. for ( ix = 0; ix < gridX1; ix ++ ) {
  80. var x = ix * segmentWidth - widthHalf;
  81. // set values to correct vector component
  82. vector[ u ] = x * udir;
  83. vector[ v ] = y * vdir;
  84. vector[ w ] = depthHalf;
  85. // now apply vector to vertex buffer
  86. vertices.push( vector.x, vector.y, vector.z );
  87. // set values to correct vector component
  88. vector[ u ] = 0;
  89. vector[ v ] = 0;
  90. vector[ w ] = depth > 0 ? 1 : - 1;
  91. // now apply vector to normal buffer
  92. normals.push( vector.x, vector.y, vector.z );
  93. // uvs
  94. uvs.push( ix / gridX );
  95. uvs.push( 1 - ( iy / gridY ) );
  96. // counters
  97. vertexCounter += 1;
  98. }
  99. }
  100. // indices
  101. // 1. you need three indices to draw a single face
  102. // 2. a single segment consists of two faces
  103. // 3. so we need to generate six (2*3) indices per segment
  104. for ( iy = 0; iy < gridY; iy ++ ) {
  105. for ( ix = 0; ix < gridX; ix ++ ) {
  106. var a = numberOfVertices + ix + gridX1 * iy;
  107. var b = numberOfVertices + ix + gridX1 * ( iy + 1 );
  108. var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );
  109. var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;
  110. // faces
  111. indices.push( a, b, d );
  112. indices.push( b, c, d );
  113. // increase counter
  114. groupCount += 6;
  115. }
  116. }
  117. // add a group to the geometry. this will ensure multi material support
  118. scope.addGroup( groupStart, groupCount, materialIndex );
  119. // calculate new start value for groups
  120. groupStart += groupCount;
  121. // update total number of vertices
  122. numberOfVertices += vertexCounter;
  123. }
  124. }
  125. BoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
  126. BoxBufferGeometry.prototype.constructor = BoxBufferGeometry;
  127. export { BoxGeometry, BoxBufferGeometry };