浏览代码

Simplify Transform classes. Use a single class

customisations
alemart 10 个月前
父节点
当前提交
394cf3b765

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

6
 
6
 
7
 ### transform
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
-# 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 查看文件

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
       - 'ViewerPose': 'api/viewer-pose.md'
94
       - 'ViewerPose': 'api/viewer-pose.md'
95
       - 'View': 'api/view.md'
95
       - 'View': 'api/view.md'
96
       - 'PerspectiveView': 'api/perspective-view.md'
96
       - 'PerspectiveView': 'api/perspective-view.md'
97
-      - 'RigidTransform': 'api/rigid-transform.md'
97
+      - 'Transform': 'api/transform.md'
98
       - 'Quaternion': 'api/quaternion.md'
98
       - 'Quaternion': 'api/quaternion.md'
99
       - 'Vector3': 'api/vector3.md'
99
       - 'Vector3': 'api/vector3.md'
100
     - 'Visualization':
100
     - 'Visualization':

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

17
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
  *
18
  *
19
  * pose.ts
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
 export class Pose
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
      * Constructor
38
      * Constructor
42
      * @param transform usually a rigid transform in a 3D space (e.g., world space, viewer space or other)
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
         this._transform = transform;
43
         this._transform = transform;
47
     }
44
     }
50
      * A transform describing the position and the orientation
47
      * A transform describing the position and the orientation
51
      * of the pose relative to the 3D space to which it belongs
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
         return this._transform;
52
         return this._transform;
56
     }
53
     }
57
-}
54
+}

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

17
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
  *
18
  *
19
  * transform.ts
19
  * transform.ts
20
- * 3D geometrical transforms
20
+ * 3D transforms
21
  */
21
  */
22
 
22
 
23
 import Speedy from 'speedy-vision';
23
 import Speedy from 'speedy-vision';
24
 import { SpeedyMatrix } from 'speedy-vision/types/core/speedy-matrix';
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
      * Constructor
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
     constructor(matrix: SpeedyMatrix)
46
     constructor(matrix: SpeedyMatrix)
42
     {
47
     {
43
         if(matrix.rows != 4 || matrix.columns != 4)
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
         this._matrix = matrix;
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
     get matrix(): SpeedyMatrix
58
     get matrix(): SpeedyMatrix
53
     {
59
     {
54
         return this._matrix;
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
         [  RS  t  ]    is    [  ZR' -ZR't ]
85
         [  RS  t  ]    is    [  ZR' -ZR't ]
110
         [  0'  1  ]          [  0'    1   ]
86
         [  0'  1  ]          [  0'    1   ]
111
 
87
 
112
         where S is 3x3, R is 3x3, t is 3x1, 0' is 1x3 and Z is the inverse of S
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
 import Speedy from 'speedy-vision';
23
 import Speedy from 'speedy-vision';
24
 import { SpeedyMatrix } from 'speedy-vision/types/core/speedy-matrix';
24
 import { SpeedyMatrix } from 'speedy-vision/types/core/speedy-matrix';
25
 import { Pose } from './pose';
25
 import { Pose } from './pose';
26
-import { RigidTransform } from './transform';
26
+import { Transform } from './transform';
27
 import { CameraModel } from './camera-model';
27
 import { CameraModel } from './camera-model';
28
 
28
 
29
 
29
 
46
     {
46
     {
47
         // compute the view matrix and its inverse in AR screen space
47
         // compute the view matrix and its inverse in AR screen space
48
         const viewMatrix = ViewerPose._computeViewMatrix(camera);
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
         this._viewMatrix = viewMatrix;
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
      * assume that the camera is looking in the direction of the negative
58
      * assume that the camera is looking in the direction of the negative
58
      * z-axis (WebGL-friendly)
59
      * z-axis (WebGL-friendly)
59
      */
60
      */

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

21
  */
21
  */
22
 
22
 
23
 import Speedy from 'speedy-vision';
23
 import Speedy from 'speedy-vision';
24
-import { SpeedyMatrix } from 'speedy-vision/types/core/speedy-matrix';
25
 import { CameraModel } from './camera-model';
24
 import { CameraModel } from './camera-model';
26
 import { Pose } from './pose';
25
 import { Pose } from './pose';
27
 import { ViewerPose } from './viewer-pose';
26
 import { ViewerPose } from './viewer-pose';
28
 import { View, PerspectiveView } from './view';
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
         const viewMatrix = this._pose.viewMatrix;
95
         const viewMatrix = this._pose.viewMatrix;
98
         const modelViewMatrix = Speedy.Matrix(viewMatrix.times(modelMatrix));
96
         const modelViewMatrix = Speedy.Matrix(viewMatrix.times(modelMatrix));
99
 
97
 
100
-        const transform = new StandardTransform(modelViewMatrix);
98
+        const transform = new Transform(modelViewMatrix);
101
         return new Pose(transform);
99
         return new Pose(transform);
102
     }
100
     }
103
 }
101
 }

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

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

正在加载...
取消
保存