@@ -122,6 +122,9 @@ impl Default for DepthCalculation {
122
122
123
123
impl Camera {
124
124
/// Given a position in world space, use the camera to compute the screen space coordinates.
125
+ ///
126
+ /// To get the coordinates in Normalized Device Coordinates, you should use
127
+ /// [`world_to_ndc`](Self::world_to_ndc).
125
128
pub fn world_to_screen (
126
129
& self ,
127
130
windows : & Windows ,
@@ -130,18 +133,33 @@ impl Camera {
130
133
world_position : Vec3 ,
131
134
) -> Option < Vec2 > {
132
135
let window_size = self . target . get_logical_size ( windows, images) ?;
133
- // Build a transform to convert from world to NDC using camera data
134
- let world_to_ndc: Mat4 =
135
- self . projection_matrix * camera_transform. compute_matrix ( ) . inverse ( ) ;
136
- let ndc_space_coords: Vec3 = world_to_ndc. project_point3 ( world_position) ;
136
+ let ndc_space_coords = self . world_to_ndc ( camera_transform, world_position) ?;
137
137
// NDC z-values outside of 0 < z < 1 are outside the camera frustum and are thus not in screen space
138
138
if ndc_space_coords. z < 0.0 || ndc_space_coords. z > 1.0 {
139
139
return None ;
140
140
}
141
+
141
142
// Once in NDC space, we can discard the z element and rescale x/y to fit the screen
142
- let screen_space_coords = ( ndc_space_coords. truncate ( ) + Vec2 :: ONE ) / 2.0 * window_size;
143
- if !screen_space_coords. is_nan ( ) {
144
- Some ( screen_space_coords)
143
+ Some ( ( ndc_space_coords. truncate ( ) + Vec2 :: ONE ) / 2.0 * window_size)
144
+ }
145
+
146
+ /// Given a position in world space, use the camera to compute the Normalized Device Coordinates.
147
+ ///
148
+ /// Values returned will be between -1.0 and 1.0 when the position is in screen space.
149
+ /// To get the coordinates in the render target dimensions, you should use
150
+ /// [`world_to_screen`](Self::world_to_screen).
151
+ pub fn world_to_ndc (
152
+ & self ,
153
+ camera_transform : & GlobalTransform ,
154
+ world_position : Vec3 ,
155
+ ) -> Option < Vec3 > {
156
+ // Build a transform to convert from world to NDC using camera data
157
+ let world_to_ndc: Mat4 =
158
+ self . projection_matrix * camera_transform. compute_matrix ( ) . inverse ( ) ;
159
+ let ndc_space_coords: Vec3 = world_to_ndc. project_point3 ( world_position) ;
160
+
161
+ if !ndc_space_coords. is_nan ( ) {
162
+ Some ( ndc_space_coords)
145
163
} else {
146
164
None
147
165
}
0 commit comments