molstar
Version:
A comprehensive macromolecular library.
80 lines • 4.23 kB
JavaScript
/**
* Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { ValueCell } from '../../mol-util';
import { Mat4, Mat3 } from '../../mol-math/linear-algebra';
import { fillSerial } from '../../mol-util/array';
var _m3 = Mat3();
var _m4 = Mat4();
function checkReflection(transformArray, instanceCount) {
for (var i = 0; i < instanceCount; i++) {
Mat3.fromMat4(_m3, Mat4.fromArray(_m4, transformArray, i * 16));
if (Mat3.determinant(_m3) < 0)
return true;
}
return false;
}
export function createTransform(transformArray, instanceCount, transformData) {
var hasReflection = checkReflection(transformArray, instanceCount);
if (transformData) {
ValueCell.update(transformData.matrix, transformData.matrix.ref.value);
var transform = transformData.transform.ref.value.length >= instanceCount * 16 ? transformData.transform.ref.value : new Float32Array(instanceCount * 16);
transform.set(transformArray);
ValueCell.update(transformData.transform, transform);
ValueCell.updateIfChanged(transformData.uInstanceCount, instanceCount);
ValueCell.updateIfChanged(transformData.instanceCount, instanceCount);
var aTransform = transformData.aTransform.ref.value.length >= instanceCount * 16 ? transformData.aTransform.ref.value : new Float32Array(instanceCount * 16);
ValueCell.update(transformData.aTransform, aTransform);
// Note that this sets `extraTransform` to identity transforms
var extraTransform = transformData.extraTransform.ref.value.length >= instanceCount * 16 ? transformData.extraTransform.ref.value : new Float32Array(instanceCount * 16);
ValueCell.update(transformData.extraTransform, fillIdentityTransform(extraTransform, instanceCount));
var aInstance = transformData.aInstance.ref.value.length >= instanceCount ? transformData.aInstance.ref.value : new Float32Array(instanceCount);
ValueCell.update(transformData.aInstance, fillSerial(aInstance, instanceCount));
ValueCell.update(transformData.hasReflection, hasReflection);
}
else {
transformData = {
aTransform: ValueCell.create(new Float32Array(instanceCount * 16)),
matrix: ValueCell.create(Mat4.identity()),
transform: ValueCell.create(new Float32Array(transformArray)),
extraTransform: ValueCell.create(fillIdentityTransform(new Float32Array(instanceCount * 16), instanceCount)),
uInstanceCount: ValueCell.create(instanceCount),
instanceCount: ValueCell.create(instanceCount),
aInstance: ValueCell.create(fillSerial(new Float32Array(instanceCount))),
hasReflection: ValueCell.create(hasReflection),
};
}
updateTransformData(transformData);
return transformData;
}
var identityTransform = new Float32Array(16);
Mat4.toArray(Mat4.identity(), identityTransform, 0);
export function createIdentityTransform(transformData) {
return createTransform(new Float32Array(identityTransform), 1, transformData);
}
export function fillIdentityTransform(transform, count) {
for (var i = 0; i < count; i++) {
transform.set(identityTransform, i * 16);
}
return transform;
}
/**
* updates per-instance transform calculated for instance `i` as
* `aTransform[i] = matrix * transform[i] * extraTransform[i]`
*/
export function updateTransformData(transformData) {
var aTransform = transformData.aTransform.ref.value;
var instanceCount = transformData.instanceCount.ref.value;
var matrix = transformData.matrix.ref.value;
var transform = transformData.transform.ref.value;
var extraTransform = transformData.extraTransform.ref.value;
for (var i = 0; i < instanceCount; i++) {
var i16 = i * 16;
Mat4.mulOffset(aTransform, extraTransform, transform, i16, i16, i16);
Mat4.mulOffset(aTransform, matrix, aTransform, i16, 0, i16);
}
ValueCell.update(transformData.aTransform, aTransform);
}
//# sourceMappingURL=transform-data.js.map