1
1
use crate :: {
2
2
collision_math:: Ray ,
3
- math,
4
- math:: MVector ,
3
+ math:: { MVector , PermuteXYZ } ,
5
4
node:: { ChunkLayout , VoxelAABB , VoxelData } ,
6
5
voxel_math:: Coords ,
7
6
world:: Material ,
@@ -91,8 +90,9 @@ fn find_face_collision(
91
90
for t in bounding_box. grid_planes ( t_axis) {
92
91
// Find a normal to the grid plane. Note that (t, 0, 0, x) is a normal of the plane whose closest point
93
92
// to the origin is (x, 0, 0, t), and we use that fact here.
94
- let normal = math:: tuv_to_xyz ( t_axis, MVector :: new ( 1.0 , 0.0 , 0.0 , layout. grid_to_dual ( t) ) )
95
- . normalized ( ) ;
93
+ let normal = MVector :: new ( 1.0 , 0.0 , 0.0 , layout. grid_to_dual ( t) )
94
+ . tuv_to_xyz ( t_axis)
95
+ . normalized_direction ( ) ;
96
96
97
97
let Some ( new_tanh_distance) =
98
98
ray. solve_sphere_plane_intersection ( & normal, collider_radius. sinh ( ) )
@@ -121,7 +121,7 @@ fn find_face_collision(
121
121
} ;
122
122
123
123
let ray_endpoint = ray. ray_point ( new_tanh_distance) ;
124
- let contact_point = ray_endpoint - normal * ray_endpoint. mip ( & normal) ;
124
+ let contact_point = ray_endpoint - normal. as_ref ( ) * ray_endpoint. mip ( & normal) ;
125
125
126
126
// Compute the u and v-coordinates of the voxels at the contact point
127
127
let Some ( voxel_u) = layout. dual_to_voxel ( contact_point[ u_axis] / contact_point. w ) else {
@@ -135,15 +135,15 @@ fn find_face_collision(
135
135
if !voxel_is_solid (
136
136
voxel_data,
137
137
layout,
138
- math :: tuv_to_xyz ( t_axis , [ voxel_t, voxel_u, voxel_v] ) ,
138
+ [ voxel_t, voxel_u, voxel_v] . tuv_to_xyz ( t_axis ) ,
139
139
) {
140
140
continue ;
141
141
}
142
142
143
143
// A collision was found. Update the hit.
144
144
hit = Some ( ChunkCastHit {
145
145
tanh_distance : new_tanh_distance,
146
- normal,
146
+ normal : normal . into ( ) ,
147
147
} ) ;
148
148
}
149
149
@@ -168,14 +168,14 @@ fn find_edge_collision(
168
168
// Loop through all grid lines overlapping the bounding box
169
169
for ( u, v) in bounding_box. grid_lines ( u_axis, v_axis) {
170
170
// Compute vectors Lorentz-orthogonal to the edge and to each other
171
- let edge_normal0 =
172
- math :: tuv_to_xyz ( t_axis, MVector :: new ( 0.0 , 1.0 , 0.0 , layout . grid_to_dual ( u ) ) )
173
- . normalized ( ) ;
171
+ let edge_normal0 = MVector :: new ( 0.0 , 1.0 , 0.0 , layout . grid_to_dual ( u ) )
172
+ . tuv_to_xyz ( t_axis)
173
+ . normalized_direction ( ) ;
174
174
175
- let edge_normal1 =
176
- math :: tuv_to_xyz ( t_axis , MVector :: new ( 0.0 , 0.0 , 1.0 , layout . grid_to_dual ( v ) ) ) ;
177
- let edge_normal1 =
178
- ( edge_normal1 - edge_normal0 * edge_normal0 . mip ( & edge_normal1 ) ) . normalized ( ) ;
175
+ let edge_normal1 = MVector :: new ( 0.0 , 0.0 , 1.0 , layout . grid_to_dual ( v ) ) . tuv_to_xyz ( t_axis ) ;
176
+ let edge_normal1 = ( * edge_normal1 . as_ref ( )
177
+ - * edge_normal0 . as_ref ( ) * edge_normal0 . mip ( & edge_normal1 ) )
178
+ . normalized_direction ( ) ;
179
179
180
180
let Some ( new_tanh_distance) = ray. solve_sphere_line_intersection (
181
181
& edge_normal0,
@@ -192,8 +192,8 @@ fn find_edge_collision(
192
192
193
193
let ray_endpoint = ray. ray_point ( new_tanh_distance) ;
194
194
let contact_point = ray_endpoint
195
- - edge_normal0 * ray_endpoint. mip ( & edge_normal0)
196
- - edge_normal1 * ray_endpoint. mip ( & edge_normal1) ;
195
+ - edge_normal0. as_ref ( ) * ray_endpoint. mip ( & edge_normal0)
196
+ - edge_normal1. as_ref ( ) * ray_endpoint. mip ( & edge_normal1) ;
197
197
198
198
// Compute the t-coordinate of the voxels at the contact point
199
199
let Some ( voxel_t) = layout. dual_to_voxel ( contact_point[ t_axis] / contact_point. w ) else {
@@ -206,7 +206,7 @@ fn find_edge_collision(
206
206
!voxel_is_solid (
207
207
voxel_data,
208
208
layout,
209
- math :: tuv_to_xyz ( t_axis , [ voxel_t, voxel_u, voxel_v] ) ,
209
+ [ voxel_t, voxel_u, voxel_v] . tuv_to_xyz ( t_axis ) ,
210
210
)
211
211
} )
212
212
} ) {
@@ -248,17 +248,19 @@ fn find_vertex_collision(
248
248
}
249
249
250
250
// Compute vectors Lorentz-orthogonal to the vertex and to each other
251
- let vertex_normal0 = MVector :: new ( 1.0 , 0.0 , 0.0 , layout. grid_to_dual ( x) ) . normalized ( ) ;
251
+ let vertex_normal0 =
252
+ MVector :: new ( 1.0 , 0.0 , 0.0 , layout. grid_to_dual ( x) ) . normalized_direction ( ) ;
252
253
253
254
let vertex_normal1 = MVector :: new ( 0.0 , 1.0 , 0.0 , layout. grid_to_dual ( y) ) ;
254
- let vertex_normal1 =
255
- ( vertex_normal1 - vertex_normal0 * vertex_normal0. mip ( & vertex_normal1) ) . normalized ( ) ;
255
+ let vertex_normal1 = ( vertex_normal1
256
+ - vertex_normal0. as_ref ( ) * vertex_normal0. mip ( & vertex_normal1) )
257
+ . normalized_direction ( ) ;
256
258
257
259
let vertex_normal2 = MVector :: new ( 0.0 , 0.0 , 1.0 , layout. grid_to_dual ( z) ) ;
258
260
let vertex_normal2 = ( vertex_normal2
259
- - vertex_normal0 * vertex_normal0. mip ( & vertex_normal2)
260
- - vertex_normal1 * vertex_normal1. mip ( & vertex_normal2) )
261
- . normalized ( ) ;
261
+ - vertex_normal0. as_ref ( ) * vertex_normal0. mip ( & vertex_normal2)
262
+ - vertex_normal1. as_ref ( ) * vertex_normal1. mip ( & vertex_normal2) )
263
+ . normalized_direction ( ) ;
262
264
263
265
let Some ( new_tanh_distance) = ray. solve_sphere_point_intersection (
264
266
& vertex_normal0,
@@ -281,13 +283,13 @@ fn find_vertex_collision(
281
283
layout. grid_to_dual ( z) ,
282
284
1.0 ,
283
285
)
284
- . normalized ( ) ;
286
+ . normalized_point ( ) ;
285
287
286
288
// A collision was found. Update the hit.
287
289
let ray_endpoint = ray. ray_point ( new_tanh_distance) ;
288
290
hit = Some ( ChunkCastHit {
289
291
tanh_distance : new_tanh_distance,
290
- normal : ray_endpoint - vertex_position,
292
+ normal : ray_endpoint - vertex_position. as_ref ( ) ,
291
293
} ) ;
292
294
}
293
295
@@ -355,20 +357,21 @@ mod tests {
355
357
ray_start_grid_coords[ 2 ] / ctx. layout . dual_to_grid_factor ( ) ,
356
358
1.0 ,
357
359
)
358
- . normalized ( ) ;
360
+ . normalized_point ( ) ;
359
361
360
362
let ray_end = MVector :: new (
361
363
ray_end_grid_coords[ 0 ] / ctx. layout . dual_to_grid_factor ( ) ,
362
364
ray_end_grid_coords[ 1 ] / ctx. layout . dual_to_grid_factor ( ) ,
363
365
ray_end_grid_coords[ 2 ] / ctx. layout . dual_to_grid_factor ( ) ,
364
366
1.0 ,
365
367
)
366
- . normalized ( ) ;
368
+ . normalized_point ( ) ;
367
369
368
370
let ray = Ray :: new (
369
371
ray_start,
370
- ( ( ray_end - ray_start) + ray_start * ray_start. mip ( & ( ray_end - ray_start) ) )
371
- . normalized ( ) ,
372
+ ( ( ray_end. as_ref ( ) - ray_start. as_ref ( ) )
373
+ + ray_start. as_ref ( ) * ray_start. mip ( & ( ray_end. as_ref ( ) - ray_start. as_ref ( ) ) ) )
374
+ . normalized_direction ( ) ,
372
375
) ;
373
376
374
377
let tanh_distance = ( -ray_start. mip ( & ray_end) ) . acosh ( ) ;
@@ -511,12 +514,12 @@ mod tests {
511
514
// The ray we care about is after its start point has moved to the contact point.
512
515
let ray = MIsometry :: translation (
513
516
& ray. position ,
514
- & ray. ray_point ( hit. tanh_distance ) . normalized ( ) ,
517
+ & ray. ray_point ( hit. tanh_distance ) . normalized_point ( ) ,
515
518
) * ray;
516
519
517
520
// Project normal to be perpendicular to the ray's position
518
- let corrected_normal =
519
- ( hit . normal + ray . position * hit . normal . mip ( & ray . position ) ) . normalized ( ) ;
521
+ let corrected_normal = ( hit . normal + ray . position . as_ref ( ) * hit . normal . mip ( & ray . position ) )
522
+ . normalized_direction ( ) ;
520
523
521
524
// Check that the normal and ray are pointing opposite directions
522
525
assert ! ( corrected_normal. mip( & ray. direction) < 0.0 ) ;
0 commit comments