UNPKG

molstar

Version:

A comprehensive macromolecular library.

80 lines 4.23 kB
/** * 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