Ver Fonte

use boundary helper to calculate geometry bounding sphere

Alexander Rose há 6 anos atrás
pai
commit
9d730e95fb
1 ficheiros alterados com 28 adições e 61 exclusões
  1. 28 61
      src/mol-gl/renderable/util.ts

+ 28 - 61
src/mol-gl/renderable/util.ts

@@ -6,7 +6,7 @@
 
 import { Sphere3D } from 'mol-math/geometry'
 import { Mat4, Vec3 } from 'mol-math/linear-algebra'
-import { ValueCell } from 'mol-util';
+import { BoundaryHelper } from 'mol-math/geometry/boundary-helper';
 
 export function calculateTextureInfo (n: number, itemSize: number) {
     const sqN = Math.sqrt(n)
@@ -34,76 +34,43 @@ export function createTextureImage(n: number, itemSize: number): TextureImage<Ui
     return { array: new Uint8Array(length), width, height }
 }
 
-export interface PositionValues {
-    aPosition: ValueCell<Float32Array>
-    drawCount: ValueCell<number>,
-    aTransform: ValueCell<Float32Array>,
-    instanceCount: ValueCell<number>,
-}
-
-function getPositionDataFromValues(values: PositionValues) {
-    return {
-        position: values.aPosition.ref.value,
-        positionCount: values.drawCount.ref.value / 3 / 3,
-        transform: values.aTransform.ref.value,
-        transformCount: values.instanceCount.ref.value
-    }
-}
-
-export function calculateBoundingSphereFromValues(values: PositionValues) {
-    const { position, positionCount, transform, transformCount } = getPositionDataFromValues(values)
-    return calculateBoundingSphere(position, positionCount, transform, transformCount)
-}
-
-export function calculateBoundingSphere(position: Float32Array, positionCount: number, transform: Float32Array, transformCount: number): { boundingSphere: Sphere3D, invariantBoundingSphere: Sphere3D } {
+//
 
-    const m = Mat4.zero()
-
-    let cx = 0, cy = 0, cz = 0;
-    let radiusSq = 0;
+const m = Mat4.zero()
+const v = Vec3.zero()
+const boundaryHelper = new BoundaryHelper()
 
+export function calculateInvariantBoundingSphere(position: Float32Array, positionCount: number): Sphere3D {
+    boundaryHelper.reset(0)
     for (let i = 0, _i = positionCount * 3; i < _i; i += 3) {
-        cx += position[i];
-        cy += position[i + 1];
-        cz += position[i + 2];
-    }
-
-    if (positionCount > 0) {
-        cx /= positionCount;
-        cy /= positionCount;
-        cz /= positionCount;
+        Vec3.fromArray(v, position, i)
+        boundaryHelper.boundaryStep(v, 0)
     }
-
+    boundaryHelper.finishBoundaryStep()
     for (let i = 0, _i = positionCount * 3; i < _i; i += 3) {
-        const dx = position[i] - cx
-        const dy = position[i + 1] - cy
-        const dz = position[i + 2] - cz;
-        const d = dx * dx + dy * dy + dz * dz;
-        if (d > radiusSq) radiusSq = d;
+        Vec3.fromArray(v, position, i)
+        boundaryHelper.extendStep(v, 0)
     }
+    return boundaryHelper.getSphere()
+}
 
-    const c = Vec3.create(cx, cy, cz)
-    const ct = Vec3.zero()
-
-    const center = Vec3.zero()
-    const centers = new Float32Array(3 * transformCount)
-
+export function calculateTransformBoundingSphere(invariantBoundingSphere: Sphere3D, transform: Float32Array, transformCount: number): Sphere3D {
+    const { center, radius } = invariantBoundingSphere
+    boundaryHelper.reset(0)
     for (let i = 0, _i = transformCount; i < _i; ++i) {
-        Mat4.fromArray(m, transform, i * 16)
-        Vec3.transformMat4(ct, c, m)
-        Vec3.add(center, center, ct)
-        Vec3.toArray(ct, centers, i * 3)
+        Vec3.transformMat4(v, center, Mat4.fromArray(m, transform, i * 16))
+        boundaryHelper.boundaryStep(v, radius)
     }
-
-    Vec3.scale(center, center, 1 / transformCount)
-
-    let r = Math.sqrt(radiusSq)
-    let radius = r
-
+    boundaryHelper.finishBoundaryStep()
     for (let i = 0, _i = transformCount; i < _i; ++i) {
-        Vec3.fromArray(ct, centers, i * 3)
-        radius = Math.max(radius, Vec3.distance(center, ct) + r)
+        Vec3.transformMat4(v, center, Mat4.fromArray(m, transform, i * 16))
+        boundaryHelper.extendStep(v, radius)
     }
+    return boundaryHelper.getSphere()
+}
 
-    return { boundingSphere: { center, radius }, invariantBoundingSphere: { center: c, radius: r } };
+export function calculateBoundingSphere(position: Float32Array, positionCount: number, transform: Float32Array, transformCount: number): { boundingSphere: Sphere3D, invariantBoundingSphere: Sphere3D } {
+    const invariantBoundingSphere = calculateInvariantBoundingSphere(position, positionCount)
+    const boundingSphere = calculateTransformBoundingSphere(invariantBoundingSphere, transform, transformCount)
+    return { boundingSphere, invariantBoundingSphere }
 }