entity/geoObject/InstanceData.tstypescript
import { GeoObject } from "./GeoObject";
import type { WebGLBufferExt, WebGLTextureExt } from "../../webgl/Handler";
import { loadImage, makeArrayTyped, prepareTextureImage } from "../../utils/shared";
import type { TypedArray } from "../../utils/shared";
import { ShaderProgram } from "../../webgl/ShaderProgram";
import { GeoObjectHandler } from "./GeoObjectHandler";
import {
VERTEX_BUFFER,
RTC_POSITION_BUFFER,
RGBA_BUFFER,
NORMALS_BUFFER,
INDEX_BUFFER,
QROT_BUFFER,
SIZE_BUFFER,
PICKINGCOLOR_BUFFER,
VISIBLE_BUFFER,
TEXCOORD_BUFFER,
TRANSLATE_BUFFER,
LOCALPOSITION_BUFFER
} from "./GeoObjectHandler";
const AMBIENT_OCCLUSION = 0;
const ROUGHNESS = 1;
const METALLIC = 2;
export class InstanceData {
public isFree: boolean;
public _geoObjectHandler: GeoObjectHandler;
public geoObjects: GeoObject[];
public numInstances: number;
public _opaqueInstanceCount: number;
public _colorTexture: WebGLTextureExt | null;
public _normalTexture: WebGLTextureExt | null;
public _ambientOcclusionTexture: WebGLTextureExt | null;
public _metallicRoughnessTexture: WebGLTextureExt | null;
public _colorTextureSrc: string | null;
public _normalTextureSrc: string | null;
public _ambientOcclusionTextureSrc: string | null;
public _metallicRoughnessTextureSrc: string | null;
public _colorTextureImage: HTMLImageElement | null;
public _normalTextureImage: HTMLImageElement | null;
public _ambientOcclusionTextureImage: HTMLImageElement | null;
public _metallicRoughnessTextureImage: HTMLImageElement | null;
public _objectSrc?: string;
public _sizeArr: number[] | TypedArray;
public _translateArr: number[] | TypedArray;
public _vertexArr: number[] | TypedArray;
public _rtcPositionHighArr: number[] | TypedArray;
public _rtcPositionLowArr: number[] | TypedArray;
public _qRotArr: number[] | TypedArray;
public _rgbaArr: number[] | TypedArray;
public _normalsArr: number[] | TypedArray;
public _indicesArr: number[] | TypedArray;
public _pickingColorArr: number[] | TypedArray;
public _visibleArr: number[] | TypedArray;
public _texCoordArr: number[] | TypedArray;
public _localPositionArr: number[] | TypedArray;
public _sizeBuffer: WebGLBufferExt | null;
public _translateBuffer: WebGLBufferExt | null;
public _vertexBuffer: WebGLBufferExt | null;
public _rtcPositionHighBuffer: WebGLBufferExt | null;
public _rtcPositionLowBuffer: WebGLBufferExt | null;
public _qRotBuffer: WebGLBufferExt | null;
public _rgbaBuffer: WebGLBufferExt | null;
public _normalsBuffer: WebGLBufferExt | null;
public _indicesBuffer: WebGLBufferExt | null;
public _pickingColorBuffer: WebGLBufferExt | null;
public _visibleBuffer: WebGLBufferExt | null;
public _texCoordBuffer: WebGLBufferExt | null;
public _localPositionBuffer: WebGLBufferExt | null;
public _buffersUpdateCallbacks: Function[];
public _changedBuffers: boolean[];
public _materialProperties: Float32Array;
constructor(geoObjectHandler: GeoObjectHandler) {
this.isFree = true;
this._geoObjectHandler = geoObjectHandler;
this.geoObjects = [];
this.numInstances = 0;
this._opaqueInstanceCount = 0;
this._colorTexture = null;
this._colorTextureSrc = null;
this._colorTextureImage = null;
this._normalTexture = null;
this._normalTextureSrc = null;
this._normalTextureImage = null;
this._ambientOcclusionTexture = null;
this._ambientOcclusionTextureSrc = null;
this._ambientOcclusionTextureImage = null;
this._metallicRoughnessTexture = null;
this._metallicRoughnessTextureSrc = null;
this._metallicRoughnessTextureImage = null;
this._sizeArr = [];
this._translateArr = [];
this._vertexArr = [];
this._rtcPositionHighArr = [];
this._rtcPositionLowArr = [];
this._qRotArr = [];
this._rgbaArr = [];
this._normalsArr = [];
this._indicesArr = [];
this._pickingColorArr = [];
this._visibleArr = [];
this._texCoordArr = [];
this._localPositionArr = [];
this._sizeBuffer = null;
this._translateBuffer = null;
this._vertexBuffer = null;
this._rtcPositionHighBuffer = null;
this._rtcPositionLowBuffer = null;
this._qRotBuffer = null;
this._rgbaBuffer = null;
this._normalsBuffer = null;
this._indicesBuffer = null;
this._pickingColorBuffer = null;
this._visibleBuffer = null;
this._texCoordBuffer = null;
this._localPositionBuffer = null;
this._materialProperties = new Float32Array(3);
this._buffersUpdateCallbacks = [];
this._buffersUpdateCallbacks[PICKINGCOLOR_BUFFER] = this.createPickingColorBuffer;
this._buffersUpdateCallbacks[NORMALS_BUFFER] = this.createNormalsBuffer;
this._buffersUpdateCallbacks[RGBA_BUFFER] = this.createRgbaBuffer;
this._buffersUpdateCallbacks[INDEX_BUFFER] = this.createIndicesBuffer;
this._buffersUpdateCallbacks[VERTEX_BUFFER] = this.createVertexBuffer;
this._buffersUpdateCallbacks[SIZE_BUFFER] = this.createSizeBuffer;
this._buffersUpdateCallbacks[VISIBLE_BUFFER] = this.createVisibleBuffer;
this._buffersUpdateCallbacks[TEXCOORD_BUFFER] = this.createTexCoordBuffer;
this._buffersUpdateCallbacks[QROT_BUFFER] = this.createQRotBuffer;
this._buffersUpdateCallbacks[TRANSLATE_BUFFER] = this.createTranslateBuffer;
this._buffersUpdateCallbacks[RTC_POSITION_BUFFER] = this.createRTCPositionBuffer;
this._buffersUpdateCallbacks[LOCALPOSITION_BUFFER] = this.createLocalPositionBuffer;
this._changedBuffers = new Array(this._buffersUpdateCallbacks.length);
}
public setMetallic(metallic: number) {
this._materialProperties[METALLIC] = metallic;
}
public setRoughness(roughness: number) {
this._materialProperties[ROUGHNESS] = roughness;
}
public setAmbientOcclusion(ambientOcclusion: number) {
this._materialProperties[AMBIENT_OCCLUSION] = ambientOcclusion;
}
public setMaterialProperties(ambientOcclusion: number, roughness: number, metallic: number) {
this.setAmbientOcclusion(ambientOcclusion);
this.setRoughness(roughness);
this.setMetallic(metallic);
}
//
// Instance individual data
//
public drawOpaque(p: ShaderProgram) {
const instanceCount = this._opaqueInstanceCount;
if (instanceCount <= 0) {
return;
}
let gl = p.gl!,
u = p.uniforms,
a = p.attributes;
gl.bindBuffer(gl.ARRAY_BUFFER, this._qRotBuffer!);
gl.vertexAttribPointer(a.qRot, this._qRotBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this._sizeBuffer!);
gl.vertexAttribPointer(a.aScale, this._sizeBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this._translateBuffer!);
gl.vertexAttribPointer(a.aTranslate, this._translateBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this._localPositionBuffer!);
gl.vertexAttribPointer(a.aLocalPosition, this._localPositionBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this._visibleBuffer!);
gl.vertexAttribPointer(a.aDispose, this._visibleBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.uniform1f(u.uUseColorTexture, this._colorTexture ? 1 : 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this._rgbaBuffer!);
gl.vertexAttribPointer(a.aColor, this._rgbaBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.uniform3fv(u.materialProperties, this._materialProperties);
this._drawElementsInstanced(p, 0, instanceCount);
}
//
// All instances in forward pass(opaque + transparent)
//
public drawForwardAll(p: ShaderProgram) {
const instanceCount = this.numInstances;
if (instanceCount <= 0) {
return;
}
let gl = p.gl!,
u = p.uniforms,
a = p.attributes;
gl.bindBuffer(gl.ARRAY_BUFFER, this._qRotBuffer!);
gl.vertexAttribPointer(a.qRot, this._qRotBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this._sizeBuffer!);
gl.vertexAttribPointer(a.aScale, this._sizeBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this._translateBuffer!);
gl.vertexAttribPointer(a.aTranslate, this._translateBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this._localPositionBuffer!);
gl.vertexAttribPointer(a.aLocalPosition, this._localPositionBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this._visibleBuffer!);
gl.vertexAttribPointer(a.aDispose, this._visibleBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.uniform1f(u.uUseColorTexture, this._colorTexture ? 1 : 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this._rgbaBuffer!);
gl.vertexAttribPointer(a.aColor, this._rgbaBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.uniform3fv(u.materialProperties, this._materialProperties);
this._drawElementsInstanced(p, 0, instanceCount);
}
//
// Instance individual data
//
public drawTransparent(p: ShaderProgram) {
const startInstance = this._opaqueInstanceCount;
const instanceCount = this.numInstances - startInstance;
if (instanceCount <= 0) {
return;
}
let gl = p.gl!,
u = p.uniforms,
a = p.attributes;
gl.bindBuffer(gl.ARRAY_BUFFER, this._qRotBuffer!);
gl.vertexAttribPointer(
a.qRot,
this._qRotBuffer!.itemSize,
gl.FLOAT,
false,
0,
startInstance * this._qRotBuffer!.itemSize * Float32Array.BYTES_PER_ELEMENT
);
gl.bindBuffer(gl.ARRAY_BUFFER, this._sizeBuffer!);
gl.vertexAttribPointer(
a.aScale,
this._sizeBuffer!.itemSize,
gl.FLOAT,
false,
0,
startInstance * this._sizeBuffer!.itemSize * Float32Array.BYTES_PER_ELEMENT
);
gl.bindBuffer(gl.ARRAY_BUFFER, this._translateBuffer!);
gl.vertexAttribPointer(
a.aTranslate,
this._translateBuffer!.itemSize,
gl.FLOAT,
false,
0,
startInstance * this._translateBuffer!.itemSize * Float32Array.BYTES_PER_ELEMENT
);
gl.bindBuffer(gl.ARRAY_BUFFER, this._localPositionBuffer!);
gl.vertexAttribPointer(
a.aLocalPosition,
this._localPositionBuffer!.itemSize,
gl.FLOAT,
false,
0,
startInstance * this._localPositionBuffer!.itemSize * Float32Array.BYTES_PER_ELEMENT
);
gl.bindBuffer(gl.ARRAY_BUFFER, this._visibleBuffer!);
gl.vertexAttribPointer(
a.aDispose,
this._visibleBuffer!.itemSize,
gl.FLOAT,
false,
0,
startInstance * this._visibleBuffer!.itemSize * Float32Array.BYTES_PER_ELEMENT
);
gl.uniform1f(u.uUseColorTexture, this._colorTexture ? 1 : 0);
gl.uniform3fv(u.materialProperties, this._materialProperties);
gl.bindBuffer(gl.ARRAY_BUFFER, this._rgbaBuffer!);
gl.vertexAttribPointer(
a.aColor,
this._rgbaBuffer!.itemSize,
gl.FLOAT,
false,
0,
startInstance * this._rgbaBuffer!.itemSize * Float32Array.BYTES_PER_ELEMENT
);
this._drawElementsInstanced(p, startInstance, instanceCount);
}
//
// Instance common data(could be in VAO)
//
protected _drawElementsInstanced(p: ShaderProgram, startInstance: number, instanceCount: number) {
let gl = p.gl!,
u = p.uniforms,
a = p.attributes;
let r = this._geoObjectHandler!._renderer!;
gl.bindBuffer(gl.ARRAY_BUFFER, this._rtcPositionHighBuffer!);
gl.vertexAttribPointer(
a.aRTCPositionHigh,
this._rtcPositionHighBuffer!.itemSize,
gl.FLOAT,
false,
0,
startInstance * this._rtcPositionHighBuffer!.itemSize * Float32Array.BYTES_PER_ELEMENT
);
gl.bindBuffer(gl.ARRAY_BUFFER, this._rtcPositionLowBuffer!);
gl.vertexAttribPointer(
a.aRTCPositionLow,
this._rtcPositionLowBuffer!.itemSize,
gl.FLOAT,
false,
0,
startInstance * this._rtcPositionLowBuffer!.itemSize * Float32Array.BYTES_PER_ELEMENT
);
gl.bindBuffer(gl.ARRAY_BUFFER, this._normalsBuffer!);
gl.vertexAttribPointer(a.aVertexNormal, this._normalsBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer!);
gl.vertexAttribPointer(a.aVertexPosition, this._vertexBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this._colorTexture || r.handler.defaultTexture);
gl.uniform1i(u.uColorTexture, 0);
gl.uniform1f(u.uUseNormalTexture, this._normalTexture ? 1 : 0);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, this._normalTexture || r.handler.defaultTexture);
gl.uniform1i(u.uNormalTexture, 1);
gl.uniform1f(u.uUseMetallicRoughnessTexture, this._metallicRoughnessTexture ? 1 : 0);
gl.activeTexture(gl.TEXTURE2);
gl.bindTexture(gl.TEXTURE_2D, this._metallicRoughnessTexture || r.handler.defaultTexture);
gl.uniform1i(u.uMetallicRoughnessTexture, 2);
gl.uniform1f(u.uUseAOTexture, this._ambientOcclusionTexture ? 1 : 0);
gl.activeTexture(gl.TEXTURE3);
gl.bindTexture(gl.TEXTURE_2D, this._ambientOcclusionTexture || r.handler.defaultTexture);
gl.uniform1i(u.uAOTexture, 3);
gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordBuffer!);
gl.vertexAttribPointer(a.aTexCoord, this._texCoordBuffer!.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer!);
p.drawElementsInstanced!(gl.TRIANGLES, this._indicesBuffer!.numItems, gl.UNSIGNED_INT, 0, instanceCount);
}
public async loadColorTexture() {
if (!this._geoObjectHandler._renderer) {
return;
}
if (this._colorTextureSrc) {
const image = await loadImage(this._colorTextureSrc);
const textureImage = await prepareTextureImage(image);
if (textureImage) {
this._createColorTexture(textureImage);
}
return;
}
if (this._colorTextureImage) {
const textureImage = await prepareTextureImage(this._colorTextureImage);
if (textureImage) {
this._createColorTexture(textureImage);
}
return;
}
}
public async loadNormalTexture() {
if (!this._geoObjectHandler._renderer) {
return;
}
if (this._normalTextureSrc) {
const image = await loadImage(this._normalTextureSrc);
const textureImage = await prepareTextureImage(image);
if (textureImage) {
this._createNormalTexture(textureImage);
}
return;
}
if (this._normalTextureImage) {
const textureImage = await prepareTextureImage(this._normalTextureImage);
if (textureImage) {
this._createNormalTexture(textureImage);
}
return;
}
}
public async loadMetallicRoughnessTexture() {
if (!this._geoObjectHandler._renderer) {
return;
}
if (this._metallicRoughnessTextureSrc) {
const image = await loadImage(this._metallicRoughnessTextureSrc);
const textureImage = await prepareTextureImage(image);
if (textureImage) {
this._createMetallicRoughnessTexture(textureImage);
}
return;
}
if (this._metallicRoughnessTextureImage) {
const textureImage = await prepareTextureImage(this._metallicRoughnessTextureImage);
if (textureImage) {
this._createMetallicRoughnessTexture(textureImage);
}
return;
}
}
public async loadAmbientOcclusionTexture() {
if (!this._geoObjectHandler._renderer) {
return;
}
if (this._ambientOcclusionTextureSrc) {
const image = await loadImage(this._ambientOcclusionTextureSrc);
const textureImage = await prepareTextureImage(image);
if (textureImage) {
this._createAmbientOcclusionTexture(textureImage);
}
return;
}
if (this._ambientOcclusionTextureImage) {
const textureImage = await prepareTextureImage(this._ambientOcclusionTextureImage);
if (textureImage) {
this._createAmbientOcclusionTexture(textureImage);
}
return;
}
}
public clear() {
this.numInstances = 0;
this._opaqueInstanceCount = 0;
this.geoObjects = [];
this._sizeArr = [];
this._translateArr = [];
this._vertexArr = [];
this._rtcPositionHighArr = [];
this._rtcPositionLowArr = [];
this._qRotArr = [];
this._rgbaArr = [];
this._normalsArr = [];
this._indicesArr = [];
this._pickingColorArr = [];
this._visibleArr = [];
this._texCoordArr = [];
this._localPositionArr = [];
this._deleteBuffers();
this.isFree = false;
//this._geoObjectHandler = null;
}
public _deleteBuffers() {
if (this._geoObjectHandler && this._geoObjectHandler._renderer) {
let r = this._geoObjectHandler._renderer;
let h = r.handler;
if (h) {
r.releaseTexture(this._colorTexture);
r.releaseTexture(this._normalTexture);
r.releaseTexture(this._ambientOcclusionTexture);
r.releaseTexture(this._metallicRoughnessTexture);
let gl = h.gl;
if (gl) {
gl.deleteBuffer(this._sizeBuffer!);
gl.deleteBuffer(this._translateBuffer!);
gl.deleteBuffer(this._vertexBuffer!);
gl.deleteBuffer(this._rtcPositionHighBuffer!);
gl.deleteBuffer(this._rtcPositionLowBuffer!);
gl.deleteBuffer(this._qRotBuffer!);
gl.deleteBuffer(this._rgbaBuffer!);
gl.deleteBuffer(this._normalsBuffer!);
gl.deleteBuffer(this._indicesBuffer!);
gl.deleteBuffer(this._pickingColorBuffer!);
gl.deleteBuffer(this._visibleBuffer!);
gl.deleteBuffer(this._texCoordBuffer!);
gl.deleteBuffer(this._localPositionBuffer!);
}
}
this._colorTexture = null;
this._normalTexture = null;
this._ambientOcclusionTexture = null;
this._metallicRoughnessTexture = null;
}
this._sizeBuffer = null;
this._translateBuffer = null;
this._vertexBuffer = null;
this._rtcPositionHighBuffer = null;
this._rtcPositionLowBuffer = null;
this._qRotBuffer = null;
this._rgbaBuffer = null;
this._normalsBuffer = null;
this._indicesBuffer = null;
this._pickingColorBuffer = null;
this._visibleBuffer = null;
this._texCoordBuffer = null;
this._localPositionBuffer = null;
}
public createVertexBuffer() {
const h = this._geoObjectHandler._renderer!.handler;
h.gl!.deleteBuffer(this._vertexBuffer!);
this._vertexArr = makeArrayTyped(this._vertexArr);
this._vertexBuffer = h.createArrayBuffer(this._vertexArr as Float32Array, 3, this._vertexArr.length / 3);
}
public createVisibleBuffer() {
const h = this._geoObjectHandler._renderer!.handler,
numItems = this._visibleArr.length;
if (!this._visibleBuffer || this._visibleBuffer.numItems !== numItems) {
h.gl!.deleteBuffer(this._visibleBuffer!);
this._visibleBuffer = h.createStreamArrayBuffer(1, numItems);
}
this._visibleArr = makeArrayTyped(this._visibleArr);
h.setStreamArrayBuffer(this._visibleBuffer, this._visibleArr as Uint8Array);
}
public createSizeBuffer() {
let h = this._geoObjectHandler._renderer!.handler,
numItems = this._sizeArr.length / 3;
if (!this._sizeBuffer || this._sizeBuffer.numItems !== numItems) {
h.gl!.deleteBuffer(this._sizeBuffer!);
this._sizeBuffer = h.createStreamArrayBuffer(3, numItems);
}
this._sizeArr = makeArrayTyped(this._sizeArr);
h.setStreamArrayBuffer(this._sizeBuffer, this._sizeArr as Float32Array);
}
public createTranslateBuffer() {
let h = this._geoObjectHandler._renderer!.handler,
numItems = this._translateArr.length / 3;
if (!this._translateBuffer || this._translateBuffer.numItems !== numItems) {
h.gl!.deleteBuffer(this._translateBuffer!);
this._translateBuffer = h.createStreamArrayBuffer(3, numItems);
}
this._translateArr = makeArrayTyped(this._translateArr);
h.setStreamArrayBuffer(this._translateBuffer, this._translateArr as Float32Array);
}
public createLocalPositionBuffer() {
let h = this._geoObjectHandler._renderer!.handler,
numItems = this._localPositionArr.length / 3;
if (!this._localPositionBuffer || this._localPositionBuffer.numItems !== numItems) {
h.gl!.deleteBuffer(this._localPositionBuffer!);
this._localPositionBuffer = h.createStreamArrayBuffer(3, numItems);
}
this._localPositionArr = makeArrayTyped(this._localPositionArr);
h.setStreamArrayBuffer(this._localPositionBuffer, this._localPositionArr as Float32Array);
}
public createTexCoordBuffer() {
const h = this._geoObjectHandler._renderer!.handler;
h.gl!.deleteBuffer(this._texCoordBuffer!);
this._texCoordArr = makeArrayTyped(this._texCoordArr);
this._texCoordBuffer = h.createArrayBuffer(this._texCoordArr as Uint8Array, 2, this._texCoordArr.length / 2);
}
public createRTCPositionBuffer() {
let h = this._geoObjectHandler._renderer!.handler,
numItems = this._rtcPositionHighArr.length / 3;
if (!this._rtcPositionHighBuffer || this._rtcPositionHighBuffer.numItems !== numItems) {
h.gl!.deleteBuffer(this._rtcPositionHighBuffer!);
h.gl!.deleteBuffer(this._rtcPositionLowBuffer!);
this._rtcPositionHighBuffer = h.createStreamArrayBuffer(3, numItems);
this._rtcPositionLowBuffer = h.createStreamArrayBuffer(3, numItems);
}
this._rtcPositionHighArr = makeArrayTyped(this._rtcPositionHighArr);
this._rtcPositionLowArr = makeArrayTyped(this._rtcPositionLowArr);
h.setStreamArrayBuffer(this._rtcPositionHighBuffer!, this._rtcPositionHighArr as Float32Array);
h.setStreamArrayBuffer(this._rtcPositionLowBuffer!, this._rtcPositionLowArr as Float32Array);
}
public createRgbaBuffer() {
let h = this._geoObjectHandler._renderer!.handler,
numItems = this._rgbaArr.length / 4;
if (!this._rgbaBuffer || this._rgbaBuffer.numItems !== numItems) {
h.gl!.deleteBuffer(this._rgbaBuffer!);
this._rgbaBuffer = h.createStreamArrayBuffer(4, numItems);
}
this._rgbaArr = makeArrayTyped(this._rgbaArr);
h.setStreamArrayBuffer(this._rgbaBuffer, this._rgbaArr as Uint8Array);
}
public createQRotBuffer() {
let h = this._geoObjectHandler._renderer!.handler,
numItems = this._qRotArr.length / 4;
if (!this._qRotBuffer || this._qRotBuffer.numItems !== numItems) {
h.gl!.deleteBuffer(this._qRotBuffer!);
this._qRotBuffer = h.createStreamArrayBuffer(4, numItems);
}
this._qRotArr = makeArrayTyped(this._qRotArr);
h.setStreamArrayBuffer(this._qRotBuffer, this._qRotArr as Float32Array);
}
public createNormalsBuffer() {
const h = this._geoObjectHandler._renderer!.handler;
h.gl!.deleteBuffer(this._normalsBuffer!);
this._normalsArr = makeArrayTyped(this._normalsArr);
this._normalsBuffer = h.createArrayBuffer(this._normalsArr as Uint8Array, 3, this._normalsArr.length / 3);
}
public createIndicesBuffer() {
const h = this._geoObjectHandler._renderer!.handler;
h.gl!.deleteBuffer(this._indicesBuffer!);
this._indicesArr = makeArrayTyped(this._indicesArr, Uint32Array);
this._indicesBuffer = h.createElementArrayBuffer(this._indicesArr as Uint32Array, 1, this._indicesArr.length);
}
public createPickingColorBuffer() {
const h = this._geoObjectHandler._renderer!.handler;
h.gl!.deleteBuffer(this._pickingColorBuffer!);
this._pickingColorArr = makeArrayTyped(this._pickingColorArr);
this._pickingColorBuffer = h.createArrayBuffer(
this._pickingColorArr as Uint8Array,
3,
this._pickingColorArr.length / 3
);
}
public refresh() {
let i = this._changedBuffers.length;
while (i--) {
this.setChangedBuffer(i);
}
}
/**
* Marks a buffer to be updated in the next frame and requests the frame to be rendered.
* @public
* @param {number} index - Buffer index.
*/
public setChangedBuffer(index: number) {
this._changedBuffers[index] = true;
this._geoObjectHandler._renderer && this._geoObjectHandler._renderer.requestRedraw();
}
public update() {
if (this._geoObjectHandler._renderer) {
let i = this._changedBuffers.length;
while (i--) {
if (this._changedBuffers[i]) {
this._buffersUpdateCallbacks[i].call(this);
this._changedBuffers[i] = false;
}
}
this.isFree = true;
}
}
private _createColorTexture(image: HTMLCanvasElement | ImageBitmap | ImageData | HTMLImageElement) {
if (this._geoObjectHandler && this._geoObjectHandler._renderer) {
let r = this._geoObjectHandler._renderer;
let h = r.handler;
const gl = h.gl!;
this._colorTexture = r.acquireTexture({
image,
internalFormat: h.gl!.SRGB8_ALPHA8,
texParami: gl.REPEAT
});
}
}
private _createNormalTexture(image: HTMLCanvasElement | ImageBitmap | ImageData | HTMLImageElement) {
if (this._geoObjectHandler && this._geoObjectHandler._renderer) {
let r = this._geoObjectHandler._renderer;
let h = r.handler;
this._normalTexture = r.acquireTexture({
image,
internalFormat: null,
texParami: h.gl!.REPEAT
});
}
}
private _createMetallicRoughnessTexture(image: HTMLCanvasElement | ImageBitmap | ImageData | HTMLImageElement) {
if (this._geoObjectHandler && this._geoObjectHandler._renderer) {
let r = this._geoObjectHandler._renderer;
let h = r.handler;
this._metallicRoughnessTexture = r.acquireTexture({
image,
internalFormat: null,
texParami: h.gl!.REPEAT
});
}
}
private _createAmbientOcclusionTexture(image: HTMLCanvasElement | ImageBitmap | ImageData | HTMLImageElement) {
if (this._geoObjectHandler && this._geoObjectHandler._renderer) {
let r = this._geoObjectHandler._renderer;
let h = r.handler;
this._ambientOcclusionTexture = r.acquireTexture({
image,
internalFormat: null,
texParami: h.gl!.REPEAT
});
}
}
}