| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import {AGeometryGenerator} from '../AGeometryGenerator'
- import {Vector3} from 'threepipe'
-
-
- export interface BoxGeometryGeneratorParams {
- width: number,
- height: number,
- depth: number,
- widthSegments: number,
- heightSegments: number,
- depthSegments: number
- }
-
- export class BoxGeometryGenerator extends AGeometryGenerator<BoxGeometryGeneratorParams> {
-
- defaultParams = {
- width: 1,
- height: 1,
- depth: 1,
- widthSegments: 1,
- heightSegments: 1,
- depthSegments: 1,
- }
-
- // helper variables
-
- protected _buildPlane(state: any, u: 'x'|'y'|'z', v: 'x'|'y'|'z', w: 'x'|'y'|'z', udir: number, vdir: number, width: number, height: number, depth: number, gridX: number, gridY: number, materialIndex: number) {
- const {indices, vertices, normals, uvs, numberOfVertices, groupStart, groups} = state
-
- const segmentWidth = width / gridX
- const segmentHeight = height / gridY
-
- const widthHalf = width / 2
- const heightHalf = height / 2
- const depthHalf = depth / 2
-
- const gridX1 = gridX + 1
- const gridY1 = gridY + 1
-
- let vertexCounter = 0
- let groupCount = 0
-
- const vector = new Vector3()
-
- // generate vertices, normals and uvs
- for (let iy = 0; iy < gridY1; iy++) {
- const y = iy * segmentHeight - heightHalf
- for (let ix = 0; ix < gridX1; ix++) {
- const x = ix * segmentWidth - widthHalf
- // set values to correct vector component
- vector[ u ] = x * udir
- vector[ v ] = y * vdir
- vector[ w ] = depthHalf
- // now apply vector to vertex buffer
- vertices.push(vector.x, vector.y, vector.z)
- // set values to correct vector component
- vector[ u ] = 0
- vector[ v ] = 0
- vector[ w ] = depth > 0 ? 1 : -1
- // now apply vector to normal buffer
- normals.push(vector.x, vector.y, vector.z)
- // uvs
- uvs.push(ix / gridX)
- uvs.push(1 - iy / gridY)
- // counters
- vertexCounter += 1
- }
- }
- // indices
- // 1. you need three indices to draw a single face
- // 2. a single segment consists of two faces
- // 3. so we need to generate six (2*3) indices per segment
- for (let iy = 0; iy < gridY; iy++) {
- for (let ix = 0; ix < gridX; ix++) {
- const a = numberOfVertices + ix + gridX1 * iy
- const b = numberOfVertices + ix + gridX1 * (iy + 1)
- const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1)
- const d = numberOfVertices + (ix + 1) + gridX1 * iy
- // faces
- indices.push(a, b, d)
- indices.push(b, c, d)
- // increase counter
- groupCount += 6
- }
- }
- // add a group to the geometry. this will ensure multi material support
- groups.push({start: groupStart, count: groupCount, materialIndex})
- // calculate new start value for groups
- state.groupStart += groupCount
- // update total number of vertices
- state.numberOfVertices += vertexCounter
- }
-
- protected _generateData(params: BoxGeometryGeneratorParams) {
- const {width, height, depth} = params
- let {widthSegments, heightSegments, depthSegments} = params
-
- // segments
- widthSegments = Math.floor(widthSegments)
- heightSegments = Math.floor(heightSegments)
- depthSegments = Math.floor(depthSegments)
-
- // buffers
-
- const state = {
- indices: [],
- vertices: [],
- normals: [],
- uvs: [],
- numberOfVertices: 0,
- groupStart: 0,
- groups: [],
- }
-
- // build each side of the box geometry
-
- this._buildPlane(state, 'z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0) // px
- this._buildPlane(state, 'z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1) // nx
- this._buildPlane(state, 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2) // py
- this._buildPlane(state, 'x', 'z', 'y', 1, -1, width, depth, -height, widthSegments, depthSegments, 3) // ny
- this._buildPlane(state, 'x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4) // pz
- this._buildPlane(state, 'x', 'y', 'z', -1, -1, width, height, -depth, widthSegments, heightSegments, 5) // nz
-
- return state
- }
-
- }
|