Bladeren bron

vec3 improvements, .matchDirection & readonly .negUnit

Alexander Rose 5 jaren geleden
bovenliggende
commit
14623f5df2

+ 1 - 2
src/mol-geo/geometry/mesh/builder/cylinder.ts

@@ -26,8 +26,7 @@ function setCylinderMat(m: Mat4, start: Vec3, dir: Vec3, length: number) {
     Vec3.add(tmpCylinderCenter, start, tmpCylinderMatDir)
     // ensure the direction used to create the rotation is always pointing in the same
     // direction so the triangles of adjacent cylinder will line up
-    Vec3.copy(tmpUp, up)
-    if (Vec3.dot(tmpCylinderMatDir, tmpUp) < 0) Vec3.scale(tmpUp, tmpUp, -1)
+    Vec3.matchDirection(tmpUp, up, tmpCylinderMatDir)
     Vec3.makeRotation(m, tmpUp, tmpCylinderMatDir)
     return Mat4.setTranslation(m, tmpCylinderCenter)
 }

+ 1 - 1
src/mol-math/linear-algebra/3d/mat4.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>

+ 16 - 3
src/mol-math/linear-algebra/3d/vec3.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -23,6 +23,7 @@ import { spline as _spline, quadraticBezier as _quadraticBezier, clamp } from '.
 import { NumberArray } from '../../../mol-util/type-helpers';
 
 interface Vec3 extends Array<number> { [d: number]: number, '@type': 'vec3', length: 3 }
+interface ReadonlyVec3 extends Array<number> { readonly [d: number]: number, '@type': 'vec3', length: 3 }
 
 function Vec3() {
     return Vec3.zero();
@@ -497,13 +498,12 @@ namespace Vec3 {
     }
 
     const rotTemp = zero();
-    const flipScaling = create(-1, -1, -1);
     export function makeRotation(mat: Mat4, a: Vec3, b: Vec3): Mat4 {
         const by = angle(a, b);
         if (Math.abs(by) < 0.0001) return Mat4.setIdentity(mat);
         if (Math.abs(by - Math.PI) < EPSILON) {
             // here, axis can be [0,0,0] but the rotation is a simple flip
-            return Mat4.fromScaling(mat, flipScaling);
+            return Mat4.fromScaling(mat, negUnit);
         }
         const axis = cross(rotTemp, a, b);
         return Mat4.fromRotation(mat, by, axis);
@@ -525,6 +525,16 @@ namespace Vec3 {
         return normalize(out, cross(out, cross(out, a, b), a));
     }
 
+    /**
+     * Get a vector like `a` that point into the same general direction as `b`,
+     * i.e. where the dot product is > 0
+     */
+    export function matchDirection(out: Vec3, a: Vec3, b: Vec3) {
+        if (Vec3.dot(a, b) > 0) Vec3.copy(out, a)
+        else Vec3.negate(out, Vec3.copy(out, a))
+        return out
+    }
+
     const triangleNormalTmpAB = zero();
     const triangleNormalTmpAC = zero();
     /** Calculate normal for the triangle defined by `a`, `b` and `c` */
@@ -537,6 +547,9 @@ namespace Vec3 {
     export function toString(a: Vec3, precision?: number) {
         return `[${a[0].toPrecision(precision)} ${a[1].toPrecision(precision)} ${a[2].toPrecision(precision)}]`;
     }
+
+    export const unit: ReadonlyVec3 = Vec3.create(1, 1, 1)
+    export const negUnit: ReadonlyVec3 = Vec3.create(-1, -1, -1)
 }
 
 export default Vec3

+ 1 - 4
src/mol-repr/structure/visual/util/polymer/curve-segment.ts

@@ -100,10 +100,7 @@ export function interpolateNormals(state: CurveSegmentState, controls: CurveSegm
 
     Vec3.orthogonalize(firstNormalVec, firstTangentVec, firstDirection)
     Vec3.orthogonalize(lastNormalVec, lastTangentVec, lastDirection)
-
-    if (Vec3.dot(firstNormalVec, lastNormalVec) < 0) {
-        Vec3.scale(lastNormalVec, lastNormalVec, -1)
-    }
+    Vec3.matchDirection(lastNormalVec, lastNormalVec, firstNormalVec)
 
     Vec3.copy(prevNormal, firstNormalVec)
 

+ 2 - 4
src/mol-repr/structure/visual/util/polymer/trace-iterator.ts

@@ -171,10 +171,8 @@ export class AtomicPolymerTraceIterator implements Iterator<PolymerTraceElement>
     }
 
     private setDirection(out: Vec3, v1: Vec3, v2: Vec3, v3: Vec3) {
-        Vec3.copy(tmpVecA, v1)
-        Vec3.copy(tmpVecB, v3)
-        if (Vec3.dot(v2, tmpVecA) < 0) Vec3.scale(tmpVecA, tmpVecA, -1)
-        if (Vec3.dot(v2, tmpVecB) < 0) Vec3.scale(tmpVecB, tmpVecB, -1)
+        Vec3.matchDirection(tmpVecA, v1, v2)
+        Vec3.matchDirection(tmpVecB, v3, v2)
         Vec3.scale(out, Vec3.add(out, tmpVecA, Vec3.add(out, tmpVecB, Vec3.add(out, v2, v2))), 1/4)
     }