mesh.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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 REGL = require('regl');
  7. import { Renderable } from '../renderable'
  8. import { getBuffers } from './util'
  9. import Attribute from '../attribute';
  10. import { MeshShaders } from '../shaders'
  11. type Mesh = 'mesh'
  12. type Uniforms = { [k: string]: REGL.Uniform | REGL.Texture }
  13. export function fillSerial<T extends Helpers.NumberArray> (array: T) {
  14. const n = array.length
  15. for (let i = 0; i < n; ++i) array[ i ] = i
  16. return array
  17. }
  18. namespace Mesh {
  19. export type DataType = {
  20. position: { type: Float32Array, itemSize: 3 }
  21. normal: { type: Float32Array, itemSize: 3 }
  22. transformColumn0: { type: Float32Array, itemSize: 4 }
  23. transformColumn1: { type: Float32Array, itemSize: 4 }
  24. transformColumn2: { type: Float32Array, itemSize: 4 }
  25. transformColumn3: { type: Float32Array, itemSize: 4 }
  26. }
  27. export type Data = { [K in keyof DataType]: DataType[K]['type'] }
  28. export type Attributes = { [K in keyof Data]: Attribute<Data[K]> }
  29. export function create(regl: REGL.Regl, attributes: Attributes, uniforms: Uniforms, elements?: Helpers.UintArray): Renderable<Data> {
  30. // console.log('mesh', {
  31. // count: attributes.position.getCount(),
  32. // instances: attributes.transformColumn0.getCount(),
  33. // attributes,
  34. // uniforms
  35. // })
  36. const instanceCount = attributes.transformColumn0.getCount()
  37. const instanceId = fillSerial(new Float32Array(instanceCount))
  38. // console.log(instanceId)
  39. const command = regl({
  40. ...MeshShaders,
  41. uniforms: {
  42. objectId: uniforms.objectId || 0,
  43. instanceCount,
  44. ...uniforms
  45. },
  46. attributes: getBuffers({
  47. instanceId: Attribute.create(regl, instanceId, { size: 1, divisor: 1 }),
  48. ...attributes
  49. }),
  50. elements: elements && regl.elements({
  51. data: new Uint16Array(elements),
  52. primitive: 'triangles',
  53. // type: 'uint16',
  54. // count: elements.length / 3,
  55. // length: elements.length * 2
  56. }),
  57. count: elements ? elements.length : attributes.position.getCount(),
  58. instances: instanceCount,
  59. primitive: 'triangles'
  60. })
  61. return {
  62. draw: () => command(),
  63. }
  64. }
  65. }
  66. export default Mesh