Home Reference Source

cables_dev/cables/src/core/cgp/cgp_mesh.js

  1. import { Logger } from "cables-shared-client";
  2. import Pipeline from "./cgp_pipeline.js";
  3.  
  4. export default class Mesh
  5. {
  6. constructor(_cgp, __geom)
  7. {
  8. this._log = new Logger("cgl_mesh");
  9. this._cgp = _cgp;
  10. this._geom = null;
  11. this.numIndex = 0;
  12. this.instances = 1;
  13.  
  14. this._pipe = new Pipeline(this._cgp, "new mesh");
  15. this._numNonIndexed = 0;
  16. this._positionBuffer = null;
  17. this._bufVerticesIndizes = null;
  18. this._attributes = [];
  19. this._needsPipelineUpdate = false;
  20.  
  21. if (__geom) this.setGeom(__geom);
  22. }
  23.  
  24. _createBuffer(device, data, usage)
  25. {
  26. let bo = {
  27. "size": data.byteLength,
  28. "usage": usage,
  29. "mappedAtCreation": true,
  30. };
  31. // ifbo.stepMode = "instance";
  32. const buffer = device.createBuffer(bo);
  33. const dst = new data.constructor(buffer.getMappedRange());
  34. dst.set(data);
  35. buffer.unmap();
  36. return buffer;
  37. }
  38.  
  39. /**
  40. * @function setGeom
  41. * @memberof Mesh
  42. * @instance
  43. * @description set geometry for mesh
  44. * @param {Geometry} geom geometry
  45. * @param {boolean} removeRef
  46. */
  47. setGeom(geom, removeRef)
  48. {
  49. this._needsPipelineUpdate = true;
  50. this._geom = geom;
  51. this._disposeAttributes();
  52.  
  53. this._positionBuffer = this._createBuffer(this._cgp.device, new Float32Array(geom.vertices), GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST);
  54.  
  55. let vi = geom.verticesIndices;
  56. if (!geom.isIndexed()) vi = Array.from(Array(geom.vertices.length / 3).keys());
  57. this._numIndices = vi.length;
  58. this._indicesBuffer = this._createBuffer(this._cgp.device, new Uint32Array(vi), GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST);
  59.  
  60. if (geom.texCoords && geom.texCoords.length) this.setAttribute("texCoords", geom.texCoords, 2);
  61. if (geom.vertexNormals && geom.vertexNormals.length) this.setAttribute("normals", geom.vertexNormals, 3);
  62.  
  63. this.setAttribute("normals", geom.vertexNormals, 3);
  64. }
  65.  
  66.  
  67. _disposeAttributes()
  68. {
  69. this._needsPipelineUpdate = true;
  70. for (let i = 0; i < this._attributes.length; i++)
  71. {
  72. this._attributes[i].buffer.destroy();
  73. }
  74. this._attributes.length = 0;
  75. }
  76.  
  77. dispose()
  78. {
  79. this._disposeAttributes();
  80. }
  81.  
  82. /**
  83. * @function setAttribute
  84. * @description update attribute
  85. * @memberof Mesh
  86. * @instance
  87. * @param {String} name attribute name
  88. * @param {Array} array data
  89. * @param {Number} itemSize
  90. * @param {Object} options
  91. */
  92. setAttribute(name, array, itemSize, options = {})
  93. {
  94. if (!array)
  95. {
  96. this._log.error("mesh addAttribute - no array given! " + name);
  97. throw new Error();
  98. }
  99.  
  100. let instanced = false;
  101. if (options.instanced) instanced = options.instanced;
  102.  
  103. const buffer = this._createBuffer(this._cgp.device, new Float32Array(array), GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST);
  104.  
  105. const attr = {
  106. "buffer": buffer,
  107. "name": name,
  108. "instanced": instanced,
  109. };
  110. this._attributes.push(attr);
  111.  
  112. return attr;
  113. }
  114.  
  115.  
  116. render()
  117. {
  118. if (!this._positionBuffer) return;
  119. if (this.instances <= 0) return;
  120.  
  121. const shader = this._cgp.getShader();
  122. if (shader)shader.bind();
  123.  
  124. if (!this._cgp.getShader() || !this._cgp.getShader().isValid)
  125. {
  126. // this.status = "shader invalid";
  127. return;
  128. }
  129.  
  130. if (this._cgp.frameStore.branchProfiler) this._cgp.frameStore.branchStack.push("mesh", ["geom " + this._geom.name, "shader " + this._cgp.getShader().getName()]);
  131.  
  132. this._pipe.setName("mesh " + this._geom.name + " " + this._cgp.getShader().getName());
  133. this._pipe.setPipeline(this._cgp.getShader(), this);
  134.  
  135.  
  136. if (this._pipe.isValid)
  137. {
  138. this._cgp.passEncoder.setVertexBuffer(0, this._positionBuffer);
  139. for (let i = 0; i < this._attributes.length; i++)
  140. {
  141. this._cgp.passEncoder.setVertexBuffer(i + 1, this._attributes[i].buffer);
  142. }
  143.  
  144. this._cgp.passEncoder.setIndexBuffer(this._indicesBuffer, "uint32");
  145.  
  146. if (this._numNonIndexed)
  147. this._cgp.passEncoder.draw(this._numIndices, this.instances);
  148. else
  149. this._cgp.passEncoder.drawIndexed(this._numIndices, this.instances);
  150. }
  151.  
  152. if (this._cgp.frameStore.branchProfiler) this._cgp.frameStore.branchStack.pop();
  153.  
  154. // if (shader)shader.unbind();
  155. }
  156. }