viewer/buffertransformer.js
/**
* This class transforms buffers. The main purpose is to fix discrepancies between the over-the-line format and the glsl format. In ideal situations no conversions are needed.
* At the moment these methods are only used when data is reused. The idea is that all transformations will happen in this class, making for more readable renderers
*/
export class BufferTransformer {
constructor(settings, vertexQuantization) {
this.settings = settings;
this.vertexQuantization = vertexQuantization;
}
convertVertices(uniqueModelId, vertices) {
if (this.settings.quantizeVertices == this.settings.loaderSettings.quantizeVertices) {
return vertices;
}
var vertex = Array(3);
var newPositions;
if (this.settings.quantizeVertices) {
newPositions = new Int16Array(vertices.length);
} else {
newPositions = new Float32Array(vertices.length);
}
for (var i=0; i<vertices.length; i+=3) {
// When quantizeVertices is on and we use the buffers in a combined buffer (which is what this method, addGeometry does),
// we need to un-quantize the vertices, transform them, then quantize them again (so the shaders can again unquantize them).
// This because order does matter (object transformation sometimes even mirror stuff)
// Obviously quantization slows down both CPU (only initially) and GPU (all the time)
vertex[0] = vertices[i + 0];
vertex[1] = vertices[i + 1];
vertex[2] = vertices[i + 2];
// if (this.settings.loaderSettings.quantizeVertices) {
// vec3.transformMat4(vertex, vertex, this.vertexQuantization.getUntransformedInverseVertexQuantizationMatrixForUniqueModelId(uniqueModelId));
// }
// TODO something is wrong here
// if (this.settings.quantizeVertices) {
// vec3.transformMat4(vertex, vertex, this.vertexQuantization.getUntransformedVertexQuantizationMatrix());
// }
newPositions.set(vertex, i);
}
return newPositions;
}
convertNormals(normals) {
// When the given normals variable is already in the right format according to the settings, just return that
if ((this.settings.quantizeNormals && normals instanceof Int8Array) || (!this.settings.quantizeNormals && normals instanceof Float32Array)) {
return normals;
}
var newNormals;
if (this.settings.quantizeNormals) {
newNormals = new Int8Array(normals.length);
} else {
newNormals = new Float32Array(normals.length);
}
var normal = Array(3);
for (var i=0; i<normals.length; i+=3) {
normal[0] = normals[i + 0];
normal[1] = normals[i + 1];
normal[2] = normals[i + 2];
// Because of the early return on the top of this method, only 2 out of 4 combinations are possible, allowing for this if/else
if (this.settings.quantizeNormals) {
normal[0] = normal[0] * 127;
normal[1] = normal[1] * 127;
normal[2] = normal[2] * 127;
} else {
normal[0] = normal[0] / 127;
normal[1] = normal[1] / 127;
normal[2] = normal[2] / 127;
}
newNormals.set(normal, i);
}
return newNormals;
}
convertIndices(indices, nrOfVertices) {
if (this.settings.useSmallIndicesIfPossible && nrOfVertices < 65536) {
// TODO at the moment, indices are never sent in unsigned 16 format
if (indices instanceof Uint16Array) {
return indices;
}
return new Uint16Array(indices);
} else {
if (indices instanceof Uint32Array) {
return indices;
}
return new Uint32Array(indices);
}
}
}