UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

131 lines (128 loc) 4.76 kB
import { Debug } from '../../core/debug.js'; import { BoundingBox } from '../../core/shape/bounding-box.js'; import { TYPE_UINT32, SEMANTIC_ATTR13, BUFFER_STATIC, ADDRESS_CLAMP_TO_EDGE, FILTER_NEAREST } from '../../platform/graphics/constants.js'; import { Texture } from '../../platform/graphics/texture.js'; import { VertexFormat } from '../../platform/graphics/vertex-format.js'; import { VertexBuffer } from '../../platform/graphics/vertex-buffer.js'; import { Mesh } from '../mesh.js'; /** * @import { Vec2 } from '../../core/math/vec2.js'; * @import { GraphicsDevice } from '../../platform/graphics/graphics-device.js' * @import { GSplatData } from './gsplat-data.js'; * @import { GSplatCompressedData } from './gsplat-compressed-data.js'; * @import { GSplatSogsData } from './gsplat-sogs-data.js'; */ /** * Base class for a GSplat resource and defines common properties. * * @ignore */ class GSplatResourceBase { constructor(device, gsplatData){ this.device = device; this.gsplatData = gsplatData; this.centers = new Float32Array(gsplatData.numSplats * 3); gsplatData.getCenters(this.centers); this.aabb = new BoundingBox(); gsplatData.calcAabb(this.aabb); // construct the mesh // number of quads to combine into a single instance. this is to increase occupancy // in the vertex shader. const splatInstanceSize = 128; const numSplats = Math.ceil(gsplatData.numSplats / splatInstanceSize) * splatInstanceSize; const numSplatInstances = numSplats / splatInstanceSize; // specify the base splat index per instance const indexData = new Uint32Array(numSplatInstances); for(let i = 0; i < numSplatInstances; ++i){ indexData[i] = i * splatInstanceSize; } const vertexFormat = new VertexFormat(device, [ { semantic: SEMANTIC_ATTR13, components: 1, type: TYPE_UINT32, asInt: true } ]); // build the instance mesh const meshPositions = new Float32Array(12 * splatInstanceSize); const meshIndices = new Uint32Array(6 * splatInstanceSize); for(let i = 0; i < splatInstanceSize; ++i){ meshPositions.set([ -1, -1, i, 1, -1, i, 1, 1, i, -1, 1, i ], i * 12); const b = i * 4; meshIndices.set([ 0 + b, 1 + b, 2 + b, 0 + b, 2 + b, 3 + b ], i * 6); } this.mesh = new Mesh(device); this.mesh.setPositions(meshPositions, 3); this.mesh.setIndices(meshIndices); this.mesh.update(); // keep extra reference since mesh is shared between instances this.mesh.incRefCount(); this.mesh.aabb.copy(this.aabb); this.instanceIndices = new VertexBuffer(device, vertexFormat, numSplatInstances, { usage: BUFFER_STATIC, data: indexData.buffer }); } destroy() { this.mesh?.destroy(); this.instanceIndices?.destroy(); } get instanceSize() { return 128; // number of splats per instance } get numSplats() { return this.gsplatData.numSplats; } configureMaterial(material) {} evalTextureSize(count) {} /** * Creates a new texture with the specified parameters. * * @param {string} name - The name of the texture to be created. * @param {number} format - The pixel format of the texture. * @param {Vec2} size - The size of the texture in a Vec2 object, containing width (x) and height (y). * @param {Uint8Array|Uint16Array|Uint32Array} [data] - The initial data to fill the texture with. * @returns {Texture} The created texture instance. */ createTexture(name, format, size, data) { return new Texture(this.device, { name: name, width: size.x, height: size.y, format: format, cubemap: false, mipmaps: false, minFilter: FILTER_NEAREST, magFilter: FILTER_NEAREST, addressU: ADDRESS_CLAMP_TO_EDGE, addressV: ADDRESS_CLAMP_TO_EDGE, ...data ? { levels: [ data ] } : {} }); } instantiate() { Debug.removed('GSplatResource.instantiate is removed. Use gsplat component instead'); } } export { GSplatResourceBase };