Kaynağa Gözat

wip, use EPOS for boundary calculation

Alexander Rose 5 yıl önce
ebeveyn
işleme
969a70d571

+ 13 - 14
src/mol-gl/renderable/util.ts

@@ -6,8 +6,7 @@
 
 import { Sphere3D } from '../../mol-math/geometry'
 import { Vec3 } from '../../mol-math/linear-algebra'
-import { BoundaryHelper } from '../../mol-math/geometry/boundary-helper';
-import { Epos14 } from '../../mol-math/geometry/epos-helper';
+import { Epos14, Epos98 } from '../../mol-math/geometry/epos-helper';
 
 export function calculateTextureInfo (n: number, itemSize: number) {
     const sqN = Math.sqrt(n)
@@ -79,37 +78,37 @@ export function printImageData(imageData: ImageData, scale = 1, pixelated = fals
 //
 
 const v = Vec3.zero()
-const boundaryHelper = new BoundaryHelper()
-const eposHelper = Epos14()
+const eposHelper14 = Epos14()
+const eposHelper98 = Epos98()
 
 export function calculateInvariantBoundingSphere(position: Float32Array, positionCount: number, stepFactor: number): Sphere3D {
     const step = stepFactor * 3
-    eposHelper.reset()
+    eposHelper14.reset()
     for (let i = 0, _i = positionCount * 3; i < _i; i += step) {
         Vec3.fromArray(v, position, i)
-        eposHelper.includeStep(v)
+        eposHelper14.includeStep(v)
     }
-    eposHelper.finishedIncludeStep()
+    eposHelper14.finishedIncludeStep()
     for (let i = 0, _i = positionCount * 3; i < _i; i += step) {
         Vec3.fromArray(v, position, i)
-        eposHelper.radiusStep(v)
+        eposHelper14.radiusStep(v)
     }
-    return eposHelper.getSphere()
+    return eposHelper14.getSphere()
 }
 
 export function calculateTransformBoundingSphere(invariantBoundingSphere: Sphere3D, transform: Float32Array, transformCount: number): Sphere3D {
     const { center, radius } = invariantBoundingSphere
-    boundaryHelper.reset(0)
+    eposHelper98.reset()
     for (let i = 0, _i = transformCount; i < _i; ++i) {
         Vec3.transformMat4Offset(v, center, transform, 0, 0, i * 16)
-        boundaryHelper.boundaryStep(v, radius)
+        eposHelper98.includeStep(v)
     }
-    boundaryHelper.finishBoundaryStep()
+    eposHelper98.finishedIncludeStep()
     for (let i = 0, _i = transformCount; i < _i; ++i) {
         Vec3.transformMat4Offset(v, center, transform, 0, 0, i * 16)
-        boundaryHelper.extendStep(v, radius)
+        eposHelper98.paddedRadiusStep(v, radius)
     }
-    return boundaryHelper.getSphere()
+    return eposHelper98.getSphere()
 }
 
 export function calculateBoundingSphere(position: Float32Array, positionCount: number, transform: Float32Array, transformCount: number, padding = 0, stepFactor = 1): { boundingSphere: Sphere3D, invariantBoundingSphere: Sphere3D } {

+ 8 - 11
src/mol-gl/scene.ts

@@ -11,32 +11,29 @@ import { RenderableValues, BaseValues } from './renderable/schema';
 import { GraphicsRenderObject, createRenderable } from './render-object';
 import { Object3D } from './object3d';
 import { Sphere3D } from '../mol-math/geometry';
-import { Vec3 } from '../mol-math/linear-algebra';
-import { BoundaryHelper } from '../mol-math/geometry/boundary-helper';
 import { CommitQueue } from './commit-queue';
 import { now } from '../mol-util/now';
 import { arraySetRemove } from '../mol-util/array';
+import { Epos98 } from '../mol-math/geometry/epos-helper';
+
+const eposHelper98 = Epos98()
 
-const boundaryHelper = new BoundaryHelper();
 function calculateBoundingSphere(renderables: Renderable<RenderableValues & BaseValues>[], boundingSphere: Sphere3D): Sphere3D {
-    boundaryHelper.reset(0.1);
+    eposHelper98.reset();
 
     for (let i = 0, il = renderables.length; i < il; ++i) {
         const boundingSphere = renderables[i].values.boundingSphere.ref.value
         if (!boundingSphere.radius) continue;
-        boundaryHelper.boundaryStep(boundingSphere.center, boundingSphere.radius);
+        eposHelper98.includeStep(boundingSphere.center);
     }
-    boundaryHelper.finishBoundaryStep();
+    eposHelper98.finishedIncludeStep();
     for (let i = 0, il = renderables.length; i < il; ++i) {
         const boundingSphere = renderables[i].values.boundingSphere.ref.value
         if (!boundingSphere.radius) continue;
-        boundaryHelper.extendStep(boundingSphere.center, boundingSphere.radius);
+        eposHelper98.paddedRadiusStep(boundingSphere.center, boundingSphere.radius);
     }
 
-    Vec3.copy(boundingSphere.center, boundaryHelper.center);
-    boundingSphere.radius = boundaryHelper.radius;
-
-    return boundingSphere;
+    return eposHelper98.getSphere(boundingSphere);
 }
 
 function renderableSort(a: Renderable<RenderableValues & BaseValues>, b: Renderable<RenderableValues & BaseValues>) {

+ 12 - 2
src/mol-math/geometry/centroid-helper.ts

@@ -37,8 +37,18 @@ class CentroidHelper {
         if (d > this.radiusSq) this.radiusSq = d;
     }
 
-    getSphere(): Sphere3D {
-        return { center: Vec3.clone(this.center), radius: Math.sqrt(this.radiusSq) };
+    paddedRadiusStep(p: Vec3, padding: number) {
+        // TODO take existing radius into account
+        const _d = Vec3.distance(p, this.center) + padding;
+        const d = _d * _d;
+        if (d > this.radiusSq) this.radiusSq = d;
+    }
+
+    getSphere(sphere?: Sphere3D): Sphere3D {
+        if (!sphere) sphere = Sphere3D()
+        Vec3.copy(sphere.center, this.center)
+        sphere.radius = Math.sqrt(this.radiusSq)
+        return sphere
     }
 
     constructor() {

+ 52 - 10
src/mol-math/geometry/epos-helper.ts

@@ -6,10 +6,13 @@
 
 import { Vec3 } from '../linear-algebra/3d';
 import { CentroidHelper } from './centroid-helper';
+import { Sphere3D } from '../geometry';
 
 // implementing http://www.ep.liu.se/ecp/034/009/ecp083409.pdf
 
 export class EposHelper {
+    private dir: Vec3[]
+
     private minDist: number[] = []
     private maxDist: number[] = []
     private extrema: Vec3[] = []
@@ -45,8 +48,12 @@ export class EposHelper {
         this.centroidHelper.radiusStep(p);
     }
 
-    getSphere() {
-        return this.centroidHelper.getSphere();
+    paddedRadiusStep(p: Vec3, padding: number) {
+        this.centroidHelper.paddedRadiusStep(p, padding);
+    }
+
+    getSphere(sphere?: Sphere3D) {
+        return this.centroidHelper.getSphere(sphere);
     }
 
     reset() {
@@ -59,23 +66,58 @@ export class EposHelper {
         this.centroidHelper.reset()
     }
 
-    constructor(private dir: Vec3[]) {
+    constructor(dir: number[][]) {
+        this.dir = dir.map(a => {
+            const v = Vec3.create(a[0], a[1], a[2])
+            return Vec3.normalize(v, v)
+        })
         this.reset()
     }
 }
 
-const DirEpos6 = [
-    Vec3.create(1, 0, 0), Vec3.create(0, 1, 0), Vec3.create(0, 0, 1)
+const Type001 = [
+    [1, 0, 0], [0, 1, 0], [0, 0, 1]
+]
+
+const Type111 = [
+    [1, 1, 1], [-1, 1, 1], [-1, -1, 1], [1, -1, 1]
 ]
+
+const Type011 = [
+    [1, 1, 0], [1, -1, 0], [1, 0, 1], [1, 0, -1], [0, 1, 1], [0, 1, -1]
+]
+
+const Type012 = [
+    [0, 1, 2], [0, 2, 1], [1, 0, 2], [2, 0, 1], [1, 2, 0], [2, 1, 0],
+    [0, 1, -2], [0, 2, -1], [1, 0, -2], [2, 0, -1], [1, -2, 0], [2, -1, 0]
+]
+
+const Type112 = [
+    [1, 1, 2], [2, 1, 1], [1, 2, 1], [1, -1, 2], [1, 1, -2], [1, -1, -2],
+    [2, -1, 1], [2, 1, -1], [2, -1, -1], [1, -2, 1], [1, 2, -1], [1, -2, -1]
+]
+
+const Type122 = [
+    [2, 2, 1], [1, 2, 2], [2, 1, 2], [2, -2, 1], [2, 2, -1], [2, -2, -1],
+    [1, -2, 2], [1, 2, -2], [1, -2, -2], [2, -1, 2], [2, 1, -2], [2, -1, -2]
+]
+
+const DirEpos6 = [ ...Type001 ]
 export function Epos6() {
     return new EposHelper(DirEpos6)
 }
 
-const DirEpos14 = [
-    Vec3.create(1, 0, 0), Vec3.create(0, 1, 0), Vec3.create(0, 0, 1),
-    Vec3.create(1/3, 1/3, 1/3), Vec3.create(-1/3, 1/3, 1/3),
-    Vec3.create(-1/3, -1/3, 1/3), Vec3.create(1/3, -1/3, 1/3)
-]
+const DirEpos14 = [ ...Type001, ...Type111 ]
 export function Epos14() {
     return new EposHelper(DirEpos14)
+}
+
+const DirEpos26 = [ ...Type001, ...Type111, ...Type011 ]
+export function Epos26() {
+    return new EposHelper(DirEpos26)
+}
+
+const DirEpos98 = [ ...Type001, ...Type111, ...Type011, ...Type012, ...Type112, ...Type122 ]
+export function Epos98() {
+    return new EposHelper(DirEpos98)
 }