|
@@ -26,6 +26,9 @@ import { Pose } from './pose';
|
26
|
26
|
import { ViewerPose } from './viewer-pose';
|
27
|
27
|
import { View, PerspectiveView } from './view';
|
28
|
28
|
import { Transform } from './transform';
|
|
29
|
+import { Vector2 } from './vector2';
|
|
30
|
+import { Vector3 } from './vector3';
|
|
31
|
+import { Ray } from './ray';
|
29
|
32
|
|
30
|
33
|
|
31
|
34
|
|
|
@@ -98,4 +101,39 @@ export class Viewer
|
98
|
101
|
const transform = new Transform(modelViewMatrix);
|
99
|
102
|
return new Pose(transform);
|
100
|
103
|
}
|
|
104
|
+
|
|
105
|
+ /**
|
|
106
|
+ * Cast a ray from a point in the image space associated with this Viewer
|
|
107
|
+ * @param position a point in image space, given in normalized units [-1,1]x[-1,1]
|
|
108
|
+ * @returns a ray in world space that corresponds to the given point
|
|
109
|
+ */
|
|
110
|
+ raycast(position: Vector2): Ray
|
|
111
|
+ {
|
|
112
|
+ const projectionMatrixInverse = this.view._projectionMatrixInverse;
|
|
113
|
+ const viewMatrixInverse = this._pose.transform.matrix;
|
|
114
|
+ const pointInClipSpace = Speedy.Matrix(4, 1, [
|
|
115
|
+ // Normalized Device Coordinates (NDC)
|
|
116
|
+ position.x,
|
|
117
|
+ position.y,
|
|
118
|
+ 0, // (*)
|
|
119
|
+ 1 // homogeneous coordinates
|
|
120
|
+ ]);
|
|
121
|
+
|
|
122
|
+ const pointInViewSpace = projectionMatrixInverse.times(pointInClipSpace);
|
|
123
|
+ const pointInWorldSpace = viewMatrixInverse.times(pointInViewSpace);
|
|
124
|
+ const p = Speedy.Matrix(pointInWorldSpace).read();
|
|
125
|
+
|
|
126
|
+ /*
|
|
127
|
+
|
|
128
|
+ (*) since we're just interested in the direction, any z coordinate in
|
|
129
|
+ clip space [-1,1] will give us a suitable point p in world space.
|
|
130
|
+
|
|
131
|
+ */
|
|
132
|
+
|
|
133
|
+ const origin = this._pose.transform.position;
|
|
134
|
+ const direction = new Vector3(p[0] / p[3], p[1] / p[3], p[2] / p[3])
|
|
135
|
+ ._subtract(origin)._normalize();
|
|
136
|
+
|
|
137
|
+ return new Ray(origin, direction);
|
|
138
|
+ }
|
101
|
139
|
}
|