threepipe
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

BoxGeometryGenerator.ts 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import {AGeometryGenerator} from '../AGeometryGenerator'
  2. import {Vector3} from 'threepipe'
  3. export interface BoxGeometryGeneratorParams {
  4. width: number,
  5. height: number,
  6. depth: number,
  7. widthSegments: number,
  8. heightSegments: number,
  9. depthSegments: number
  10. }
  11. export class BoxGeometryGenerator extends AGeometryGenerator<BoxGeometryGeneratorParams> {
  12. defaultParams = {
  13. width: 1,
  14. height: 1,
  15. depth: 1,
  16. widthSegments: 1,
  17. heightSegments: 1,
  18. depthSegments: 1,
  19. }
  20. // helper variables
  21. 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) {
  22. const {indices, vertices, normals, uvs, numberOfVertices, groupStart, groups} = state
  23. const segmentWidth = width / gridX
  24. const segmentHeight = height / gridY
  25. const widthHalf = width / 2
  26. const heightHalf = height / 2
  27. const depthHalf = depth / 2
  28. const gridX1 = gridX + 1
  29. const gridY1 = gridY + 1
  30. let vertexCounter = 0
  31. let groupCount = 0
  32. const vector = new Vector3()
  33. // generate vertices, normals and uvs
  34. for (let iy = 0; iy < gridY1; iy++) {
  35. const y = iy * segmentHeight - heightHalf
  36. for (let ix = 0; ix < gridX1; ix++) {
  37. const x = ix * segmentWidth - widthHalf
  38. // set values to correct vector component
  39. vector[ u ] = x * udir
  40. vector[ v ] = y * vdir
  41. vector[ w ] = depthHalf
  42. // now apply vector to vertex buffer
  43. vertices.push(vector.x, vector.y, vector.z)
  44. // set values to correct vector component
  45. vector[ u ] = 0
  46. vector[ v ] = 0
  47. vector[ w ] = depth > 0 ? 1 : -1
  48. // now apply vector to normal buffer
  49. normals.push(vector.x, vector.y, vector.z)
  50. // uvs
  51. uvs.push(ix / gridX)
  52. uvs.push(1 - iy / gridY)
  53. // counters
  54. vertexCounter += 1
  55. }
  56. }
  57. // indices
  58. // 1. you need three indices to draw a single face
  59. // 2. a single segment consists of two faces
  60. // 3. so we need to generate six (2*3) indices per segment
  61. for (let iy = 0; iy < gridY; iy++) {
  62. for (let ix = 0; ix < gridX; ix++) {
  63. const a = numberOfVertices + ix + gridX1 * iy
  64. const b = numberOfVertices + ix + gridX1 * (iy + 1)
  65. const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1)
  66. const d = numberOfVertices + (ix + 1) + gridX1 * iy
  67. // faces
  68. indices.push(a, b, d)
  69. indices.push(b, c, d)
  70. // increase counter
  71. groupCount += 6
  72. }
  73. }
  74. // add a group to the geometry. this will ensure multi material support
  75. groups.push({start: groupStart, count: groupCount, materialIndex})
  76. // calculate new start value for groups
  77. state.groupStart += groupCount
  78. // update total number of vertices
  79. state.numberOfVertices += vertexCounter
  80. }
  81. protected _generateData(params: BoxGeometryGeneratorParams) {
  82. const {width, height, depth} = params
  83. let {widthSegments, heightSegments, depthSegments} = params
  84. // segments
  85. widthSegments = Math.floor(widthSegments)
  86. heightSegments = Math.floor(heightSegments)
  87. depthSegments = Math.floor(depthSegments)
  88. // buffers
  89. const state = {
  90. indices: [],
  91. vertices: [],
  92. normals: [],
  93. uvs: [],
  94. numberOfVertices: 0,
  95. groupStart: 0,
  96. groups: [],
  97. }
  98. // build each side of the box geometry
  99. this._buildPlane(state, 'z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0) // px
  100. this._buildPlane(state, 'z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1) // nx
  101. this._buildPlane(state, 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2) // py
  102. this._buildPlane(state, 'x', 'z', 'y', 1, -1, width, depth, -height, widthSegments, depthSegments, 3) // ny
  103. this._buildPlane(state, 'x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4) // pz
  104. this._buildPlane(state, 'x', 'y', 'z', -1, -1, width, height, -depth, widthSegments, heightSegments, 5) // nz
  105. return state
  106. }
  107. }