|
@@ -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 }
|
|
|
}
|