瀏覽代碼

Simplify Transform classes. Use a single class

customisations
alemart 10 月之前
父節點
當前提交
394cf3b765

+ 2
- 2
docs/api/pose.md 查看文件

@@ -6,6 +6,6 @@ A pose represents a position and an orientation in 3D space.
6 6
 
7 7
 ### transform
8 8
 
9
-`pose.transform: RigidTransform, read-only`
9
+`pose.transform: Transform, read-only`
10 10
 
11
-The underlying [rigid transform](rigid-transform.md).
11
+The underlying [transform](transform.md).

+ 0
- 17
docs/api/rigid-transform.md 查看文件

@@ -1,17 +0,0 @@
1
-# RigidTransform
2
-
3
-A RigidTransform represents a rotation and a translation in 3D space.
4
-
5
-## Properties
6
-
7
-### matrix
8
-
9
-`transform.matrix: SpeedyMatrix, read-only`
10
-
11
-A 4x4 matrix encoding the transform.
12
-
13
-### inverse
14
-
15
-`transform.inverse: RigidTransform, read-only`
16
-
17
-The inverse transform.

+ 17
- 0
docs/api/transform.md 查看文件

@@ -0,0 +1,17 @@
1
+# Transform
2
+
3
+A Transform represents a rotation and a translation in 3D space.
4
+
5
+## Properties
6
+
7
+### matrix
8
+
9
+`transform.matrix: SpeedyMatrix, read-only`
10
+
11
+A 4x4 matrix encoding the transform.
12
+
13
+### inverse
14
+
15
+`transform.inverse: Transform, read-only`
16
+
17
+The inverse transform.

+ 1
- 1
mkdocs.yml 查看文件

@@ -94,7 +94,7 @@ nav:
94 94
       - 'ViewerPose': 'api/viewer-pose.md'
95 95
       - 'View': 'api/view.md'
96 96
       - 'PerspectiveView': 'api/perspective-view.md'
97
-      - 'RigidTransform': 'api/rigid-transform.md'
97
+      - 'Transform': 'api/transform.md'
98 98
       - 'Quaternion': 'api/quaternion.md'
99 99
       - 'Vector3': 'api/vector3.md'
100 100
     - 'Visualization':

+ 8
- 11
src/geometry/pose.ts 查看文件

@@ -17,23 +17,20 @@
17 17
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18 18
  *
19 19
  * pose.ts
20
- * A pose represents a position and an orientation in a 3D space
20
+ * A pose represents a position and an orientation in 3D space
21 21
  */
22 22
 
23
-import Speedy from 'speedy-vision';
24
-import { SpeedyMatrix } from 'speedy-vision/types/core/speedy-matrix';
25
-import { RigidTransform, StandardTransform } from './transform';
23
+import { Transform } from './transform';
26 24
 
27 25
 
28 26
 
29 27
 /**
30
- * A pose represents a position and an orientation in a 3D space
31
- * (and sometimes a scale, too...)
28
+ * A pose represents a position and an orientation in 3D space
32 29
  */
33 30
 export class Pose
34 31
 {
35
-    /** A transform in 3D world space */
36
-    private _transform: StandardTransform;
32
+    /** Internal transform */
33
+    private _transform: Transform;
37 34
 
38 35
 
39 36
 
@@ -41,7 +38,7 @@ export class Pose
41 38
      * Constructor
42 39
      * @param transform usually a rigid transform in a 3D space (e.g., world space, viewer space or other)
43 40
      */
44
-    constructor(transform: StandardTransform)
41
+    constructor(transform: Transform)
45 42
     {
46 43
         this._transform = transform;
47 44
     }
@@ -50,8 +47,8 @@ export class Pose
50 47
      * A transform describing the position and the orientation
51 48
      * of the pose relative to the 3D space to which it belongs
52 49
      */
53
-    get transform(): StandardTransform
50
+    get transform(): Transform
54 51
     {
55 52
         return this._transform;
56 53
     }
57
-}
54
+}

+ 29
- 108
src/geometry/transform.ts 查看文件

@@ -17,160 +17,81 @@
17 17
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18 18
  *
19 19
  * transform.ts
20
- * 3D geometrical transforms
20
+ * 3D transforms
21 21
  */
22 22
 
23 23
 import Speedy from 'speedy-vision';
24 24
 import { SpeedyMatrix } from 'speedy-vision/types/core/speedy-matrix';
25
-import { IllegalArgumentError, IllegalOperationError } from '../utils/errors';
25
+import { Nullable } from '../utils/utils';
26
+import { IllegalArgumentError } from '../utils/errors';
27
+
26 28
 
27 29
 /**
28
- * A 3D transformation
30
+ * A Transform represents a position, a rotation and a scale in 3D space
29 31
  */
30
-abstract class BaseTransform
32
+export class Transform
31 33
 {
32
-    /** 4x4 matrix describing the transformation */
33
-    protected readonly _matrix: SpeedyMatrix;
34
+    /** transformation matrix */
35
+    private readonly _matrix: SpeedyMatrix;
36
+
37
+    /** inverse transform, computed lazily */
38
+    private _inverse: Nullable<Transform>;
34 39
 
35 40
 
36 41
 
37 42
     /**
38 43
      * Constructor
39
-     * @param matrix a 4x4 matrix
44
+     * @param matrix a 4x4 transformation matrix. You should ensure that its form is T * R * S (translation * rotation * scale).
40 45
      */
41 46
     constructor(matrix: SpeedyMatrix)
42 47
     {
43 48
         if(matrix.rows != 4 || matrix.columns != 4)
44
-            throw new IllegalArgumentError('A 3D transform expects a 4x4 matrix');
49
+            throw new IllegalArgumentError('A Transform expects a 4x4 transformation matrix');
45 50
 
46 51
         this._matrix = matrix;
52
+        this._inverse = null;
47 53
     }
48 54
 
49 55
     /**
50
-     * The 4x4 transformation matrix (read-only)
56
+     * The 4x4 transformation matrix
51 57
      */
52 58
     get matrix(): SpeedyMatrix
53 59
     {
54 60
         return this._matrix;
55 61
     }
56
-}
57 62
 
58
-/**
59
- * An invertible 3D transformation
60
- */
61
-class InvertibleTransform extends BaseTransform
62
-{
63 63
     /**
64
-     * Constructor
65
-     * @param matrix a 4x4 matrix
64
+     * The inverse transform
66 65
      */
67
-    constructor(matrix: SpeedyMatrix)
66
+    get inverse(): Transform
68 67
     {
69
-        // WARNING: we do not check if the matrix actually encodes an invertible transform!
70
-        super(matrix);
71
-    }
68
+        if(this._inverse === null)
69
+            this._inverse = new Transform(Transform._invert(this._matrix));
72 70
 
73
-    /**
74
-     * The inverse of the transform
75
-     */
76
-    get inverse(): InvertibleTransform
77
-    {
78
-        const inverseMatrix = Speedy.Matrix(this._matrix.inverse());
79
-        return new InvertibleTransform(inverseMatrix);
71
+        return this._inverse;
80 72
     }
81
-}
82
-
83
-/**
84
- * A 3D transformation described by translation, rotation and scale
85
- */
86
-export class StandardTransform extends InvertibleTransform
87
-{
88
-    // TODO: position, rotation and scale attributes
89 73
 
90 74
     /**
91
-     * Constructor
92
-     * @param matrix a 4x4 matrix
75
+     * Compute the inverse of a transformation matrix
76
+     * @param matrix the transformation matrix to invert
77
+     * @returns the inverse matrix
93 78
      */
94
-    constructor(matrix: SpeedyMatrix)
95
-    {
96
-        // WARNING: we do not check if the matrix actually encodes a standard transform!
97
-        super(matrix);
98
-    }
99
-
100
-    /**
101
-     * The inverse of the transform
102
-     */
103
-    get inverse(): StandardTransform
79
+    private static _invert(matrix: SpeedyMatrix): SpeedyMatrix
104 80
     {
105 81
         /*
106 82
 
107
-        The inverse of a 4x4 standard transform T * R * S...
83
+        The inverse of a 4x4 transform T * R * S
108 84
 
109 85
         [  RS  t  ]    is    [  ZR' -ZR't ]
110 86
         [  0'  1  ]          [  0'    1   ]
111 87
 
112 88
         where S is 3x3, R is 3x3, t is 3x1, 0' is 1x3 and Z is the inverse of S
113 89
 
114
-        */
115
-
116
-        return super.inverse as StandardTransform;
117
-    }
118
-}
119
-
120
-/**
121
- * A 3D transformation described by position and orientation
122
- */
123
-export class RigidTransform extends StandardTransform
124
-{
125
-    // TODO: position and rotation attributes (need to decompose the matrix)
126
-
127
-    /**
128
-     * Constructor
129
-     * @param matrix a 4x4 matrix
130
-     */
131
-    constructor(matrix: SpeedyMatrix)
132
-    {
133
-        // WARNING: we do not check if the matrix actually encodes a rigid transform!
134
-        super(matrix);
135
-    }
136
-
137
-    /**
138
-     * The inverse of the transform
139
-     */
140
-    get inverse(): RigidTransform
141
-    {
142
-        /*
143
-
144
-        The inverse of a 4x4 rigid transform
145
-
146
-        [  R   t  ]    is    [  R'  -R't  ]
147
-        [  0'  1  ]          [  0'    1   ]
148
-
149
-        where R is 3x3, t is 3x1 and 0' is 1x3
90
+        R is a rotation matrix; S is a diagonal matrix
150 91
 
151 92
         */
152 93
 
153
-        const m = this._matrix.read();
154
-        if(m[15] == 0) // error? abs()??
155
-            throw new IllegalOperationError('Not a rigid transform');
156
-        const s = 1 / m[15]; // should be 1 (normalize homogeneous coordinates)
157
-
158
-        const r11 = m[0] * s, r12 = m[4] * s, r13 = m[8] * s;
159
-        const r21 = m[1] * s, r22 = m[5] * s, r23 = m[9] * s;
160
-        const r31 = m[2] * s, r32 = m[6] * s, r33 = m[10] * s;
161
-        const t1 = m[12] * s, t2 = m[13] * s, t3 = m[14] * s;
162
-
163
-        const rt1 = r11 * t1 + r21 * t2 + r31 * t3;
164
-        const rt2 = r12 * t1 + r22 * t2 + r32 * t3;
165
-        const rt3 = r13 * t1 + r23 * t2 + r33 * t3;
166
-
167
-        const inverseMatrix = Speedy.Matrix(4, 4, [
168
-            r11, r12, r13, 0,
169
-            r21, r22, r23, 0,
170
-            r31, r32, r33, 0,
171
-            -rt1, -rt2, -rt3, 1
172
-        ]);
173
-
174
-        return new RigidTransform(inverseMatrix);
94
+        // this works, but this inverse is straightforward
95
+        return Speedy.Matrix(matrix.inverse());
175 96
     }
176
-}
97
+}

+ 5
- 4
src/geometry/viewer-pose.ts 查看文件

@@ -23,7 +23,7 @@
23 23
 import Speedy from 'speedy-vision';
24 24
 import { SpeedyMatrix } from 'speedy-vision/types/core/speedy-matrix';
25 25
 import { Pose } from './pose';
26
-import { RigidTransform } from './transform';
26
+import { Transform } from './transform';
27 27
 import { CameraModel } from './camera-model';
28 28
 
29 29
 
@@ -46,14 +46,15 @@ export class ViewerPose extends Pose
46 46
     {
47 47
         // compute the view matrix and its inverse in AR screen space
48 48
         const viewMatrix = ViewerPose._computeViewMatrix(camera);
49
-        const inverseTransform = new RigidTransform(viewMatrix);
49
+        const inverseTransform = new Transform(viewMatrix); // from world space to view space
50
+        const transform = inverseTransform.inverse; // from view space to world space
50 51
 
51
-        super(inverseTransform.inverse);
52
+        super(transform);
52 53
         this._viewMatrix = viewMatrix;
53 54
     }
54 55
 
55 56
     /**
56
-     * This 4x4 matrix moves 3D points from world space to viewer space. We
57
+     * This 4x4 matrix moves 3D points from world space to view space. We
57 58
      * assume that the camera is looking in the direction of the negative
58 59
      * z-axis (WebGL-friendly)
59 60
      */

+ 2
- 4
src/geometry/viewer.ts 查看文件

@@ -21,13 +21,11 @@
21 21
  */
22 22
 
23 23
 import Speedy from 'speedy-vision';
24
-import { SpeedyMatrix } from 'speedy-vision/types/core/speedy-matrix';
25 24
 import { CameraModel } from './camera-model';
26 25
 import { Pose } from './pose';
27 26
 import { ViewerPose } from './viewer-pose';
28 27
 import { View, PerspectiveView } from './view';
29
-import { StandardTransform } from './transform';
30
-import { IllegalOperationError } from '../utils/errors';
28
+import { Transform } from './transform';
31 29
 
32 30
 
33 31
 
@@ -97,7 +95,7 @@ export class Viewer
97 95
         const viewMatrix = this._pose.viewMatrix;
98 96
         const modelViewMatrix = Speedy.Matrix(viewMatrix.times(modelMatrix));
99 97
 
100
-        const transform = new StandardTransform(modelViewMatrix);
98
+        const transform = new Transform(modelViewMatrix);
101 99
         return new Pose(transform);
102 100
     }
103 101
 }

+ 2
- 2
src/trackers/image-tracker/states/tracking.ts 查看文件

@@ -46,7 +46,7 @@ import { ReferenceImage } from '../reference-image';
46 46
 import { CameraModel } from '../../../geometry/camera-model';
47 47
 import { Viewer } from '../../../geometry/viewer';
48 48
 import { Pose } from '../../../geometry/pose';
49
-import { RigidTransform, StandardTransform } from '../../../geometry/transform';
49
+import { Transform } from '../../../geometry/transform';
50 50
 import { IllegalOperationError, IllegalArgumentError, TrackingError } from '../../../utils/errors';
51 51
 import {
52 52
     TRACK_RECTIFIED_BORDER, TRACK_CLIPPING_BORDER, TRACK_MIN_MATCHES, TRACK_LOST_TOLERANCE,
@@ -386,7 +386,7 @@ export class ImageTrackerTrackingState extends ImageTrackerState
386 386
             // (identity transform). We also perform a change of coordinates,
387 387
             // so that we move out from pixel space and into normalized space
388 388
             const modelMatrix = this._camera.denormalizer(); // ~ "identity matrix"
389
-            const transform = new StandardTransform(modelMatrix);
389
+            const transform = new Transform(modelMatrix);
390 390
             const pose = new Pose(transform);
391 391
 
392 392
             // given the current state of the camera model, we get a viewer

Loading…
取消
儲存