@@ -106,32 +106,6 @@ namespace physics {
106
106
}
107
107
108
108
109
- pny_internal void update_best_for_face_axis (
110
- real32 *best_sep, uint32 *best_axis, v3 *best_normal,
111
- real32 sep, uint32 axis, v3 normal
112
- ) {
113
- if (sep > *best_sep) {
114
- *best_sep = sep;
115
- *best_axis = axis;
116
- *best_normal = normal ;
117
- }
118
- }
119
-
120
-
121
- pny_internal void update_best_for_edge_axis (
122
- real32 *best_sep, uint32 *best_axis, v3 *best_normal,
123
- real32 sep, uint32 axis, v3 normal
124
- ) {
125
- real32 normal_len = length (normal );
126
- sep /= normal_len;
127
- if (sep > *best_sep) {
128
- *best_sep = sep;
129
- *best_axis = axis;
130
- *best_normal = normal / normal_len;
131
- }
132
- }
133
-
134
-
135
109
/* !
136
110
This function gets the nearest contact point between two edges. It's used
137
111
to determine a collision point for a box collision that has happened
@@ -279,6 +253,122 @@ namespace physics {
279
253
}
280
254
281
255
256
+ pny_internal void get_reference_face_edges_and_basis (
257
+ m3 *cob, // object change of base
258
+ v3 e, // object extents
259
+ v3 c, // object center
260
+ v3 n, // collision normal
261
+ uint32 axis, // axis of separation
262
+ uint32 clip_edges[4 ], // the indices of the reference face edges
263
+ m3 *reference_face_cob, // the change of basis of the reference face
264
+ v3 *reference_face_e // the extents of the reference face
265
+ ) {
266
+ n = transpose (*cob) * n;
267
+
268
+ if (axis >= 3 ) {
269
+ axis -= 3 ;
270
+ }
271
+
272
+ if (axis == 0 ) {
273
+ if (n.x > 0 .0f ) {
274
+ clip_edges[0 ] = 1 ;
275
+ clip_edges[1 ] = 8 ;
276
+ clip_edges[2 ] = 7 ;
277
+ clip_edges[3 ] = 9 ;
278
+ row (*reference_face_cob, 0 , row (*cob, 1 ));
279
+ row (*reference_face_cob, 1 , row (*cob, 2 ));
280
+ row (*reference_face_cob, 2 , row (*cob, 0 ));
281
+ *reference_face_e = v3 (e.y , e.z , e.x );
282
+ } else {
283
+ clip_edges[0 ] = 11 ;
284
+ clip_edges[1 ] = 3 ;
285
+ clip_edges[2 ] = 10 ;
286
+ clip_edges[3 ] = 5 ;
287
+ row (*reference_face_cob, 0 , row (*cob, 2 ));
288
+ row (*reference_face_cob, 1 , row (*cob, 1 ));
289
+ row (*reference_face_cob, 2 , -row (*cob, 0 ));
290
+ *reference_face_e = v3 (e.z , e.y , e.x );
291
+ }
292
+ } else if (axis == 1 ) {
293
+ if (n.y > 0 .0f ) {
294
+ clip_edges[0 ] = 0 ;
295
+ clip_edges[1 ] = 1 ;
296
+ clip_edges[2 ] = 2 ;
297
+ clip_edges[3 ] = 3 ;
298
+ row (*reference_face_cob, 0 , row (*cob, 2 ));
299
+ row (*reference_face_cob, 1 , row (*cob, 0 ));
300
+ row (*reference_face_cob, 2 , row (*cob, 1 ));
301
+ *reference_face_e = v3 (e.z , e.x , e.y );
302
+ } else {
303
+ clip_edges[0 ] = 4 ;
304
+ clip_edges[1 ] = 5 ;
305
+ clip_edges[2 ] = 6 ;
306
+ clip_edges[3 ] = 7 ;
307
+ row (*reference_face_cob, 0 , row (*cob, 2 ));
308
+ row (*reference_face_cob, 1 , -row (*cob, 0 ));
309
+ row (*reference_face_cob, 2 , -row (*cob, 1 ));
310
+ *reference_face_e = v3 (e.z , e.x , e.y );
311
+ }
312
+ } else if (axis == 2 ) {
313
+ if (n.z > 0 .0f ) {
314
+ clip_edges[0 ] = 11 ;
315
+ clip_edges[1 ] = 4 ;
316
+ clip_edges[2 ] = 8 ;
317
+ clip_edges[3 ] = 0 ;
318
+ row (*reference_face_cob, 0 , -row (*cob, 1 ));
319
+ row (*reference_face_cob, 1 , row (*cob, 0 ));
320
+ row (*reference_face_cob, 2 , row (*cob, 2 ));
321
+ *reference_face_e = v3 (e.y , e.x , e.z );
322
+ } else {
323
+ clip_edges[0 ] = 6 ;
324
+ clip_edges[1 ] = 10 ;
325
+ clip_edges[2 ] = 2 ;
326
+ clip_edges[3 ] = 9 ;
327
+ row (*reference_face_cob, 0 , -row (*cob, 1 ));
328
+ row (*reference_face_cob, 1 , -row (*cob, 0 ));
329
+ row (*reference_face_cob, 2 , -row (*cob, 2 ));
330
+ *reference_face_e = v3 (e.y , e.x , e.z );
331
+ }
332
+ }
333
+ }
334
+
335
+
336
+ uint32 clip_faces (
337
+ v3 reference_center, v3 reference_face_extents,
338
+ uint32 clip_edges[4 ], m3 reference_face_cob,
339
+ Face incident_face,
340
+ v3 clip_vertices[8 ], real32 clip_depths[8 ]
341
+ ) {
342
+ return 0 ;
343
+ }
344
+
345
+
346
+ pny_internal void update_best_for_face_axis (
347
+ real32 *best_sep, uint32 *best_axis, v3 *best_normal,
348
+ real32 sep, uint32 axis, v3 normal
349
+ ) {
350
+ if (sep > *best_sep) {
351
+ *best_sep = sep;
352
+ *best_axis = axis;
353
+ *best_normal = normal ;
354
+ }
355
+ }
356
+
357
+
358
+ pny_internal void update_best_for_edge_axis (
359
+ real32 *best_sep, uint32 *best_axis, v3 *best_normal,
360
+ real32 sep, uint32 axis, v3 normal
361
+ ) {
362
+ real32 normal_len = length (normal );
363
+ sep /= normal_len;
364
+ if (sep > *best_sep) {
365
+ *best_sep = sep;
366
+ *best_axis = axis;
367
+ *best_normal = normal / normal_len;
368
+ }
369
+ }
370
+
371
+
282
372
/* !
283
373
This function implements collision detection between two OBBs.
284
374
@@ -536,7 +626,24 @@ namespace physics {
536
626
&incident_cob, incident_extents, incident_center, manifold.normal
537
627
);
538
628
539
- // TODO: Clipping goes here.
629
+ uint32 clip_edges[4 ];
630
+ m3 reference_face_cob;
631
+ v3 reference_face_extents;
632
+ get_reference_face_edges_and_basis (
633
+ &reference_cob, reference_extents, reference_center, manifold.normal ,
634
+ manifold.axis ,
635
+ clip_edges, &reference_face_cob, &reference_face_extents
636
+ );
637
+
638
+ uint32 n_clip_vertices;
639
+ v3 clip_vertices[8 ];
640
+ real32 clip_depths[8 ];
641
+ n_clip_vertices = clip_faces (
642
+ reference_center, reference_face_extents,
643
+ clip_edges, reference_face_cob,
644
+ incident_face,
645
+ clip_vertices, clip_depths
646
+ );
540
647
541
648
debugdraw::draw_quad (
542
649
debugdraw::g_dds,
0 commit comments