diff --git a/src/mol-geo/geometry/transform-data.ts b/src/mol-geo/geometry/transform-data.ts index 486400aa21a6a1f6f62e820df05d7855c87b667a..03e107a88ec684ae447cd1ec06d18a6d57ba26ef 100644 --- a/src/mol-geo/geometry/transform-data.ts +++ b/src/mol-geo/geometry/transform-data.ts @@ -42,15 +42,12 @@ export function createIdentityTransform(transformData?: TransformData): Transfor return createTransform(new Float32Array(identityTransform), 1, transformData) } -const tmpTransformMat4 = Mat4.identity() export function setTransformData(matrix: Mat4, transformData: TransformData) { const instanceCount = transformData.instanceCount.ref.value const transform = transformData.transform.ref.value const aTransform = transformData.aTransform.ref.value for (let i = 0; i < instanceCount; i++) { - Mat4.fromArray(tmpTransformMat4, transform, i * 16) - Mat4.mul(tmpTransformMat4, tmpTransformMat4, matrix) - Mat4.toArray(tmpTransformMat4, aTransform, i * 16) + Mat4.mulOffset(aTransform, transform, matrix, i * 16, i * 16, 0) } ValueCell.update(transformData.aTransform, aTransform) } \ No newline at end of file diff --git a/src/mol-gl/renderable/util.ts b/src/mol-gl/renderable/util.ts index c1bbdb345a195bbbdbc6eb62ffeaa6e109bce385..02e7cf29fc268e371204a36eba42a77472164a16 100644 --- a/src/mol-gl/renderable/util.ts +++ b/src/mol-gl/renderable/util.ts @@ -5,7 +5,7 @@ */ import { Sphere3D } from 'mol-math/geometry' -import { Mat4, Vec3 } from 'mol-math/linear-algebra' +import { Vec3 } from 'mol-math/linear-algebra' import { BoundaryHelper } from 'mol-math/geometry/boundary-helper'; export function calculateTextureInfo (n: number, itemSize: number) { @@ -36,7 +36,6 @@ export function createTextureImage(n: number, itemSize: number): TextureImage<Ui // -const m = Mat4.zero() const v = Vec3.zero() const boundaryHelper = new BoundaryHelper() @@ -58,12 +57,12 @@ export function calculateTransformBoundingSphere(invariantBoundingSphere: Sphere const { center, radius } = invariantBoundingSphere boundaryHelper.reset(0) for (let i = 0, _i = transformCount; i < _i; ++i) { - Vec3.transformMat4(v, center, Mat4.fromArray(m, transform, i * 16)) + Vec3.transformMat4Offset(v, center, transform, 0, 0, i * 16) boundaryHelper.boundaryStep(v, radius) } boundaryHelper.finishBoundaryStep() for (let i = 0, _i = transformCount; i < _i; ++i) { - Vec3.transformMat4(v, center, Mat4.fromArray(m, transform, i * 16)) + Vec3.transformMat4Offset(v, center, transform, 0, 0, i * 16) boundaryHelper.extendStep(v, radius) } return boundaryHelper.getSphere() diff --git a/src/mol-math/linear-algebra/3d/mat4.ts b/src/mol-math/linear-algebra/3d/mat4.ts index 482fc13e90157e145f8fd017cb054d465fa1935f..be275d960bf494d3937f4537d666336ddeed7d7a 100644 --- a/src/mol-math/linear-algebra/3d/mat4.ts +++ b/src/mol-math/linear-algebra/3d/mat4.ts @@ -367,6 +367,42 @@ namespace Mat4 { return out; } + /** + * Like `mul` but with offsets into arrays + */ + export function mulOffset(out: Helpers.NumberArray, a: Helpers.NumberArray, b: Helpers.NumberArray, oOut: number, oA: number, oB: number) { + const a00 = a[0 + oA], a01 = a[1 + oA], a02 = a[2 + oA], a03 = a[3 + oA], + a10 = a[4 + oA], a11 = a[5 + oA], a12 = a[6 + oA], a13 = a[7 + oA], + a20 = a[8 + oA], a21 = a[9 + oA], a22 = a[10 + oA], a23 = a[11 + oA], + a30 = a[12 + oA], a31 = a[13 + oA], a32 = a[14 + oA], a33 = a[15 + oA]; + + // Cache only the current line of the second matrix + let b0 = b[0 + oB], b1 = b[1 + oB], b2 = b[2 + oB], b3 = b[3 + oB]; + out[0 + oOut] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[1 + oOut] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[2 + oOut] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[3 + oOut] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + + b0 = b[4 + oB]; b1 = b[5 + oB]; b2 = b[6 + oB]; b3 = b[7 + oB]; + out[4 + oOut] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[5 + oOut] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[6 + oOut] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[7 + oOut] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + + b0 = b[8 + oB]; b1 = b[9 + oB]; b2 = b[10 + oB]; b3 = b[11 + oB]; + out[8 + oOut] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[9 + oOut] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[10 + oOut] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[11 + oOut] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + + b0 = b[12 + oB]; b1 = b[13 + oB]; b2 = b[14 + oB]; b3 = b[15 + oB]; + out[12 + oOut] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[13 + oOut] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[14 + oOut] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[15 + oOut] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + return out; + } + export function mul3(out: Mat4, a: Mat4, b: Mat4, c: Mat4) { return mul(out, mul(out, a, b), c); } diff --git a/src/mol-math/linear-algebra/3d/vec3.ts b/src/mol-math/linear-algebra/3d/vec3.ts index 55e6f7662eece83613b237245a79e05c3b3dd5fe..5a230ea9054ebe66f723285bd26e79f0897c92e6 100644 --- a/src/mol-math/linear-algebra/3d/vec3.ts +++ b/src/mol-math/linear-algebra/3d/vec3.ts @@ -369,6 +369,18 @@ namespace Vec3 { return out; } + /** + * Like `transformMat4` but with offsets into arrays + */ + export function transformMat4Offset(out: Helpers.NumberArray, a: Helpers.NumberArray, m: Helpers.NumberArray, outO: number, aO: number, oM: number) { + const x = a[0 + aO], y = a[1 + aO], z = a[2 + aO], + w = 1 / ((m[3 + oM] * x + m[7 + oM] * y + m[11 + oM] * z + m[15 + oM]) || 1.0); + out[0 + outO] = (m[0 + oM] * x + m[4 + oM] * y + m[8 + oM] * z + m[12 + oM]) * w; + out[1 + outO] = (m[1 + oM] * x + m[5 + oM] * y + m[9 + oM] * z + m[13 + oM]) * w; + out[2 + outO] = (m[2 + oM] * x + m[6 + oM] * y + m[10 + oM] * z + m[14 + oM]) * w; + return out; + } + /** * Transforms the Vec3 with a Mat3. */ diff --git a/src/mol-repr/visual.ts b/src/mol-repr/visual.ts index 51805957d731001be2fcdffd9e2e58b224fabec1..79a378b1e37e52edf72a728474f83a9c679d74f6 100644 --- a/src/mol-repr/visual.ts +++ b/src/mol-repr/visual.ts @@ -15,7 +15,6 @@ import { Theme } from 'mol-theme/theme'; import { Mat4 } from 'mol-math/linear-algebra'; import { setTransformData } from 'mol-geo/geometry/transform-data'; import { calculateTransformBoundingSphere } from 'mol-gl/renderable/util'; -import { Sphere3D } from 'mol-math/geometry'; import { ValueCell } from 'mol-util'; export interface VisualContext { @@ -53,9 +52,7 @@ namespace Visual { const { values } = renderObject setTransformData(value, values) const boundingSphere = calculateTransformBoundingSphere(values.invariantBoundingSphere.ref.value, values.aTransform.ref.value, values.instanceCount.ref.value) - if (!Sphere3D.equals(boundingSphere, values.boundingSphere.ref.value)) { - ValueCell.update(values.boundingSphere, boundingSphere) - } + ValueCell.update(values.boundingSphere, boundingSphere) } } } \ No newline at end of file