Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
collision.c File Reference

Go to the source code of this file.

Data Structures

struct  HitFile
 
struct  ColliderBackupEntry
 
struct  HitFileHeader
 
struct  HitAssetCollider
 

Functions

s32 collision_heap_create (void)
 
void * collision_heap_malloc (s32 size)
 
void collision_heap_free (void *)
 
void load_hit_data (s32 idx, HitFile *hit)
 
void _add_hit_vert_to_buffer (Vec3f **buf, Vec3f *vert, s32 *bufSize)
 
s32 _get_hit_vert_index_from_buffer (Vec3f **buffer, Vec3f *vert, s32 *bufferSize)
 
void backup_map_collision_data (void)
 
void func_8005AF84 (void)
 
void func_8005AF8C (void)
 
void initialize_collision (void)
 
void load_map_hit_asset (void)
 
void restore_map_collision_data (void)
 
void load_battle_hit_asset (const char *hitName)
 
void parent_collider_to_model (s16 colliderID, s16 modelIndex)
 
void update_collider_transform (s16 colliderID)
 
s32 get_collider_flags (s32 colliderID)
 
void get_flat_collider_normal (s32 colliderID, f32 *x, f32 *y, f32 *z)
 
void get_collider_center (s32 colliderID, f32 *x, f32 *y, f32 *z)
 
s32 test_ray_triangle_general (ColliderTriangle *triangle, Vec3f *vertices)
 
s32 test_ray_triangle_down (ColliderTriangle *triangle, Vec3f *vertices)
 
s32 test_ray_triangle_horizontal (ColliderTriangle *triangle, Vec3f *vertices)
 
s32 test_ray_colliders (s32 ignoreFlags, f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32 *hitX, f32 *hitY, f32 *hitZ, f32 *hitDepth, f32 *hitNx, f32 *hitNy, f32 *hitNz)
 
s32 test_ray_zones (f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32 *hitX, f32 *hitY, f32 *hitZ, f32 *hitDepth, f32 *hitNx, f32 *hitNy, f32 *hitNz)
 
f32 test_ray_collider_horizontal (s32 ignoreFlags, s32 colliderID, f32 x, f32 y, f32 z, f32 length, f32 yaw)
 
s32 test_ray_entities (f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32 *hitX, f32 *hitY, f32 *hitZ, f32 *hitDepth, f32 *hitNx, f32 *hitNy, f32 *hitNz)
 Test a general ray from a given starting position and direction against all entities.
 

Variables

CollisionData gCollisionData
 
CollisionData gZoneCollisionData
 
BSS f32 gCollisionRayStartX
 
BSS f32 gCollisionRayStartY
 
BSS f32 gCollisionRayStartZ
 
BSS f32 gCollisionRayDirX
 
BSS f32 gCollisionRayDirY
 
BSS f32 gCollisionRayDirZ
 
BSS f32 gCollisionPointX
 
BSS f32 gCollisionPointY
 
BSS f32 gCollisionPointZ
 
BSS f32 gCollisionRayLength
 
BSS f32 gCollisionNormalX
 
BSS f32 gCollisionNormalY
 
BSS f32 gCollisionNormalZ
 
BSS ColliderBackupEntrygCollisionDataBackup
 
BSS ColliderBackupEntrygCollisionDataZoneBackup
 
Vec3s gEntityColliderFaces []
 
Vec3f gEntityColliderNormals []
 

Data Structure Documentation

◆ HitFile

struct HitFile
Data Fields
u32 collisionOffset
u32 zoneOffset

◆ ColliderBackupEntry

struct ColliderBackupEntry
Data Fields
s32 flags
s16 parentModelIndex
char pad_06[2]

◆ HitFileHeader

struct HitFileHeader
Data Fields
s16 numColliders
char pad_02[2]
s32 collidersOffset
s16 numVertices
char pad_0A[2]
s32 verticesOffset
s16 boundingBoxesDataSize
char pad_12[2]
s32 boundingBoxesOffset

◆ HitAssetCollider

struct HitAssetCollider
Data Fields
s16 boundingBoxOffset
s16 nextSibling
s16 firstChild
s16 numTriangles
s32 trianglesOffset

Function Documentation

◆ collision_heap_create()

s32 collision_heap_create ( void )

Definition at line 50 of file heap.c.

50 {
52 return -1;
53 }
54 return 0;
55}
HeapNode * _heap_create(HeapNode *addr, u32 size)
Definition 43F0.c:63
HeapNode heap_collisionHead
Definition heaps2.c:7
#define COLLISION_HEAP_SIZE
Definition macros.h:111

Referenced by initialize_collision().

◆ collision_heap_malloc()

void * collision_heap_malloc ( s32 size)

Definition at line 57 of file heap.c.

57 {
59 return _heap_malloc(&heap_collisionHead, size);
60 } else {
61 return _heap_malloc(&heap_battleHead, size);
62 }
63}
@ CONTEXT_WORLD
Definition enums.h:3529
void * _heap_malloc(HeapNode *head, u32 size)
Definition 43F0.c:78
GameStatus * gGameStatusPtr
Definition main_loop.c:32
HeapNode heap_battleHead

Referenced by load_hit_data(), and parent_collider_to_model().

◆ collision_heap_free()

void collision_heap_free ( void * data)

Definition at line 65 of file heap.c.

65 {
67 return _heap_free(&heap_battleHead, data);
68 } else {
69 return _heap_free(&heap_collisionHead, data);
70 }
71}
u32 _heap_free(HeapNode *heapNodeList, void *addrToFree)
Definition 43F0.c:221

Referenced by parent_collider_to_model().

◆ load_hit_data()

void load_hit_data ( s32 idx,
HitFile * hit )

Definition at line 186 of file collision.c.

186 {
187 s32 collisionOffset;
188 MapSettings* map;
189 CollisionData* collisionData;
190 HitFileHeader* assetCollisionData;
191 Vec3f* vertices;
192 Vec3s* assetVertices;
193 u32* boundingBox;
194 u32* assetBoundingBox;
195 Collider* collider;
196 HitAssetCollider* assetCollider;
197 ColliderTriangle* triangle;
198 s32* trianglePacked;
199 s16 numTriangles;
200 s32 i,j;
201 f32 e13_y, e21_z, e13_z, e21_y, e21_x, e13_x, normalX, normalY, normalZ, coeff;
202
203 assetCollisionData = NULL;
204 collisionData = NULL;
205
207
208 switch (idx) {
209 case 0: // Colliders
210 collisionOffset = map->hitAssetCollisionOffset;
211 if (collisionOffset == 0) {
212 return;
213 }
214
215 assetCollisionData = (HitFileHeader*)((void*)hit + collisionOffset);
216 collisionData = &gCollisionData;
217 break;
218 case 1: // Zones
219 collisionOffset = map->hitAssetZoneOffset;
220 if (collisionOffset == 0) {
221 return;
222 }
223
224 assetCollisionData = (HitFileHeader*)((void*)hit + collisionOffset);
225 collisionData = &gZoneCollisionData;
226 break;
227 }
228
229 assetBoundingBox = (u32*)((void*)hit + assetCollisionData->boundingBoxesOffset);
230 collisionData->aabbs = collision_heap_malloc(assetCollisionData->boundingBoxesDataSize * 4);
231 for (i = 0, boundingBox = (u32*)(collisionData->aabbs); i < assetCollisionData->boundingBoxesDataSize;
232 assetBoundingBox++, boundingBox++, i++) {
233 *boundingBox = *assetBoundingBox;
234 }
235
236 assetVertices = (Vec3s*)((void*)hit + assetCollisionData->verticesOffset);
237 collisionData->vertices = collision_heap_malloc(assetCollisionData->numVertices * sizeof(Vec3f));
238 for (i = 0, vertices = collisionData->vertices; i < assetCollisionData->numVertices;
239 vertices++, assetVertices++, i++) {
240 vertices->x = assetVertices->x;
241 vertices->y = assetVertices->y;
242 vertices->z = assetVertices->z;
243 }
244
245 assetCollider = (HitAssetCollider*)((void*)hit + assetCollisionData->collidersOffset);
246 collider = collisionData->colliderList = collision_heap_malloc(assetCollisionData->numColliders * sizeof(Collider));
247 collisionData->numColliders = assetCollisionData->numColliders;
248 for (i = 0; i < assetCollisionData->numColliders; assetCollider++, collider++, i++) {
249 collider->flags = 0;
250 collider->nextSibling = assetCollider->nextSibling;
251 collider->firstChild = assetCollider->firstChild;
252 collider->numTriangles = assetCollider->numTriangles;
253
254 numTriangles = collider->numTriangles;
255
256 if (numTriangles) {
257 collider->triangleTable = triangle = collision_heap_malloc(assetCollider->numTriangles * sizeof(ColliderTriangle));
258
259 if (assetCollider->boundingBoxOffset < 0) {
260 collider->aabb = NULL;
261 } else {
262 collider->aabb = (ColliderBoundingBox*)((u32*)(collisionData->aabbs) + assetCollider->boundingBoxOffset);
263
264 if (idx == 0) {
265 collider->aabb->min.x -= 1;
266 collider->aabb->min.y -= 1;
267 collider->aabb->min.z -= 1;
268 collider->aabb->max.x += 1;
269 collider->aabb->max.y += 1;
270 collider->aabb->max.z += 1;
271 collider->flags = collider->aabb->flagsForCollider;
272 }
273 }
274
275 trianglePacked = (s32*)((void*)hit + assetCollider->trianglesOffset);
276
277 for (j = 0; j < assetCollider->numTriangles; trianglePacked++, triangle++, j++) {
278 Vec3f* v1 = triangle->v1 = &collisionData->vertices[(*trianglePacked) & 0x3FF];
279 Vec3f* v2 = triangle->v2 = &collisionData->vertices[(*trianglePacked >> 10) & 0x3FF];
280 Vec3f* v3 = triangle->v3 = &collisionData->vertices[(*trianglePacked >> 20) & 0x3FF];
281 triangle->oneSided = (*trianglePacked >> 30) & 1;
282
283 triangle->e13.x = v3->x - v1->x;
284 triangle->e13.y = v3->y - v1->y;
285 triangle->e13.z = v3->z - v1->z;
286 triangle->e21.x = v1->x - v2->x;
287 triangle->e21.y = v1->y - v2->y;
288 triangle->e21.z = v1->z - v2->z;
289 triangle->e32.x = v2->x - v3->x;
290 triangle->e32.y = v2->y - v3->y;
291 triangle->e32.z = v2->z - v3->z;
292
293 e13_x = triangle->e13.x;
294 e13_y = triangle->e13.y;
295 e13_z = triangle->e13.z;
296 e21_x = triangle->e21.x;
297 e21_y = triangle->e21.y;
298 e21_z = triangle->e21.z;
299
300 // cross product
301 normalX = e13_y * e21_z - e13_z * e21_y;
302 normalY = e13_z * e21_x - e13_x * e21_z;
303 normalZ = e13_x * e21_y - e13_y * e21_x;
304 coeff = SQ(normalX) + SQ(normalY) + SQ(normalZ);
305
306 if (coeff != 0) {
307 coeff = 1.0f / sqrtf(coeff);
308 } else {
309 coeff = 0.0f;
310 }
311
312 triangle->normal.x = normalX * coeff;
313 triangle->normal.y = normalY * coeff;
314 triangle->normal.z = normalZ * coeff;
315 }
316 }
317 }
318}
s32 boundingBoxesOffset
Definition collision.c:24
CollisionData gZoneCollisionData
Definition collision.c:36
s32 collidersOffset
Definition collision.c:18
CollisionData gCollisionData
Definition collision.c:35
s16 boundingBoxesDataSize
Definition collision.c:22
void * collision_heap_malloc(s32 size)
Definition heap.c:57
s32 verticesOffset
Definition collision.c:21
Collider * colliderList
#define sqrtf
#define SQ(x)
Definition macros.h:166
MapSettings * get_current_map_settings(void)
Definition world.c:224
s32 hitAssetZoneOffset
Definition map.h:29
s32 hitAssetCollisionOffset
Definition map.h:28
Fields other than main, entryList, entryCount, background, and tattle are initialised when the map lo...
Definition map.h:26

Referenced by load_battle_hit_asset(), and load_map_hit_asset().

◆ _add_hit_vert_to_buffer()

void _add_hit_vert_to_buffer ( Vec3f ** buf,
Vec3f * vert,
s32 * bufSize )

Definition at line 363 of file collision.c.

363 {
364 s32 i;
365
366 for (i = 0; i < *bufSize; i++) {
367 if (buf[i] == vert) {
368 break;
369 }
370 }
371
372 if (i == *bufSize) {
373 buf[i] = vert;
374 (*bufSize)++;
375 }
376}

Referenced by parent_collider_to_model().

◆ _get_hit_vert_index_from_buffer()

s32 _get_hit_vert_index_from_buffer ( Vec3f ** buffer,
Vec3f * vert,
s32 * bufferSize )

Definition at line 378 of file collision.c.

378 {
379 s32 i;
380
381 for (i = 0; i < *bufferSize; i++) {
382 if (*buffer == vert) {
383 break;
384 }
385 buffer++;
386 }
387
388 return i;
389}

Referenced by parent_collider_to_model().

◆ backup_map_collision_data()

void backup_map_collision_data ( void )

Definition at line 80 of file collision.c.

80 {
81 CollisionData* collisionData;
82 Collider* collider;
83 ColliderBackupEntry* backupEntry;
84 s32 i;
85
86 collisionData = &gCollisionData;
88 for (i = 0, backupEntry = gCollisionDataBackup; i < collisionData->numColliders; i++, backupEntry++) {
89 collider = &collisionData->colliderList[i];
90 backupEntry->flags = collider->flags;
91 backupEntry->parentModelIndex = collider->parentModelIndex;
92 }
93
94 collisionData = &gZoneCollisionData;
96 for (i = 0, backupEntry = gCollisionDataZoneBackup; i < collisionData->numColliders; i++, backupEntry++) {
97 collider = &collisionData->colliderList[i];
98 backupEntry->flags = collider->flags;
99 backupEntry->parentModelIndex = collider->parentModelIndex;
100 }
101
103}
BSS ColliderBackupEntry * gCollisionDataZoneBackup
Definition collision.c:52
BSS ColliderBackupEntry * gCollisionDataBackup
Definition collision.c:51
#define general_heap_malloc

Referenced by state_step_battle(), and state_step_pause().

◆ func_8005AF84()

void func_8005AF84 ( void )

Definition at line 105 of file collision.c.

105 {
106}

Referenced by state_step_end_battle(), and state_step_unpause().

◆ func_8005AF8C()

void func_8005AF8C ( void )

Definition at line 108 of file collision.c.

108 {
109}

◆ initialize_collision()

void initialize_collision ( void )

◆ load_map_hit_asset()

void load_map_hit_asset ( void )

Definition at line 117 of file collision.c.

117 {
118 u32 assetSize;
120 void* compressedData = load_asset_by_name(wMapHitName, &assetSize);
121 HitFile* uncompressedData = heap_malloc(assetSize);
122
123 decode_yay0(compressedData, uncompressedData);
124 general_heap_free(compressedData);
125
126 map->hitAssetCollisionOffset = uncompressedData->collisionOffset;
127 map->hitAssetZoneOffset = uncompressedData->zoneOffset;
128
129 load_hit_data(0, uncompressedData); // Colliders
130 load_hit_data(1, uncompressedData); // Zones
131
132 heap_free(uncompressedData);
133}
u32 zoneOffset
Definition collision.c:6
void load_hit_data(s32 idx, HitFile *hit)
Definition collision.c:186
u32 collisionOffset
Definition collision.c:5
void * load_asset_by_name(const char *assetName, u32 *decompressedSize)
Definition world.c:251
s32 heap_free(void *ptr)
Definition heap.c:42
s32 general_heap_free(void *data)
Definition heap.c:18
void decode_yay0(void *src, void *dst)
void * heap_malloc(s32 size)
Definition heap.c:34
char wMapHitName[]
Definition world.c:26

Referenced by load_map_by_IDs(), and restore_map_collision_data().

◆ restore_map_collision_data()

void restore_map_collision_data ( void )

Definition at line 135 of file collision.c.

135 {
136 CollisionData* collisionData;
137 Collider* collider;
138 ColliderBackupEntry* backupEntry;
139 s32 i;
140
142
143 collisionData = &gCollisionData;
144 for (i = 0, backupEntry = gCollisionDataBackup; i < collisionData->numColliders; i++, backupEntry++) {
145 collider = &collisionData->colliderList[i];
146 collider->flags = backupEntry->flags;
147 collider->parentModelIndex = backupEntry->parentModelIndex;
148
149 if (collider->flags != -1 && collider->flags & COLLIDER_FLAG_HAS_MODEL_PARENT) {
152 }
153 }
154
155 collisionData = &gZoneCollisionData;
156 for (i = 0, backupEntry = gCollisionDataZoneBackup; i < collisionData->numColliders; i++, backupEntry++) {
157 collider = &collisionData->colliderList[i];
158 collider->flags = backupEntry->flags;
159 collider->parentModelIndex = backupEntry->parentModelIndex;
160 }
161
164}
void load_map_hit_asset(void)
Definition collision.c:117
void update_collider_transform(s16 colliderID)
Definition collision.c:391
void parent_collider_to_model(s16 colliderID, s16 modelIndex)
Definition collision.c:320
@ COLLIDER_FLAG_HAS_MODEL_PARENT
Definition enums.h:4701

Referenced by state_step_end_battle(), and state_step_unpause().

◆ load_battle_hit_asset()

void load_battle_hit_asset ( const char * hitName)

Definition at line 166 of file collision.c.

166 {
167 if (hitName == NULL) {
169 } else {
170 u32 assetSize;
172 void* compressedData = load_asset_by_name(hitName, &assetSize);
173 HitFile* uncompressedData = heap_malloc(assetSize);
174
175 decode_yay0(compressedData, uncompressedData);
176 general_heap_free(compressedData);
177
178 map->hitAssetCollisionOffset = uncompressedData->collisionOffset;
179
180 load_hit_data(0, uncompressedData);
181
182 heap_free(uncompressedData);
183 }
184}

Referenced by btl_state_update_normal_start().

◆ parent_collider_to_model()

void parent_collider_to_model ( s16 colliderID,
s16 modelIndex )

Definition at line 320 of file collision.c.

320 {
321 Collider* collider;
322 ColliderTriangle* triangle;
323 s32 i;
324 Vec3f** vertexBuffer;
325 Vec3f** vertexPtr;
326 s32 vertexBufferSize;
327 Vec3f* vertexTable;
328 Vec3f* vertex;
329
330 collider = &gCollisionData.colliderList[colliderID];
331 collider->parentModelIndex = modelIndex;
333
334 vertexBuffer = collision_heap_malloc(collider->numTriangles * sizeof(Vec3f));
335 vertexBufferSize = 0;
336 vertexPtr = vertexBuffer;
337
338 for (i = 0, triangle = collider->triangleTable; i < collider->numTriangles; i++, triangle++) {
339 _add_hit_vert_to_buffer(vertexBuffer, triangle->v1, &vertexBufferSize);
340 _add_hit_vert_to_buffer(vertexBuffer, triangle->v2, &vertexBufferSize);
341 _add_hit_vert_to_buffer(vertexBuffer, triangle->v3, &vertexBufferSize);
342 }
343
344 collider->numVertices = vertexBufferSize;
345 collider->vertexTable = collision_heap_malloc(vertexBufferSize * 2 * sizeof(Vec3f));
346 for (i = 0, vertexTable = collider->vertexTable; i < vertexBufferSize; vertexPtr++, vertexTable += 2, i++) {
347 vertex = *vertexPtr;
348 vertexTable[0].x = vertexTable[1].x = vertex->x;
349 vertexTable[0].y = vertexTable[1].y = vertex->y;
350 vertexTable[0].z = vertexTable[1].z = vertex->z;
351 }
352
353 vertexTable = collider->vertexTable;
354 for (i = 0, triangle = collider->triangleTable; i < collider->numTriangles; triangle++, i++) {
355 triangle->v1 = &vertexTable[_get_hit_vert_index_from_buffer(vertexBuffer, triangle->v1, &vertexBufferSize) * 2];
356 triangle->v2 = &vertexTable[_get_hit_vert_index_from_buffer(vertexBuffer, triangle->v2, &vertexBufferSize) * 2];
357 triangle->v3 = &vertexTable[_get_hit_vert_index_from_buffer(vertexBuffer, triangle->v3, &vertexBufferSize) * 2];
358 }
359
360 collision_heap_free(vertexBuffer);
361}
s32 _get_hit_vert_index_from_buffer(Vec3f **buffer, Vec3f *vert, s32 *bufferSize)
Definition collision.c:378
void collision_heap_free(void *)
Definition heap.c:65
void _add_hit_vert_to_buffer(Vec3f **buf, Vec3f *vert, s32 *bufSize)
Definition collision.c:363
Vec3f * vertexTable
struct ColliderTriangle * triangleTable

Referenced by restore_map_collision_data().

◆ update_collider_transform()

void update_collider_transform ( s16 colliderID)

Definition at line 391 of file collision.c.

391 {
392 Collider* collider;
393 struct Model* model;
394 Matrix4f matrix;
395 s32 i;
396 Vec3f* vertexTable;
397 f32 min_x, min_y, min_z, max_x, max_y, max_z;
398 ColliderTriangle* triangle;
399 f32 e13_y, e21_z, e13_z, e21_y, e21_x, e13_x, normalX, normalY, normalZ, coeff;
400
401 collider = &gCollisionData.colliderList[colliderID];
403
404 if (model->bakedMtx == NULL) {
405 copy_matrix(model->userTransformMtx, matrix);
406 } else {
407 guMtxL2F(matrix, (Mtx*)model->bakedMtx);
408 guMtxCatF(model->userTransformMtx, matrix, matrix);
409 }
410
411 triangle = collider->triangleTable;
412 vertexTable = collider->vertexTable;
413
414 min_x = min_y = min_z = 999999.9f;
415 max_x = max_y = max_z = -999999.9f;
416
417 for (i = 0; i < collider->numVertices; vertexTable += 2, i++) {
418 guMtxXFMF(matrix, vertexTable[1].x, vertexTable[1].y, vertexTable[1].z, &vertexTable[0].x, &vertexTable[0].y, &vertexTable[0].z);
419
420 if (vertexTable[0].x < min_x)
421 min_x = vertexTable[0].x;
422 if (vertexTable[0].x > max_x)
423 max_x = vertexTable[0].x;
424 if (vertexTable[0].y < min_y)
425 min_y = vertexTable[0].y;
426 if (vertexTable[0].y > max_y)
427 max_y = vertexTable[0].y;
428 if (vertexTable[0].z < min_z)
429 min_z = vertexTable[0].z;
430 if (vertexTable[0].z > max_z)
431 max_z = vertexTable[0].z;
432 }
433
434 collider->aabb->min.x = min_x;
435 collider->aabb->min.y = min_y;
436 collider->aabb->min.z = min_z;
437 collider->aabb->max.x = max_x;
438 collider->aabb->max.y = max_y;
439 collider->aabb->max.z = max_z;
440
441 for (i = 0; i < collider->numTriangles; triangle++, i++) {
442 Vec3f* v1 = triangle->v1;
443 Vec3f* v2 = triangle->v2;
444 Vec3f* v3 = triangle->v3;
445
446 triangle->e13.x = v3->x - v1->x;
447 triangle->e13.y = v3->y - v1->y;
448 triangle->e13.z = v3->z - v1->z;
449 triangle->e21.x = v1->x - v2->x;
450 triangle->e21.y = v1->y - v2->y;
451 triangle->e21.z = v1->z - v2->z;
452 triangle->e32.x = v2->x - v3->x;
453 triangle->e32.y = v2->y - v3->y;
454 triangle->e32.z = v2->z - v3->z;
455
456 e13_x = triangle->e13.x;
457 e13_y = triangle->e13.y;
458 e13_z = triangle->e13.z;
459 e21_x = triangle->e21.x;
460 e21_y = triangle->e21.y;
461 e21_z = triangle->e21.z;
462
463 // vector product
464 normalX = e13_y * e21_z - e13_z * e21_y;
465 normalY = e13_z * e21_x - e13_x * e21_z;
466 normalZ = e13_x * e21_y - e13_y * e21_x;
467 coeff = SQ(normalX) + SQ(normalY) + SQ(normalZ);
468
469 if (coeff != 0) {
470 coeff = 1.0f / sqrtf(coeff);
471 } else {
472 coeff = 0.0f;
473 }
474
475 triangle->normal.x = normalX * coeff;
476 triangle->normal.y = normalY * coeff;
477 triangle->normal.z = normalZ * coeff;
478 }
479}
f32 Matrix4f[4][4]
#define guMtxCatF
struct Model * get_model_from_list_index(s32 listIndex)
Definition model.c:3315
void copy_matrix(Matrix4f src, Matrix4f dest)
Definition 43F0.c:439
Mtx * bakedMtx
Definition model.h:62
Matrix4f userTransformMtx
Definition model.h:68
Definition model.h:59

Referenced by restore_map_collision_data().

◆ get_collider_flags()

◆ get_flat_collider_normal()

void get_flat_collider_normal ( s32 colliderID,
f32 * x,
f32 * y,
f32 * z )

Definition at line 489 of file collision.c.

489 {
490 ColliderTriangle* triangle = &gCollisionData.colliderList[colliderID].triangleTable[0];
491
492 *x = triangle->normal.x;
493 *y = triangle->normal.y;
494 *z = triangle->normal.z;
495}

◆ get_collider_center()

void get_collider_center ( s32 colliderID,
f32 * x,
f32 * y,
f32 * z )

Definition at line 497 of file collision.c.

497 {
498 ColliderBoundingBox* aabb = gCollisionData.colliderList[colliderID].aabb;
499
500 *x = (aabb->min.x + aabb->max.x) * 0.5f;
501 *y = (aabb->min.y + aabb->max.y) * 0.5f;
502 *z = (aabb->min.z + aabb->max.z) * 0.5f;
503}

◆ test_ray_triangle_general()

s32 test_ray_triangle_general ( ColliderTriangle * triangle,
Vec3f * vertices )

Definition at line 505 of file collision.c.

505 {
506 f32 distToTrianglePlane;
507 f32 cosAngle;
508 Vec3f* v1;
509 Vec3f* v2;
510 Vec3f* v3;
511
512 if (triangle->normal.x == 0 &&
513 triangle->normal.y == 0 &&
514 triangle->normal.z == 0)
515 return FALSE;
516
517 v1 = triangle->v1;
518 v2 = triangle->v2;
519 v3 = triangle->v3;
520
521 distToTrianglePlane = triangle->normal.x * (gCollisionRayStartX - v1->x) +
522 triangle->normal.y * (gCollisionRayStartY - v1->y) +
523 triangle->normal.z * (gCollisionRayStartZ - v1->z);
524
525 if (triangle->oneSided) {
526 if (distToTrianglePlane < 0) {
527 return FALSE;
528 }
529
530 if (triangle->normal.x * gCollisionRayDirX + triangle->normal.y * gCollisionRayDirY + triangle->normal.z * gCollisionRayDirZ >= 0) {
531 return FALSE;
532 }
533
534 if ((gCollisionRayStartX - v1->x) * (triangle->e13.z * gCollisionRayDirY - triangle->e13.y * gCollisionRayDirZ) +
535 (gCollisionRayStartY - v1->y) * (triangle->e13.x * gCollisionRayDirZ - triangle->e13.z * gCollisionRayDirX) +
536 (gCollisionRayStartZ - v1->z) * (triangle->e13.y * gCollisionRayDirX - triangle->e13.x * gCollisionRayDirY) < 0)
537 {
538 return FALSE;
539 }
540
541 if ((gCollisionRayStartX - v2->x) * (triangle->e21.z * gCollisionRayDirY - triangle->e21.y * gCollisionRayDirZ) +
542 (gCollisionRayStartY - v2->y) * (triangle->e21.x * gCollisionRayDirZ - triangle->e21.z * gCollisionRayDirX) +
543 (gCollisionRayStartZ - v2->z) * (triangle->e21.y * gCollisionRayDirX - triangle->e21.x * gCollisionRayDirY) < 0)
544 {
545 return FALSE;
546 }
547
548 if ((gCollisionRayStartX - v3->x) * (triangle->e32.z * gCollisionRayDirY - triangle->e32.y * gCollisionRayDirZ) +
549 (gCollisionRayStartY - v3->y) * (triangle->e32.x * gCollisionRayDirZ - triangle->e32.z * gCollisionRayDirX) +
550 (gCollisionRayStartZ - v3->z) * (triangle->e32.y * gCollisionRayDirX - triangle->e32.x * gCollisionRayDirY) < 0)
551 {
552 return FALSE;
553 }
554 } else {
555 if ((triangle->normal.x * gCollisionRayDirX + triangle->normal.y * gCollisionRayDirY + triangle->normal.z * gCollisionRayDirZ) * distToTrianglePlane >= 0) {
556 return FALSE;
557 }
558
559 if (((gCollisionRayStartX - v1->x) * (triangle->e13.z * gCollisionRayDirY - triangle->e13.y * gCollisionRayDirZ) +
560 (gCollisionRayStartY - v1->y) * (triangle->e13.x * gCollisionRayDirZ - triangle->e13.z * gCollisionRayDirX) +
561 (gCollisionRayStartZ - v1->z) * (triangle->e13.y * gCollisionRayDirX - triangle->e13.x * gCollisionRayDirY)
562 ) * distToTrianglePlane < 0)
563 {
564 return FALSE;
565 }
566
567 if (((gCollisionRayStartX - v2->x) * (triangle->e21.z * gCollisionRayDirY - triangle->e21.y * gCollisionRayDirZ) +
568 (gCollisionRayStartY - v2->y) * (triangle->e21.x * gCollisionRayDirZ - triangle->e21.z * gCollisionRayDirX) +
569 (gCollisionRayStartZ - v2->z) * (triangle->e21.y * gCollisionRayDirX - triangle->e21.x * gCollisionRayDirY)
570 ) * distToTrianglePlane < 0)
571 {
572 return FALSE;
573 }
574
575 if (((gCollisionRayStartX - v3->x) * (triangle->e32.z * gCollisionRayDirY - triangle->e32.y * gCollisionRayDirZ) +
576 (gCollisionRayStartY - v3->y) * (triangle->e32.x * gCollisionRayDirZ - triangle->e32.z * gCollisionRayDirX) +
577 (gCollisionRayStartZ - v3->z) * (triangle->e32.y * gCollisionRayDirX - triangle->e32.x * gCollisionRayDirY)
578 ) * distToTrianglePlane < 0)
579 {
580 return FALSE;
581 }
582 }
583
584 cosAngle = triangle->normal.x * gCollisionRayDirX + triangle->normal.y * gCollisionRayDirY + triangle->normal.z * gCollisionRayDirZ;
585 if (gCollisionRayLength >= 0 && gCollisionRayLength <= -distToTrianglePlane / cosAngle) {
586 return FALSE;
587 }
588
589 gCollisionRayLength = -distToTrianglePlane / cosAngle;
590
594
595 gCollisionNormalX = triangle->normal.x;
596 gCollisionNormalY = triangle->normal.y;
597 gCollisionNormalZ = triangle->normal.z;
598
599 return TRUE;
600}
BSS f32 gCollisionNormalY
Definition collision.c:49
BSS f32 gCollisionRayStartZ
Definition collision.c:40
BSS f32 gCollisionNormalX
Definition collision.c:48
BSS f32 gCollisionNormalZ
Definition collision.c:50
BSS f32 gCollisionPointX
Definition collision.c:44
BSS f32 gCollisionPointZ
Definition collision.c:46
BSS f32 gCollisionRayStartY
Definition collision.c:39
BSS f32 gCollisionRayLength
Definition collision.c:47
BSS f32 gCollisionPointY
Definition collision.c:45
BSS f32 gCollisionRayDirX
Definition collision.c:41
BSS f32 gCollisionRayStartX
Definition collision.c:38
BSS f32 gCollisionRayDirZ
Definition collision.c:43
BSS f32 gCollisionRayDirY
Definition collision.c:42

Referenced by test_ray_colliders(), and test_ray_entities().

◆ test_ray_triangle_down()

s32 test_ray_triangle_down ( ColliderTriangle * triangle,
Vec3f * vertices )

Definition at line 602 of file collision.c.

602 {
603 f32 distToTrianglePlane, cosAngle;
604 Vec3f* v1;
605 Vec3f* v2;
606 Vec3f* v3;
607
608 if (triangle->normal.x == 0 && triangle->normal.y == 0 && triangle->normal.z == 0) {
609 return FALSE;
610 }
611
612 v1 = triangle->v1;
613 v2 = triangle->v2;
614 v3 = triangle->v3;
615
616 distToTrianglePlane = triangle->normal.x * (gCollisionRayStartX - v1->x) +
617 triangle->normal.y * (gCollisionRayStartY - v1->y) +
618 triangle->normal.z * (gCollisionRayStartZ - v1->z);
619
620 if (triangle->oneSided) {
621 if (distToTrianglePlane < 0) {
622 return FALSE;
623 }
624
625 if (triangle->normal.y <= 0)
626 return FALSE;
627
628 if ((gCollisionRayStartZ - v1->z) * triangle->e13.x - (gCollisionRayStartX - v1->x) * triangle->e13.z < 0) {
629 return FALSE;
630 }
631
632 if ((gCollisionRayStartZ - v2->z) * triangle->e21.x - (gCollisionRayStartX - v2->x) * triangle->e21.z < 0) {
633 return FALSE;
634 }
635
636 if ((gCollisionRayStartZ - v3->z) * triangle->e32.x - (gCollisionRayStartX - v3->x) * triangle->e32.z < 0) {
637 return FALSE;
638 }
639 } else {
640 if (triangle->normal.y * distToTrianglePlane <= 0) {
641 return FALSE;
642 }
643
644 if (((gCollisionRayStartZ - v1->z) * triangle->e13.x - (gCollisionRayStartX - v1->x) * triangle->e13.z) * distToTrianglePlane < 0) {
645 return FALSE;
646 }
647
648 if (((gCollisionRayStartZ - v2->z) * triangle->e21.x - (gCollisionRayStartX - v2->x) * triangle->e21.z) * distToTrianglePlane < 0) {
649 return FALSE;
650 }
651
652 if (((gCollisionRayStartZ - v3->z) * triangle->e32.x - (gCollisionRayStartX - v3->x) * triangle->e32.z) * distToTrianglePlane < 0) {
653 return FALSE;
654 }
655 }
656
657 cosAngle = -triangle->normal.y;
658 if (gCollisionRayLength >= 0 && gCollisionRayLength <= -distToTrianglePlane / cosAngle) {
659 return FALSE;
660 }
661
662 gCollisionRayLength = -distToTrianglePlane / cosAngle;
663
667
668 gCollisionNormalX = triangle->normal.x;
669 gCollisionNormalY = triangle->normal.y;
670 gCollisionNormalZ = triangle->normal.z;
671
672 return TRUE;
673}

Referenced by test_ray_colliders(), and test_ray_zones().

◆ test_ray_triangle_horizontal()

s32 test_ray_triangle_horizontal ( ColliderTriangle * triangle,
Vec3f * vertices )

Definition at line 675 of file collision.c.

675 {
676 f32 distToTrianglePlane, cosAngle;
677 Vec3f* v1;
678 Vec3f* v2;
679 Vec3f* v3;
680
681 if (triangle->normal.x == 0 && triangle->normal.y == 0 && triangle->normal.z == 0) {
682 return FALSE;
683 }
684
685 v1 = triangle->v1;
686 v2 = triangle->v2;
687 v3 = triangle->v3;
688
689 distToTrianglePlane = triangle->normal.x * (gCollisionRayStartX - v1->x) +
690 triangle->normal.y * (gCollisionRayStartY - v1->y) +
691 triangle->normal.z * (gCollisionRayStartZ - v1->z);
692
693 if (triangle->oneSided) {
694 if (distToTrianglePlane < 0) {
695 return FALSE;
696 }
697
698 if (triangle->normal.x * gCollisionRayDirX + triangle->normal.z * gCollisionRayDirZ >= 0) {
699 return FALSE;
700 }
701
702 if ((gCollisionRayStartX - v1->x) * (-triangle->e13.y * gCollisionRayDirZ) +
703 (gCollisionRayStartY - v1->y) * (triangle->e13.x * gCollisionRayDirZ - triangle->e13.z * gCollisionRayDirX) +
704 (gCollisionRayStartZ - v1->z) * (triangle->e13.y * gCollisionRayDirX) < 0)
705 {
706 return FALSE;
707 }
708
709 if ((gCollisionRayStartX - v2->x) * (-triangle->e21.y * gCollisionRayDirZ) +
710 (gCollisionRayStartY - v2->y) * (triangle->e21.x * gCollisionRayDirZ - triangle->e21.z * gCollisionRayDirX) +
711 (gCollisionRayStartZ - v2->z) * (triangle->e21.y * gCollisionRayDirX) < 0)
712 {
713 return FALSE;
714 }
715
716 if ((gCollisionRayStartX - v3->x) * (-triangle->e32.y * gCollisionRayDirZ) +
717 (gCollisionRayStartY - v3->y) * (triangle->e32.x * gCollisionRayDirZ - triangle->e32.z * gCollisionRayDirX) +
718 (gCollisionRayStartZ - v3->z) * (triangle->e32.y * gCollisionRayDirX) < 0)
719 {
720 return FALSE;
721 }
722 } else {
723 if ((triangle->normal.x * gCollisionRayDirX + triangle->normal.z * gCollisionRayDirZ) * distToTrianglePlane >= 0)
724 {
725 return FALSE;
726 }
727
728 if (((gCollisionRayStartX - v1->x) * (-triangle->e13.y * gCollisionRayDirZ) +
729 (gCollisionRayStartY - v1->y) * (triangle->e13.x * gCollisionRayDirZ - triangle->e13.z * gCollisionRayDirX) +
730 (gCollisionRayStartZ - v1->z) * (triangle->e13.y * gCollisionRayDirX)) * distToTrianglePlane < 0)
731 {
732 return FALSE;
733 }
734
735 if (((gCollisionRayStartX - v2->x) * (-triangle->e21.y * gCollisionRayDirZ) +
736 (gCollisionRayStartY - v2->y) * (triangle->e21.x * gCollisionRayDirZ - triangle->e21.z * gCollisionRayDirX) +
737 (gCollisionRayStartZ - v2->z) * (triangle->e21.y * gCollisionRayDirX)) * distToTrianglePlane < 0)
738 {
739 return FALSE;
740 }
741
742 if (((gCollisionRayStartX - v3->x) * (-triangle->e32.y * gCollisionRayDirZ) +
743 (gCollisionRayStartY - v3->y) * (triangle->e32.x * gCollisionRayDirZ - triangle->e32.z * gCollisionRayDirX) +
744 (gCollisionRayStartZ - v3->z) * (triangle->e32.y * gCollisionRayDirX)) * distToTrianglePlane < 0)
745 {
746 return FALSE;
747 }
748 }
749
750 cosAngle = triangle->normal.x * gCollisionRayDirX + triangle->normal.z * gCollisionRayDirZ;
751 if (gCollisionRayLength >= 0 && gCollisionRayLength <= -distToTrianglePlane / cosAngle) {
752 return FALSE;
753 }
754
755 gCollisionRayLength = -distToTrianglePlane / cosAngle;
756
760
761 gCollisionNormalX = triangle->normal.x;
762 gCollisionNormalY = triangle->normal.y;
763 gCollisionNormalZ = triangle->normal.z;
764
765 return TRUE;
766}

Referenced by test_ray_collider_horizontal(), and test_ray_colliders().

◆ test_ray_colliders()

s32 test_ray_colliders ( s32 ignoreFlags,
f32 startX,
f32 startY,
f32 startZ,
f32 dirX,
f32 dirY,
f32 dirZ,
f32 * hitX,
f32 * hitY,
f32 * hitZ,
f32 * hitDepth,
f32 * hitNx,
f32 * hitNy,
f32 * hitNz )

Definition at line 768 of file collision.c.

769 {
770 Collider* collider;
771 CollisionData* collisionData;
772 ColliderTriangle* triangle;
773 s32 i, j;
774 s32 colliderID;
775 f32 min_x, min_y, min_z, max_x, max_y, max_z;
776
777 if (dirX == 0 && dirY == 0 && dirZ == 0) {
778 return 0;
779 }
780
781 collisionData = &gCollisionData;
782 gCollisionRayDirX = dirX;
783 gCollisionRayDirY = dirY;
784 gCollisionRayDirZ = dirZ;
785 gCollisionRayStartX = startX;
786 gCollisionRayStartY = startY;
787 gCollisionRayStartZ = startZ;
788 gCollisionRayLength = *hitDepth;
789 colliderID = NO_COLLIDER;
790
791 if (dirX < 0) {
792 min_x = startX + dirX * gCollisionRayLength;
793 max_x = startX;
794 } else {
795 min_x = startX;
796 max_x = startX + dirX * gCollisionRayLength;
797 }
798
799 if (dirY < 0) {
800 min_y = startY + dirY * gCollisionRayLength;
801 max_y = startY;
802 } else {
803 min_y = startY;
804 max_y = startY + dirY * gCollisionRayLength;
805 }
806
807 if (dirZ < 0) {
808 min_z = startZ + dirZ * gCollisionRayLength;
809 max_z = startZ;
810 } else {
811 min_z = startZ;
812 max_z = startZ + dirZ * gCollisionRayLength;
813 }
814
815 for (i = 0; i < collisionData->numColliders; i++) {
816 collider = &collisionData->colliderList[i];
817
818 if ((collider->flags & ignoreFlags) ||
819 collider->numTriangles == 0 ||
820 max_x < collider->aabb->min.x ||
821 min_x > collider->aabb->max.x ||
822 max_z < collider->aabb->min.z ||
823 min_z > collider->aabb->max.z ||
824 max_y < collider->aabb->min.y ||
825 min_y > collider->aabb->max.y)
826 {
827 continue;
828 }
829
830 triangle = collider->triangleTable;
831 if (gCollisionRayDirX == 0 && gCollisionRayDirZ == 0 && gCollisionRayDirY == -1.0) {
832 for (j = 0; j < collider->numTriangles; j++) {
833 if (test_ray_triangle_down(triangle++, collisionData->vertices)) {
834 colliderID = i;
835 }
836 }
837 } else if (gCollisionRayDirY == 0) {
838 for (j = 0; j < collider->numTriangles; j++) {
839 if (test_ray_triangle_horizontal(triangle++, collisionData->vertices)) {
840 colliderID = i;
841 }
842 }
843 } else {
844 for (j = 0; j < collider->numTriangles; j++) {
845 if (test_ray_triangle_general(triangle++, collisionData->vertices)) {
846 colliderID = i;
847 }
848 }
849 }
850 }
851
852 if (colliderID > NO_COLLIDER) {
853 *hitX = gCollisionPointX;
854 *hitY = gCollisionPointY;
855 *hitZ = gCollisionPointZ;
856 *hitDepth = gCollisionRayLength;
857 *hitNx = gCollisionNormalX;
858 *hitNy = gCollisionNormalY;
859 *hitNz = gCollisionNormalZ;
860 return colliderID;
861 } else {
862 return colliderID;
863 }
864}
s32 test_ray_triangle_down(ColliderTriangle *triangle, Vec3f *vertices)
Definition collision.c:602
s32 test_ray_triangle_general(ColliderTriangle *triangle, Vec3f *vertices)
Definition collision.c:505
s32 test_ray_triangle_horizontal(ColliderTriangle *triangle, Vec3f *vertices)
Definition collision.c:675
#define NO_COLLIDER
Definition macros.h:156

Referenced by entity_raycast_down(), npc_raycast_down(), npc_raycast_general(), npc_raycast_up(), npc_raycast_up_corner(), player_raycast_down(), player_raycast_general(), player_raycast_up_corner(), and test_ray_to_wall_center().

◆ test_ray_zones()

s32 test_ray_zones ( f32 startX,
f32 startY,
f32 startZ,
f32 dirX,
f32 dirY,
f32 dirZ,
f32 * hitX,
f32 * hitY,
f32 * hitZ,
f32 * hitDepth,
f32 * hitNx,
f32 * hitNy,
f32 * hitNz )

Definition at line 866 of file collision.c.

867 {
868 Collider* collider;
869 CollisionData* collisionData;
870 ColliderTriangle* triangle;
871 s32 i, j;
872 s32 colliderID;
873
874 collisionData = &gZoneCollisionData;
875 gCollisionRayDirX = dirX;
876 gCollisionRayDirY = dirY;
877 gCollisionRayDirZ = dirZ;
878 gCollisionRayStartX = startX;
879 gCollisionRayStartY = startY;
880 gCollisionRayStartZ = startZ;
881 gCollisionRayLength = *hitDepth;
882 colliderID = NO_COLLIDER;
883
884 for (i = 0; i < collisionData->numColliders; i++) {
885 collider = &collisionData->colliderList[i];
886
887 if (collider->flags & COLLIDER_FLAG_IGNORE_PLAYER)
888 continue;
889
890 if (collider->numTriangles == 0 || collider->aabb == NULL)
891 continue;
892
893 triangle = collider->triangleTable;
894 for (j = 0; j < collider->numTriangles; j++) {
895 if (test_ray_triangle_down(triangle++, collisionData->vertices)) {
896 colliderID = i;
897 }
898 }
899 }
900
901 if (colliderID > NO_COLLIDER) {
902 *hitX = gCollisionPointX;
903 *hitY = gCollisionPointY;
904 *hitZ = gCollisionPointZ;
905 *hitDepth = gCollisionRayLength;
906 *hitNx = gCollisionNormalX;
907 *hitNy = gCollisionNormalY;
908 *hitNz = gCollisionNormalZ;
909 return colliderID;
910 } else {
911 return colliderID;
912 }
913}
@ COLLIDER_FLAG_IGNORE_PLAYER
Definition enums.h:4696

Referenced by test_ray_zone(), and test_ray_zone_aabb().

◆ test_ray_collider_horizontal()

f32 test_ray_collider_horizontal ( s32 ignoreFlags,
s32 colliderID,
f32 x,
f32 y,
f32 z,
f32 length,
f32 yaw )

Definition at line 915 of file collision.c.

915 {
916 CollisionData* collisionData = &gCollisionData;
917 f32 cosTheta;
918 f32 sinTheta;
919 Collider* collider;
920 ColliderTriangle* triangleTable;
921 s32 i;
922 f32 ret;
923
924 sin_cos_rad(DEG_TO_RAD(yaw), &sinTheta, &cosTheta);
925 collider = &collisionData->colliderList[colliderID];
926
931 gCollisionRayLength = length;
932 gCollisionRayDirX = sinTheta;
933 gCollisionRayDirZ = -cosTheta;
934 ret = -1.0f;
935
936 if (!(collider->flags & ignoreFlags) && collider->numTriangles != 0) {
937 triangleTable = collider->triangleTable;
938
939 for (i = 0; i < collider->numTriangles; i++)
940 if (test_ray_triangle_horizontal(triangleTable++, collisionData->vertices))
942 }
943
944 return ret;
945}
void sin_cos_rad(f32 rad, f32 *outSinTheta, f32 *outCosTheta)
Definition 43F0.c:706
#define DEG_TO_RAD(deg)
Definition macros.h:134

◆ test_ray_entities()

s32 test_ray_entities ( f32 startX,
f32 startY,
f32 startZ,
f32 dirX,
f32 dirY,
f32 dirZ,
f32 * hitX,
f32 * hitY,
f32 * hitZ,
f32 * hitDepth,
f32 * hitNx,
f32 * hitNy,
f32 * hitNz )

Test a general ray from a given starting position and direction against all entities.

If one is hit, returns the position and normal of the hit and the length along the ray on the output params. All output params are invalid when a value of NO_COLLIDER is returned.

Parameters
startXorigin x position of the ray
startYorigin y position of the ray
startZorigin z position of the ray
dirXnormalized x direction of the ray
dirYnormalized y direction of the ray
dirZnormalized z direction of the ray
[out]hitXnormalized x position of the hit
[out]hitYnormalized y position of the hit
[out]hitZnormalized z position of the hit
[in,out]hitDepthas input, maximum length of the ray; as output, distance along the ray of the hit
[out]hitNxx normal direction of the hit
[out]hitNyy normal direction of the hit
[out]hitNzz normal direction of the hit
Returns
entity index or NO_COLLIDER is none is hit

Definition at line 947 of file collision.c.

948 {
949 f32 hitDepthDown, hitDepthHoriz;
950 s32 type;
951 s32 i, j;
952 Entity* entity;
953 Matrix4f tempMatrix1;
954 Matrix4f tempMatrix2;
955 Vec3f boxVertices[8];
956 ColliderTriangle entityTriangle;
957 s32 entityIndex;
958 f32 h;
959 f32 aabbX, aabbZ;
960 s32 hasCollision;
961 f32 dist, dist2;
962 ColliderTriangle *triangle = &entityTriangle;
963
964 enum {
965 ENTITY_TEST_ANY = 0,
966 ENTITY_TEST_DOWN = 1,
967 ENTITY_TEST_LATERAL = 2,
968 };
969
970 entityIndex = NO_COLLIDER;
971 type = ENTITY_TEST_ANY;
972 hitDepthDown = hitDepthHoriz = *hitDepth;
973
974 if (dirX == 0 && dirZ == 0 && dirY < 0) {
975 hitDepthHoriz = 0;
976 type = ENTITY_TEST_DOWN;
977 } else if (dirY == 0) {
978 hitDepthDown = 0;
979 type = ENTITY_TEST_LATERAL;
980 }
981
983 triangle->oneSided = TRUE;
984 for (i = 0; i < MAX_ENTITIES; i++) {
985 entity = get_entity_by_index(i);
986
987 if (entity == NULL || (entity->flags & (ENTITY_FLAG_SKIP_UPDATE | ENTITY_FLAG_DISABLE_COLLISION))) {
988 continue;
989 }
990
991 dist = hitDepthHoriz + entity->effectiveSize;
992 if (startX > entity->pos.x + dist || startX < entity->pos.x - dist) {
993 continue;
994 }
995
996 if (startZ > entity->pos.z + dist || startZ < entity->pos.z - dist) {
997 continue;
998 }
999
1000 switch (type) {
1001 case ENTITY_TEST_ANY:
1002 case ENTITY_TEST_DOWN:
1003 dist = entity->pos.y;
1004 dist2 = hitDepthDown + entity->effectiveSize * 2;
1005 if (dist + dist2 < startY || startY < dist - dist2) {
1006 continue;
1007 }
1008 break;
1009 case ENTITY_TEST_LATERAL:
1010 dist = entity->pos.y;
1011 dist2 = entity->effectiveSize * 2;
1012 if (dist + dist2 < startY || startY < dist - dist2) {
1013 continue;
1014 }
1015 break;
1016 }
1017
1018 aabbX = entity->aabb.x / 2;
1019 aabbZ = entity->aabb.z / 2;
1020
1021 boxVertices[1].x = boxVertices[2].x = boxVertices[5].x = boxVertices[6].x = -aabbX;
1022 boxVertices[0].x = boxVertices[3].x = boxVertices[4].x = boxVertices[7].x = aabbX;
1023 boxVertices[0].y = boxVertices[1].y = boxVertices[2].y = boxVertices[3].y = 0;
1024 boxVertices[4].y = boxVertices[5].y = boxVertices[6].y = boxVertices[7].y = entity->aabb.y;
1025 boxVertices[0].z = boxVertices[1].z = boxVertices[4].z = boxVertices[5].z = aabbZ;
1026 boxVertices[2].z = boxVertices[3].z = boxVertices[6].z = boxVertices[7].z = -aabbZ;
1027
1028 guMtxXFMF(entity->inverseTransformMatrix, dirX, dirY, dirZ, &gCollisionRayDirX, &gCollisionRayDirY, &gCollisionRayDirZ);
1029 guMtxXFMF(entity->inverseTransformMatrix, startX - entity->pos.x, startY - entity->pos.y,
1031
1032 for (j = 0; j < 12; j++) {
1033 Vec3f* v1 = triangle->v1 = &boxVertices[gEntityColliderFaces[j].x];
1034 Vec3f* v2 = triangle->v2 = &boxVertices[gEntityColliderFaces[j].y];
1035 Vec3f* v3 = triangle->v3 = &boxVertices[gEntityColliderFaces[j].z];
1036 triangle->e13.x = v3->x - v1->x;
1037 triangle->e13.y = v3->y - v1->y;
1038 triangle->e13.z = v3->z - v1->z;
1039 triangle->e21.x = v1->x - v2->x;
1040 triangle->e21.y = v1->y - v2->y;
1041 triangle->e21.z = v1->z - v2->z;
1042 triangle->e32.x = v2->x - v3->x;
1043 triangle->e32.y = v2->y - v3->y;
1044 triangle->e32.z = v2->z - v3->z;
1045 triangle->normal.x = gEntityColliderNormals[j].x;
1046 triangle->normal.y = gEntityColliderNormals[j].y;
1047 triangle->normal.z = gEntityColliderNormals[j].z;
1048
1049 if (hasCollision = test_ray_triangle_general(&entityTriangle, boxVertices)) {
1050 break;
1051 }
1052 }
1053
1054 if (hasCollision && gCollisionRayLength < *hitDepth) {
1055 entityIndex = i;
1056 *hitDepth = gCollisionRayLength;
1057
1058 switch (type) {
1059 case ENTITY_TEST_ANY:
1060 hitDepthDown = gCollisionRayLength;
1061 hitDepthHoriz = gCollisionRayLength;
1062 break;
1063 case ENTITY_TEST_DOWN:
1064 hitDepthDown = gCollisionRayLength;
1065 break;
1066 case ENTITY_TEST_LATERAL:
1067 hitDepthHoriz = gCollisionRayLength;
1068 break;
1069 }
1070
1071 guRotateF(tempMatrix1, entity->rot.x, 1.0f, 0.0f, 0.0f);
1072 guRotateF(tempMatrix2, entity->rot.z, 0.0f, 0.0f, 1.0f);
1073 guMtxCatF(tempMatrix1, tempMatrix2, tempMatrix1);
1074 guRotateF(tempMatrix2, entity->rot.y, 0.0f, 1.0f, 0.0f);
1075 guMtxCatF(tempMatrix1, tempMatrix2, tempMatrix1);
1076 guTranslateF(tempMatrix2, entity->pos.x, entity->pos.y, entity->pos.z);
1077 guMtxCatF(tempMatrix1, tempMatrix2, tempMatrix1);
1078 guMtxXFMF(tempMatrix1, gCollisionPointX, gCollisionPointY, gCollisionPointZ, hitX, hitY, hitZ);
1079
1081 *hitNx = gCollisionNormalX * h;
1082 *hitNy = gCollisionNormalY * h;
1083 *hitNz = gCollisionNormalZ * h;
1084 }
1085 }
1086
1087 return entityIndex;
1088}
Vec3f gEntityColliderNormals[]
Definition collision.c:63
Vec3s gEntityColliderFaces[]
Definition collision.c:54
Vec3s pos
Definition demo_api.c:17
#define guRotateF
#define guTranslateF
@ ENTITY_FLAG_SKIP_UPDATE
Definition enums.h:2643
@ ENTITY_FLAG_DISABLE_COLLISION
Definition enums.h:2618
Entity * get_entity_by_index(s32 index)
Definition entity.c:530
#define MAX_ENTITIES
Definition macros.h:94
Matrix4f inverseTransformMatrix
f32 effectiveSize

Referenced by entity_raycast_down(), npc_raycast_down(), npc_raycast_general(), npc_raycast_up(), npc_raycast_up_corner(), player_raycast_down(), player_raycast_general(), and player_raycast_up_corner().

Variable Documentation

◆ gCollisionData

◆ gZoneCollisionData

◆ gCollisionRayStartX

◆ gCollisionRayStartY

◆ gCollisionRayStartZ

◆ gCollisionRayDirX

◆ gCollisionRayDirY

◆ gCollisionRayDirZ

◆ gCollisionPointX

◆ gCollisionPointY

◆ gCollisionPointZ

◆ gCollisionRayLength

◆ gCollisionNormalX

◆ gCollisionNormalY

◆ gCollisionNormalZ

◆ gCollisionDataBackup

BSS ColliderBackupEntry* gCollisionDataBackup

Definition at line 51 of file collision.c.

Referenced by backup_map_collision_data(), and restore_map_collision_data().

◆ gCollisionDataZoneBackup

BSS ColliderBackupEntry* gCollisionDataZoneBackup

Definition at line 52 of file collision.c.

Referenced by backup_map_collision_data(), and restore_map_collision_data().

◆ gEntityColliderFaces

Vec3s gEntityColliderFaces[]
Initial value:
= {
{ 4, 6, 5 }, { 4, 7, 6 },
{ 0, 3, 4 }, { 3, 7, 4 },
{ 3, 2, 7 }, { 2, 6, 7 },
{ 2, 1, 6 }, { 1, 5, 6 },
{ 1, 0, 5 }, { 0, 4, 5 },
{ 0, 1, 2 }, { 0, 2, 3 },
}

Definition at line 54 of file collision.c.

54 {
55 { 4, 6, 5 }, { 4, 7, 6 },
56 { 0, 3, 4 }, { 3, 7, 4 },
57 { 3, 2, 7 }, { 2, 6, 7 },
58 { 2, 1, 6 }, { 1, 5, 6 },
59 { 1, 0, 5 }, { 0, 4, 5 },
60 { 0, 1, 2 }, { 0, 2, 3 },
61};

Referenced by test_ray_entities().

◆ gEntityColliderNormals

Vec3f gEntityColliderNormals[]
Initial value:
= {
{ 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f },
{ 1.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f }, { 0.0f, 0.0f, -1.0f },
{ -1.0f, 0.0f, 0.0f }, { -1.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
{ 0.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f },
}

Definition at line 63 of file collision.c.

63 {
64 { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f },
65 { 1.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f },
66 { 0.0f, 0.0f, -1.0f }, { 0.0f, 0.0f, -1.0f },
67 { -1.0f, 0.0f, 0.0f }, { -1.0f, 0.0f, 0.0f },
68 { 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
69 { 0.0f, -1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f },
70};

Referenced by test_ray_entities().