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 },
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 },
167 if (hitName == NULL) {
192 Vec3s* assetVertices;
194 u32* assetBoundingBox;
201 f32 e13_y, e21_z, e13_z, e21_y, e21_x, e13_x, normalX, normalY, normalZ, coeff;
203 assetCollisionData = NULL;
204 collisionData = NULL;
211 if (collisionOffset == 0) {
215 assetCollisionData = (
HitFileHeader*)((
void*)hit + collisionOffset);
220 if (collisionOffset == 0) {
224 assetCollisionData = (
HitFileHeader*)((
void*)hit + collisionOffset);
231 for (i = 0, boundingBox = (u32*)(collisionData->aabbs); i < assetCollisionData->
boundingBoxesDataSize;
232 assetBoundingBox++, boundingBox++, i++) {
233 *boundingBox = *assetBoundingBox;
239 vertices++, assetVertices++, i++) {
240 vertices->
x = assetVertices->
x;
241 vertices->
y = assetVertices->
y;
242 vertices->
z = assetVertices->
z;
248 for (i = 0; i < assetCollisionData->
numColliders; assetCollider++, collider++, i++) {
260 collider->aabb = NULL;
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;
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;
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;
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;
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);
307 coeff = 1.0f /
sqrtf(coeff);
312 triangle->normal.x = normalX * coeff;
313 triangle->normal.y = normalY * coeff;
314 triangle->normal.z = normalZ * coeff;
324 Vec3f** vertexBuffer;
326 s32 vertexBufferSize;
335 vertexBufferSize = 0;
336 vertexPtr = vertexBuffer;
346 for (i = 0, vertexTable = collider->
vertexTable; i < vertexBufferSize; vertexPtr++, vertexTable += 2, i++) {
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;
366 for (i = 0; i < *bufSize; i++) {
367 if (buf[i] == vert) {
381 for (i = 0; i < *bufferSize; i++) {
382 if (*buffer == vert) {
397 f32 min_x, min_y, min_z, max_x, max_y, max_z;
399 f32 e13_y, e21_z, e13_z, e21_y, e21_x, e13_x, normalX, normalY, normalZ, coeff;
407 guMtxL2F(matrix, (Mtx*)model->
bakedMtx);
414 min_x = min_y = min_z = 999999.9f;
415 max_x = max_y = max_z = -999999.9f;
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);
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;
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;
441 for (i = 0; i < collider->
numTriangles; triangle++, i++) {
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;
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;
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);
470 coeff = 1.0f /
sqrtf(coeff);
475 triangle->
normal.
x = normalX * coeff;
476 triangle->
normal.
y = normalY * coeff;
477 triangle->
normal.
z = normalZ * coeff;
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;
506 f32 distToTrianglePlane;
526 if (distToTrianglePlane < 0) {
562 ) * distToTrianglePlane < 0)
570 ) * distToTrianglePlane < 0)
578 ) * distToTrianglePlane < 0)
603 f32 distToTrianglePlane, cosAngle;
621 if (distToTrianglePlane < 0) {
640 if (triangle->
normal.
y * distToTrianglePlane <= 0) {
657 cosAngle = -triangle->
normal.
y;
676 f32 distToTrianglePlane, cosAngle;
694 if (distToTrianglePlane < 0) {
768s32
test_ray_colliders(s32 ignoreFlags, f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ,
769 f32* hitX, f32* hitY, f32* hitZ, f32* hitDepth, f32* hitNx, f32* hitNy, f32* hitNz) {
775 f32 min_x, min_y, min_z, max_x, max_y, max_z;
777 if (dirX == 0 && dirY == 0 && dirZ == 0) {
818 if ((collider->
flags & ignoreFlags) ||
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)
866s32
test_ray_zones(f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ,
867 f32* hitX, f32* hitY, f32* hitZ, f32* hitDepth, f32* hitNx, f32* hitNy, f32* hitNz) {
890 if (collider->
numTriangles == 0 || collider->aabb == NULL)
948 f32* hitX, f32* hitY, f32* hitZ, f32* hitDepth, f32* hitNx, f32* hitNy, f32* hitNz) {
949 f32 hitDepthDown, hitDepthHoriz;
955 Vec3f boxVertices[8];
966 ENTITY_TEST_DOWN = 1,
967 ENTITY_TEST_LATERAL = 2,
971 type = ENTITY_TEST_ANY;
972 hitDepthDown = hitDepthHoriz = *hitDepth;
974 if (dirX == 0 && dirZ == 0 && dirY < 0) {
976 type = ENTITY_TEST_DOWN;
977 }
else if (dirY == 0) {
979 type = ENTITY_TEST_LATERAL;
992 if (startX > entity->
pos.
x + dist || startX < entity->
pos.
x - dist) {
996 if (startZ > entity->
pos.
z + dist || startZ < entity->
pos.
z - dist) {
1001 case ENTITY_TEST_ANY:
1002 case ENTITY_TEST_DOWN:
1003 dist = entity->
pos.
y;
1005 if (dist + dist2 < startY || startY < dist - dist2) {
1009 case ENTITY_TEST_LATERAL:
1010 dist = entity->
pos.
y;
1012 if (dist + dist2 < startY || startY < dist - dist2) {
1018 aabbX = entity->
aabb.
x / 2;
1019 aabbZ = entity->
aabb.
z / 2;
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;
1032 for (j = 0; j < 12; j++) {
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;
1059 case ENTITY_TEST_ANY:
1063 case ENTITY_TEST_DOWN:
1066 case ENTITY_TEST_LATERAL:
1073 guMtxCatF(tempMatrix1, tempMatrix2, tempMatrix1);
1075 guMtxCatF(tempMatrix1, tempMatrix2, tempMatrix1);
1077 guMtxCatF(tempMatrix1, tempMatrix2, tempMatrix1);
void load_map_hit_asset(void)
BSS f32 gCollisionNormalY
BSS ColliderBackupEntry * gCollisionDataZoneBackup
BSS f32 gCollisionRayStartZ
BSS f32 gCollisionNormalX
CollisionData gZoneCollisionData
s32 collision_heap_create(void)
void load_battle_hit_asset(const char *hitName)
BSS f32 gCollisionNormalZ
s32 get_collider_flags(s32 colliderID)
void backup_map_collision_data(void)
s32 _get_hit_vert_index_from_buffer(Vec3f **buffer, Vec3f *vert, s32 *bufferSize)
void get_flat_collider_normal(s32 colliderID, f32 *x, f32 *y, f32 *z)
BSS ColliderBackupEntry * gCollisionDataBackup
void update_collider_transform(s16 colliderID)
void initialize_collision(void)
BSS f32 gCollisionRayStartY
BSS f32 gCollisionRayLength
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)
void load_hit_data(s32 idx, HitFile *hit)
void collision_heap_free(void *)
BSS f32 gCollisionRayDirX
CollisionData gCollisionData
void get_collider_center(s32 colliderID, f32 *x, f32 *y, f32 *z)
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.
s32 test_ray_triangle_down(ColliderTriangle *triangle, Vec3f *vertices)
BSS f32 gCollisionRayStartX
s32 test_ray_triangle_general(ColliderTriangle *triangle, Vec3f *vertices)
Vec3f gEntityColliderNormals[]
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)
s16 boundingBoxesDataSize
void _add_hit_vert_to_buffer(Vec3f **buf, Vec3f *vert, s32 *bufSize)
BSS f32 gCollisionRayDirZ
void parent_collider_to_model(s16 colliderID, s16 modelIndex)
void * collision_heap_malloc(s32 size)
void restore_map_collision_data(void)
s32 test_ray_triangle_horizontal(ColliderTriangle *triangle, Vec3f *vertices)
Vec3s gEntityColliderFaces[]
f32 test_ray_collider_horizontal(s32 ignoreFlags, s32 colliderID, f32 x, f32 y, f32 z, f32 length, f32 yaw)
BSS f32 gCollisionRayDirY
struct ColliderTriangle * triangleTable
#define general_heap_malloc
@ COLLIDER_FLAG_IGNORE_PLAYER
@ COLLIDER_FLAG_HAS_MODEL_PARENT
@ ENTITY_FLAG_SKIP_UPDATE
@ ENTITY_FLAG_DISABLE_COLLISION
Entity * get_entity_by_index(s32 index)
void * load_asset_by_name(const char *assetName, u32 *decompressedSize)
struct Model * get_model_from_list_index(s32 listIndex)
void copy_matrix(Matrix4f src, Matrix4f dest)
s32 general_heap_free(void *data)
void decode_yay0(void *src, void *dst)
void sin_cos_rad(f32 rad, f32 *outSinTheta, f32 *outCosTheta)
void * heap_malloc(s32 size)
Matrix4f userTransformMtx
#define COLLISION_WITH_ENTITY_BIT
MapSettings * get_current_map_settings(void)
s32 hitAssetCollisionOffset
Fields other than main, entryList, entryCount, background, and tattle are initialised when the map lo...
Matrix4f inverseTransformMatrix