mesh-builder.ts 4.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { ValueCell } from 'mol-util/value-cell'
  7. import { Vec3, Mat4 } from 'mol-math/linear-algebra';
  8. import { ChunkedArray } from 'mol-data/util';
  9. import Box, { BoxProps } from '../primitive/box';
  10. import Cylinder, { CylinderProps } from '../primitive/cylinder';
  11. import Icosahedron, { IcosahedronProps } from '../primitive/icosahedron';
  12. import { Mesh } from './mesh';
  13. export interface MeshBuilder {
  14. add(t: Mat4, _vertices: Float32Array, _normals: Float32Array, _indices?: Uint32Array): number
  15. addBox(t: Mat4, props?: BoxProps): number
  16. addCylinder(t: Mat4, props?: CylinderProps): number
  17. addIcosahedron(t: Mat4, props?: IcosahedronProps): number
  18. setId(id: number): void
  19. getMesh(): Mesh
  20. }
  21. const tmpV = Vec3.zero()
  22. // TODO cache primitives based on props
  23. export namespace MeshBuilder {
  24. export function create(initialCount = 2048, chunkSize = 1024): MeshBuilder {
  25. const vertices = ChunkedArray.create(Float32Array, 3, chunkSize, initialCount);
  26. const normals = ChunkedArray.create(Float32Array, 3, chunkSize, initialCount);
  27. const indices = ChunkedArray.create(Uint32Array, 3, chunkSize * 3, initialCount * 3);
  28. const ids = ChunkedArray.create(Float32Array, 1, chunkSize, initialCount);
  29. const offsets = ChunkedArray.create(Uint32Array, 1, chunkSize, initialCount);
  30. let currentId = -1
  31. const add = (t: Mat4, _vertices: Float32Array, _normals: Float32Array, _indices: Uint32Array) => {
  32. const { elementCount, elementSize } = vertices
  33. for (let i = 0, il = _vertices.length; i < il; i += 3) {
  34. // position
  35. Vec3.fromArray(tmpV, _vertices, i)
  36. Vec3.transformMat4(tmpV, tmpV, t)
  37. ChunkedArray.add3(vertices, tmpV[0], tmpV[1], tmpV[2]);
  38. // normal
  39. Vec3.fromArray(tmpV, _normals, i)
  40. // Vec3.transformDirection(tmpV, tmpV, n) // TODO
  41. ChunkedArray.add3(normals, tmpV[0], tmpV[1], tmpV[2]);
  42. ChunkedArray.add(ids, currentId);
  43. }
  44. for (let i = 0, il = _indices.length; i < il; i += 3) {
  45. ChunkedArray.add3(indices, _indices[i] + elementCount, _indices[i + 1] + elementCount, _indices[i + 2] + elementCount);
  46. }
  47. return elementCount * elementSize
  48. }
  49. return {
  50. add,
  51. addBox: (t: Mat4, props?: BoxProps) => {
  52. const box = Box(props)
  53. return add(t, box.vertices, box.normals, box.indices)
  54. },
  55. addCylinder: (t: Mat4, props?: CylinderProps) => {
  56. const cylinder = Cylinder(props)
  57. return add(t, cylinder.vertices, cylinder.normals, cylinder.indices)
  58. },
  59. addIcosahedron: (t: Mat4, props?: IcosahedronProps) => {
  60. const icosahedron = Icosahedron(props)
  61. return add(t, icosahedron.vertices, icosahedron.normals, icosahedron.indices)
  62. },
  63. setId: (id: number) => {
  64. if (currentId !== id) {
  65. currentId = id
  66. ChunkedArray.add(offsets, vertices.elementCount)
  67. }
  68. },
  69. getMesh: () => {
  70. ChunkedArray.add(offsets, vertices.elementCount)
  71. const mesh = {
  72. vertexCount: vertices.elementCount,
  73. triangleCount: indices.elementCount,
  74. offsetCount: offsets.elementCount,
  75. vertexBuffer: ValueCell.create(ChunkedArray.compact(vertices, true) as Float32Array),
  76. indexBuffer: ValueCell.create(ChunkedArray.compact(indices, true) as Uint32Array),
  77. normalBuffer: ValueCell.create(ChunkedArray.compact(normals, true) as Float32Array),
  78. idBuffer: ValueCell.create(ChunkedArray.compact(ids, true) as Float32Array),
  79. offsetBuffer: ValueCell.create(ChunkedArray.compact(offsets, true) as Uint32Array),
  80. normalsComputed: true,
  81. }
  82. return mesh
  83. }
  84. }
  85. }
  86. }