viewer/vertexquantization.js
import * as mat4 from "./glmatrix/mat4.js";
import * as vec3 from "./glmatrix/vec3.js";
import {Utils} from "./utils.js";
/**
* This class is responsible for keeping track of the various matrices used for quantization/unquantization
*
* uniqueModelId when loading from BIMserver stands for: ConcreteRevision Object Identifier, it's a BIMserver object, you can see it as a unique identifier that identifies a revision.
*/
export class VertexQuantization {
constructor(settings) {
this.settings = settings;
// uniqueModelId -> untransformed quantization matrices (1 per model)
this.untransformedQuantizationMatrices = new Map();
// uniqueModelId -> untransformed inverse quantization matrices (1 per model)
this.untransformedInverseQuantizationMatrices = new Map();
}
getUntransformedInverseVertexQuantizationMatrixForUniqueModelId(uniqueModelId) {
var matrix = this.untransformedInverseQuantizationMatrices.get(uniqueModelId);
if (matrix == null) {
throw "Not found for uniqueModelId " + uniqueModelId;
}
return matrix;
}
getUntransformedVertexQuantizationMatrixForUniqueModelId(uniqueModelId) {
var matrix = this.untransformedQuantizationMatrices.get(uniqueModelId);
if (matrix == null) {
throw "Not found: " + uniqueModelId;
}
return matrix;
}
getTransformedVertexQuantizationMatrix() {
if (this.vertexQuantizationMatrix == null) {
throw "Not found: vertexQuantizationMatrix";
}
return this.vertexQuantizationMatrix;
}
getUntransformedVertexQuantizationMatrix() {
if (this.untransformedVertexQuantizationMatrix == null) {
throw "Not found: untransformedVertexQuantizationMatrix";
}
return this.vertexQuantizationMatrix;
}
getTransformedInverseVertexQuantizationMatrix() {
if (this.inverseVertexQuantizationMatrix == null) {
throw "Not found: inverseVertexQuantizationMatrix";
}
return this.inverseVertexQuantizationMatrix;
}
generateUntransformedMatrices(uniqueModelId, boundsUntransformed) {
var matrix = mat4.create();
var scale = 32768;
// Scale the model to make sure all values fit within a 2-byte signed short
mat4.scale(matrix, matrix, vec3.fromValues(
scale / (boundsUntransformed.max.x - boundsUntransformed.min.x),
scale / (boundsUntransformed.max.y - boundsUntransformed.min.y),
scale / (boundsUntransformed.max.z - boundsUntransformed.min.z)
));
// Move the model with its center to the origin
mat4.translate(matrix, matrix, vec3.fromValues(
-(boundsUntransformed.max.x + boundsUntransformed.min.x) / 2,
-(boundsUntransformed.max.y + boundsUntransformed.min.y) / 2,
-(boundsUntransformed.max.z + boundsUntransformed.min.z) / 2
));
// Store the untransformed quantization matrix
this.untransformedQuantizationMatrices.set(uniqueModelId, Utils.toArray(matrix));
var inverse = mat4.create();
mat4.invert(inverse, matrix);
// Store the untransformed inverse quantization matrix
this.untransformedInverseQuantizationMatrices.set(uniqueModelId, Utils.toArray(inverse));
}
getTransformedQuantizationMatrix(boundsUntransformed) {
var matrix = mat4.create();
var scale = 32768;
// Scale the model to make sure all values fit within a 2-byte signed short
mat4.scale(matrix, matrix, vec3.fromValues(
scale / boundsUntransformed[3],
scale / boundsUntransformed[4],
scale / boundsUntransformed[5]
));
// Move the model with its center to the origin
mat4.translate(matrix, matrix, vec3.fromValues(
-(boundsUntransformed[3] / 2 + boundsUntransformed[0]),
-(boundsUntransformed[4] / 2 + boundsUntransformed[1]),
-(boundsUntransformed[5] / 2 + boundsUntransformed[2])
));
return matrix;
}
getTransformedInverseQuantizationMatrix(boundsUntransformed) {
var matrix = this.getTransformedQuantizationMatrix(boundsUntransformed);
var inverse = mat4.create();
mat4.invert(inverse, matrix);
return inverse;
}
generateMatrix(bounds, globalTranslationVector) {
var matrix = mat4.create();
var scale = 32768;
var min = vec3.fromValues(bounds.min.x, bounds.min.y, bounds.min.z);
var max = vec3.fromValues(bounds.max.x, bounds.max.y, bounds.max.z);
vec3.add(min, min, globalTranslationVector);
vec3.add(max, max, globalTranslationVector);
// Scale the model to make sure all values fit within a 2-byte signed short
mat4.scale(matrix, matrix, vec3.fromValues(
scale / (max[0] - min[0]),
scale / (max[1] - min[1]),
scale / (max[2] - min[2])
));
// Move the model with its center to the origin
mat4.translate(matrix, matrix, vec3.fromValues(
-(max[0] + min[0]) / 2,
-(max[1] + min[1]) / 2,
-(max[2] + min[2]) / 2
));
return matrix;
}
generateMatrices(totalBounds, totalBoundsUntransformed, globalTranslationVector) {
var matrix = this.generateMatrix(totalBounds, vec3.create());
var matrixWithGlobalTranslation = this.generateMatrix(totalBounds, globalTranslationVector);
this.vertexQuantizationMatrix = Utils.toArray(matrix);
this.vertexQuantizationMatrixWithGlobalTranslation = Utils.toArray(matrixWithGlobalTranslation);
var inverse = mat4.create();
mat4.invert(inverse, matrix);
this.inverseVertexQuantizationMatrix = Utils.toArray(inverse);
var inverse = mat4.create();
mat4.invert(inverse, matrixWithGlobalTranslation);
this.inverseVertexQuantizationMatrixWithGlobalTranslation = Utils.toArray(inverse);
var matrix = this.generateMatrix(totalBoundsUntransformed, vec3.create());
this.untransformedVertexQuantizationMatrix = Utils.toArray(matrix);
}
}