UNPKG

4.67 kBJavaScriptView Raw
1import { Geometry } from '../core/Geometry.js';
2import { BufferGeometry } from '../core/BufferGeometry.js';
3import { Float32BufferAttribute } from '../core/BufferAttribute.js';
4import { Vector3 } from '../math/Vector3.js';
5
6// BoxGeometry
7
8class BoxGeometry extends Geometry {
9
10 constructor( width, height, depth, widthSegments, heightSegments, depthSegments ) {
11
12 super();
13
14 this.type = 'BoxGeometry';
15
16 this.parameters = {
17 width: width,
18 height: height,
19 depth: depth,
20 widthSegments: widthSegments,
21 heightSegments: heightSegments,
22 depthSegments: depthSegments
23 };
24
25 this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );
26 this.mergeVertices();
27
28 }
29
30}
31
32// BoxBufferGeometry
33
34class BoxBufferGeometry extends BufferGeometry {
35
36 constructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) {
37
38 super();
39
40 this.type = 'BoxBufferGeometry';
41
42 this.parameters = {
43 width: width,
44 height: height,
45 depth: depth,
46 widthSegments: widthSegments,
47 heightSegments: heightSegments,
48 depthSegments: depthSegments
49 };
50
51 const scope = this;
52
53 // segments
54
55 widthSegments = Math.floor( widthSegments );
56 heightSegments = Math.floor( heightSegments );
57 depthSegments = Math.floor( depthSegments );
58
59 // buffers
60
61 const indices = [];
62 const vertices = [];
63 const normals = [];
64 const uvs = [];
65
66 // helper variables
67
68 let numberOfVertices = 0;
69 let groupStart = 0;
70
71 // build each side of the box geometry
72
73 buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px
74 buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx
75 buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py
76 buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny
77 buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz
78 buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz
79
80 // build geometry
81
82 this.setIndex( indices );
83 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
84 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
85 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
86
87 function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {
88
89 const segmentWidth = width / gridX;
90 const segmentHeight = height / gridY;
91
92 const widthHalf = width / 2;
93 const heightHalf = height / 2;
94 const depthHalf = depth / 2;
95
96 const gridX1 = gridX + 1;
97 const gridY1 = gridY + 1;
98
99 let vertexCounter = 0;
100 let groupCount = 0;
101
102 const vector = new Vector3();
103
104 // generate vertices, normals and uvs
105
106 for ( let iy = 0; iy < gridY1; iy ++ ) {
107
108 const y = iy * segmentHeight - heightHalf;
109
110 for ( let ix = 0; ix < gridX1; ix ++ ) {
111
112 const x = ix * segmentWidth - widthHalf;
113
114 // set values to correct vector component
115
116 vector[ u ] = x * udir;
117 vector[ v ] = y * vdir;
118 vector[ w ] = depthHalf;
119
120 // now apply vector to vertex buffer
121
122 vertices.push( vector.x, vector.y, vector.z );
123
124 // set values to correct vector component
125
126 vector[ u ] = 0;
127 vector[ v ] = 0;
128 vector[ w ] = depth > 0 ? 1 : - 1;
129
130 // now apply vector to normal buffer
131
132 normals.push( vector.x, vector.y, vector.z );
133
134 // uvs
135
136 uvs.push( ix / gridX );
137 uvs.push( 1 - ( iy / gridY ) );
138
139 // counters
140
141 vertexCounter += 1;
142
143 }
144
145 }
146
147 // indices
148
149 // 1. you need three indices to draw a single face
150 // 2. a single segment consists of two faces
151 // 3. so we need to generate six (2*3) indices per segment
152
153 for ( let iy = 0; iy < gridY; iy ++ ) {
154
155 for ( let ix = 0; ix < gridX; ix ++ ) {
156
157 const a = numberOfVertices + ix + gridX1 * iy;
158 const b = numberOfVertices + ix + gridX1 * ( iy + 1 );
159 const c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );
160 const d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;
161
162 // faces
163
164 indices.push( a, b, d );
165 indices.push( b, c, d );
166
167 // increase counter
168
169 groupCount += 6;
170
171 }
172
173 }
174
175 // add a group to the geometry. this will ensure multi material support
176
177 scope.addGroup( groupStart, groupCount, materialIndex );
178
179 // calculate new start value for groups
180
181 groupStart += groupCount;
182
183 // update total number of vertices
184
185 numberOfVertices += vertexCounter;
186
187 }
188
189 }
190
191}
192
193export { BoxGeometry, BoxBufferGeometry };