1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-12-25 22:26:12 +00:00

Match Retail BgCheck (#1734)

* 2 funcs left

* so close

* bgcheck OK
This commit is contained in:
engineer124 2024-02-09 00:47:07 +11:00 committed by GitHub
parent e48cdaf598
commit 63f0033fe5
No account linked to committer's email address

View file

@ -79,6 +79,7 @@ u16 sSurfaceMaterialToSfxOffset[SURFACE_MATERIAL_MAX] = {
SURFACE_SFX_OFFSET_CARPET, // SURFACE_MATERIAL_CARPET
};
#if OOT_DEBUG
/**
* original name: T_BGCheck_PosErrorCheck
*/
@ -94,6 +95,7 @@ s32 BgCheck_PosErrorCheck(Vec3f* pos, char* file, s32 line) {
}
return false;
}
#endif
/**
* Set SSNode
@ -194,30 +196,24 @@ void BgCheck_Vec3fToVec3s(Vec3s* dst, Vec3f* src) {
* Get CollisionPoly's lowest y point
*/
s16 CollisionPoly_GetMinY(CollisionPoly* poly, Vec3s* vtxList) {
s32 a;
s32 b;
s32 c;
s16 min;
//! @bug Due to rounding errors, some polys with a slight slope have a y normal of 1.0f/-1.0f. As such, this
//! optimization returns the wrong minimum y for a subset of these polys.
if (poly->normal.y == COLPOLY_SNORMAL(1.0f) || poly->normal.y == COLPOLY_SNORMAL(-1.0f)) {
return vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)].y;
}
} else {
s32 a = COLPOLY_VTX_INDEX(poly->flags_vIA);
s32 b = COLPOLY_VTX_INDEX(poly->flags_vIB);
s32 c = poly->vIC;
s16 min = vtxList[a].y;
a = COLPOLY_VTX_INDEX(poly->flags_vIA);
b = COLPOLY_VTX_INDEX(poly->flags_vIB);
c = poly->vIC;
min = vtxList[a].y;
if (min > vtxList[b].y) {
min = vtxList[b].y;
if (min > vtxList[b].y) {
min = vtxList[b].y;
}
if (min < vtxList[c].y) {
return min;
}
return vtxList[c].y;
}
if (min < vtxList[c].y) {
return min;
}
return vtxList[c].y;
}
/**
@ -491,8 +487,8 @@ void StaticLookup_AddPolyToSSList(CollisionContext* colCtx, SSList* ssList, Coll
SSNode* curNode;
SSNode* nextNode;
s32 polyYMin;
u16 newNodeId;
s16 curPolyId;
u16 newNodeId;
// if list is null
if (ssList->head == SS_NULL) {
@ -514,6 +510,8 @@ void StaticLookup_AddPolyToSSList(CollisionContext* colCtx, SSList* ssList, Coll
while (true) {
// if at the end of the list
if (curNode->next == SS_NULL) {
s32 pad;
newNodeId = SSNodeList_GetNextNodeIdx(&colCtx->polyNodes);
SSNode_SetValue(&colCtx->polyNodes.tbl[newNodeId], &polyId, SS_NULL);
curNode->next = newNodeId;
@ -681,8 +679,8 @@ s32 BgCheck_ComputeWallDisplacement(CollisionContext* colCtx, CollisionPoly* pol
s32 BgCheck_SphVsStaticWall(StaticLookup* lookup, CollisionContext* colCtx, u16 xpFlags, f32* outX, f32* outZ,
Vec3f* pos, f32 radius, CollisionPoly** outPoly) {
Vec3f resultPos;
f32 temp_f2;
f32 temp_f2_2;
f32 zTemp;
f32 xTemp;
f32 planeDist;
f32 intersect;
s32 result;
@ -690,17 +688,14 @@ s32 BgCheck_SphVsStaticWall(StaticLookup* lookup, CollisionContext* colCtx, u16
CollisionPoly* polyList;
SSNode* curNode;
f32 invNormalXZ;
f32 zTemp;
f32 xTemp;
s32 polyId;
f32 normalXZ;
f32 nx;
f32 ny;
f32 nz;
f32 temp_f16;
s32 pad;
Vec3s* vtxList;
u16 pad;
f32 temp_f16;
f32 zMin;
f32 zMax;
f32 xMin;
@ -780,8 +775,10 @@ s32 BgCheck_SphVsStaticWall(StaticLookup* lookup, CollisionContext* colCtx, u16
}
}
if (CollisionPoly_CheckZIntersectApprox(curPoly, vtxList, resultPos.x, pos->y, &intersect)) {
if (fabsf(intersect - resultPos.z) <= radius / temp_f16) {
if ((intersect - resultPos.z) * nz <= 4.0f) {
f32 zIntersectDist = intersect - resultPos.z;
if (fabsf(zIntersectDist) <= radius / temp_f16) {
if (zIntersectDist * nz <= 4.0f) {
BgCheck_ComputeWallDisplacement(colCtx, curPoly, &resultPos.x, &resultPos.z, nx, ny, nz,
invNormalXZ, planeDist, radius, outPoly);
result = true;
@ -790,9 +787,8 @@ s32 BgCheck_SphVsStaticWall(StaticLookup* lookup, CollisionContext* colCtx, u16
}
if (curNode->next == SS_NULL) {
break;
} else {
curNode = &colCtx->polyNodes.tbl[curNode->next];
}
curNode = &colCtx->polyNodes.tbl[curNode->next];
}
curNode = &colCtx->polyNodes.tbl[lookup->wall.head];
@ -861,8 +857,10 @@ s32 BgCheck_SphVsStaticWall(StaticLookup* lookup, CollisionContext* colCtx, u16
}
}
if (CollisionPoly_CheckXIntersectApprox(curPoly, vtxList, pos->y, resultPos.z, &intersect)) {
if (fabsf(intersect - resultPos.x) <= radius / temp_f16) {
if ((intersect - resultPos.x) * nx <= 4.0f) {
f32 xIntersectDist = intersect - resultPos.x;
if (fabsf(xIntersectDist) <= radius / temp_f16) {
if (xIntersectDist * nx <= 4.0f) {
BgCheck_ComputeWallDisplacement(colCtx, curPoly, &resultPos.x, &resultPos.z, nx, ny, nz,
invNormalXZ, planeDist, radius, outPoly);
result = true;
@ -871,10 +869,8 @@ s32 BgCheck_SphVsStaticWall(StaticLookup* lookup, CollisionContext* colCtx, u16
}
if (curNode->next == SS_NULL) {
break;
} else {
curNode = &colCtx->polyNodes.tbl[curNode->next];
continue;
}
curNode = &colCtx->polyNodes.tbl[curNode->next];
}
*outX = resultPos.x;
@ -909,6 +905,9 @@ s32 BgCheck_CheckStaticCeiling(StaticLookup* lookup, u16 xpFlags, CollisionConte
*outY = pos->y;
while (true) {
f32 intersectDist;
f32 ny;
curPolyId = curNode->polyId;
if (COLPOLY_VTX_CHECK_FLAGS_ANY(colCtx->colHeader->polyList[curPolyId].flags_vIA, xpFlags)) {
if (curNode->next == SS_NULL) {
@ -921,8 +920,8 @@ s32 BgCheck_CheckStaticCeiling(StaticLookup* lookup, u16 xpFlags, CollisionConte
curPoly = &polyList[curPolyId];
if (CollisionPoly_CheckYIntersectApprox2(curPoly, vtxList, pos->x, pos->z, &ceilingY)) {
f32 intersectDist = ceilingY - *outY;
f32 ny = COLPOLY_GET_NORMAL(curPoly->normal.y);
intersectDist = ceilingY - *outY;
ny = COLPOLY_GET_NORMAL(curPoly->normal.y);
if (intersectDist > 0.0f && intersectDist < checkHeight && intersectDist * ny <= 0) {
*outY = ceilingY - checkHeight;
@ -958,7 +957,6 @@ s32 BgCheck_CheckLineAgainstSSList(SSList* ssList, CollisionContext* colCtx, u16
s32 result;
f32 minY;
f32 distSq;
s16 polyId;
result = false;
polyList = colCtx->colHeader->polyList;
@ -968,7 +966,8 @@ s32 BgCheck_CheckLineAgainstSSList(SSList* ssList, CollisionContext* colCtx, u16
curNode = &colCtx->polyNodes.tbl[ssList->head];
while (true) {
polyId = curNode->polyId;
s16 polyId = curNode->polyId;
checkedPoly = &colCtx->polyNodes.polyCheckTbl[polyId];
if (*checkedPoly == true || COLPOLY_VTX_CHECK_FLAGS_ANY(polyList[polyId].flags_vIA, xpFlags1) ||
@ -1051,13 +1050,12 @@ s32 BgCheck_SphVsFirstStaticPolyList(SSNode* node, u16 xpFlags, CollisionContext
CollisionPoly** outPoly) {
CollisionPoly* polyList = colCtx->colHeader->polyList;
Vec3s* vtxList = colCtx->colHeader->vtxList;
CollisionPoly* curPoly;
u16 nextId;
s16 curPolyId;
while (true) {
curPolyId = node->polyId;
curPoly = &polyList[curPolyId];
u16 nextId;
s16 curPolyId = node->polyId;
CollisionPoly* curPoly = &polyList[curPolyId];
if (COLPOLY_VTX_CHECK_FLAGS_ANY(colCtx->colHeader->polyList[curPolyId].flags_vIA, xpFlags)) {
if (node->next == SS_NULL) {
break;
@ -1542,10 +1540,10 @@ void BgCheck_Allocate(CollisionContext* colCtx, PlayState* play, CollisionHeader
u32 tblMax;
u32 memSize;
u32 lookupTblMemSize;
SSNodeList* nodeList;
s32 useCustomSubdivisions;
u32 customMemSize;
s32 customNodeListMax;
SSNodeList* nodeList;
u32 customMemSize;
s32 useCustomSubdivisions;
s32 i;
colCtx->colHeader = colHeader;
@ -1717,11 +1715,15 @@ f32 BgCheck_RaycastDownImpl(PlayState* play, CollisionContext* colCtx, u16 xpFla
if (checkPos.y < colCtx->minBounds.y) {
break;
}
#if OOT_DEBUG
if (BgCheck_PosErrorCheck(&checkPos, "../z_bgcheck.c", 4410)) {
if (actor != NULL) {
PRINTF("こいつ,pself_actor->name %d\n", actor->id);
}
}
#endif
lookup = BgCheck_GetStaticLookup(colCtx, lookupTbl, &checkPos);
if (lookup == NULL) {
checkPos.y -= colCtx->subdivLength.y;
@ -1735,16 +1737,16 @@ f32 BgCheck_RaycastDownImpl(PlayState* play, CollisionContext* colCtx, u16 xpFla
checkPos.y -= colCtx->subdivLength.y;
}
dynaRaycastDown.play = play;
dynaRaycastDown.colCtx = colCtx;
dynaRaycastDown.xpFlags = xpFlags;
dynaRaycastDown.resultPoly = outPoly;
dynaRaycastDown.yIntersect = yIntersect;
dynaRaycastDown.pos = pos;
dynaRaycastDown.bgId = outBgId;
dynaRaycastDown.actor = actor;
dynaRaycastDown.downChkFlags = downChkFlags;
dynaRaycastDown.chkDist = chkDist;
dynaRaycastDown.play = play;
dynaRaycastDown.resultPoly = outPoly;
dynaRaycastDown.bgId = outBgId;
yIntersectDyna = BgCheck_RaycastDownDyna(&dynaRaycastDown);
@ -1951,11 +1953,11 @@ s32 BgCheck_CheckWallImpl(CollisionContext* colCtx, u16 xpFlags, Vec3f* posResul
Vec3f checkLinePrev;
f32 n2XZDist;
f32 n3XZDist;
f32 nx3, nz3;
s32 bccFlags;
f32 nx;
f32 nz;
Vec3f posIntersect2;
s32 bgId2;
f32 nx, ny, nz; // unit normal of polygon
result = false;
*outBgId = BGCHECK_SCENE;
@ -1966,12 +1968,14 @@ s32 BgCheck_CheckWallImpl(CollisionContext* colCtx, u16 xpFlags, Vec3f* posResul
dy = posNext->y - posPrev->y;
dz = posNext->z - posPrev->z;
#if OOT_DEBUG
if (BgCheck_PosErrorCheck(posNext, "../z_bgcheck.c", 4831) == true ||
BgCheck_PosErrorCheck(posPrev, "../z_bgcheck.c", 4832) == true) {
if (actor != NULL) {
PRINTF("こいつ,pself_actor->name %d\n", actor->id);
}
}
#endif
// if there's movement on the xz plane, and argA flag is 0,
if ((dx != 0.0f || dz != 0.0f) && (argA & 1) == 0) {
@ -1980,7 +1984,8 @@ s32 BgCheck_CheckWallImpl(CollisionContext* colCtx, u16 xpFlags, Vec3f* posResul
result = BgCheck_CheckLineImpl(colCtx, xpFlags, COLPOLY_IGNORE_NONE, posPrev, posNext, &posIntersect, &poly,
&bgId, actor, 1.0f, BGCHECK_CHECK_ALL & ~BGCHECK_CHECK_CEILING);
if (result) {
ny = COLPOLY_GET_NORMAL(poly->normal.y);
f32 ny = COLPOLY_GET_NORMAL(poly->normal.y);
// if poly is floor, push result underneath the floor
if (ny > 0.5f) {
posResult->x = posIntersect.x;
@ -2061,8 +2066,9 @@ s32 BgCheck_CheckWallImpl(CollisionContext* colCtx, u16 xpFlags, Vec3f* posResul
if (dynaPolyCollision == true || *outBgId != BGCHECK_SCENE) {
if (BgCheck_CheckLineImpl(colCtx, xpFlags, COLPOLY_IGNORE_NONE, posPrev, posResult, &posIntersect2, &poly,
&bgId2, actor, 1.0f, BGCHECK_CHECK_ONE_FACE | BGCHECK_CHECK_WALL)) {
nx3 = COLPOLY_GET_NORMAL(poly->normal.x);
nz3 = COLPOLY_GET_NORMAL(poly->normal.z);
f32 nx3 = COLPOLY_GET_NORMAL(poly->normal.x);
f32 nz3 = COLPOLY_GET_NORMAL(poly->normal.z);
n3XZDist = sqrtf(SQ(nx3) + SQ(nz3));
// if poly is not a "flat" floor or "flat" ceiling
@ -2155,11 +2161,15 @@ s32 BgCheck_CheckCeilingImpl(CollisionContext* colCtx, u16 xpFlags, f32* outY, V
*outBgId = BGCHECK_SCENE;
*outY = pos->y;
#if OOT_DEBUG
if (BgCheck_PosErrorCheck(pos, "../z_bgcheck.c", 5206) == true) {
if (actor != NULL) {
PRINTF("こいつ,pself_actor->name %d\n", actor->id);
}
}
#endif
lookupTbl = colCtx->lookupTbl;
if (!BgCheck_PosInStaticBoundingBox(colCtx, pos)) {
return false;
@ -2222,13 +2232,10 @@ s32 BgCheck_CheckLineImpl(CollisionContext* colCtx, u16 xpFlags1, u16 xpFlags2,
Vec3f posBTemp = *posB;
Vec3f sectorMin;
Vec3f sectorMax;
s32 k;
StaticLookup* lookup;
s32 j;
StaticLookup* jLookup;
s32 temp_lo;
*outBgId = BGCHECK_SCENE;
#if OOT_DEBUG
if (BgCheck_PosErrorCheck(posA, "../z_bgcheck.c", 5334) == true ||
BgCheck_PosErrorCheck(posB, "../z_bgcheck.c", 5335) == true) {
if (actor != NULL) {
@ -2237,6 +2244,7 @@ s32 BgCheck_CheckLineImpl(CollisionContext* colCtx, u16 xpFlags1, u16 xpFlags2,
PRINTF("pself_actor == NULLで犯人不明\n");
}
}
#endif
BgCheck_ResetPolyCheckTbl(&colCtx->polyNodes, colCtx->colHeader->numPolygons);
BgCheck_GetStaticLookupIndicesFromPos(colCtx, posA, (Vec3i*)&subdivMin);
@ -2247,6 +2255,10 @@ s32 BgCheck_CheckLineImpl(CollisionContext* colCtx, u16 xpFlags1, u16 xpFlags2,
*outPoly = NULL;
if (subdivMin[0] != subdivMax[0] || subdivMin[1] != subdivMax[1] || subdivMin[2] != subdivMax[2]) {
s32 k;
s32 temp_lo;
s32 j;
for (i = 0; i < 3; i++) {
if (subdivMax[i] < subdivMin[i]) {
j = subdivMax[i];
@ -2260,12 +2272,14 @@ s32 BgCheck_CheckLineImpl(CollisionContext* colCtx, u16 xpFlags1, u16 xpFlags2,
sectorMax.z = colCtx->subdivLength.z + sectorMin.z;
for (i = subdivMin[2]; i < subdivMax[2] + 1; i++) {
jLookup = iLookup + subdivMin[1] * colCtx->subdivAmount.x;
StaticLookup* jLookup = iLookup + subdivMin[1] * colCtx->subdivAmount.x;
sectorMin.y = subdivMin[1] * colCtx->subdivLength.y + colCtx->minBounds.y;
sectorMax.y = colCtx->subdivLength.y + sectorMin.y;
for (j = subdivMin[1]; j < subdivMax[1] + 1; j++) {
lookup = jLookup + subdivMin[0];
StaticLookup* lookup = jLookup + subdivMin[0];
sectorMin.x = subdivMin[0] * colCtx->subdivLength.x + colCtx->minBounds.x;
sectorMax.x = colCtx->subdivLength.x + sectorMin.x;
@ -2443,11 +2457,14 @@ s32 BgCheck_SphVsFirstPolyImpl(CollisionContext* colCtx, u16 xpFlags, CollisionP
StaticLookup* lookup;
*outBgId = BGCHECK_SCENE;
#if OOT_DEBUG
if (BgCheck_PosErrorCheck(center, "../z_bgcheck.c", 5852) == true) {
if (actor != NULL) {
PRINTF("こいつ,pself_actor->name %d\n", actor->id);
}
}
#endif
lookup = BgCheck_GetStaticLookup(colCtx, colCtx->lookupTbl, center);
if (lookup == NULL) {
@ -2784,12 +2801,12 @@ void DynaPoly_DeleteBgActor(PlayState* play, DynaCollisionContext* dyna, s32 bgI
PRINTF(VT_RST);
if (!DynaPoly_IsBgIdBgActor(bgId)) {
#if OOT_DEBUG
if (bgId == -1) {
PRINTF(VT_FGCOL(GREEN));
// "The index that should have been deleted(? ) was(== -1), processing aborted."
PRINTF("DynaPolyInfo_delReserve():削除されているはずの(?)\nインデックス(== -1)のため,処理を中止します。\n");
PRINTF(VT_RST);
return;
} else {
PRINTF(VT_FGCOL(RED));
// "Unable to deallocate index / index unallocated, processing aborted."
@ -2797,15 +2814,17 @@ void DynaPoly_DeleteBgActor(PlayState* play, DynaCollisionContext* dyna, s32 bgI
"確保していない出来なかったインデックスの解放のため、処理を中止します。index == %d\n",
bgId);
PRINTF(VT_RST);
return;
}
}
actor = DynaPoly_GetActor(&play->colCtx, bgId);
if (actor != NULL) {
#endif
actor->bgId = BGACTOR_NEG_ONE;
dyna->bgActors[bgId].actor = NULL;
dyna->bgActorFlags[bgId] |= BGACTOR_1;
} else {
actor = DynaPoly_GetActor(&play->colCtx, bgId);
if (actor != NULL) {
actor->bgId = BGACTOR_NEG_ONE;
dyna->bgActors[bgId].actor = NULL;
dyna->bgActorFlags[bgId] |= BGACTOR_1;
}
}
}
@ -2821,7 +2840,7 @@ void DynaPoly_AddBgActorToLookup(PlayState* play, DynaCollisionContext* dyna, s3
MtxF mtx;
Actor* actor;
s32 pad;
s32 pad2;
f32 radiusSq;
f32 numVtxInverse;
s32 i;
Vec3f pos;
@ -2851,6 +2870,7 @@ void DynaPoly_AddBgActorToLookup(PlayState* play, DynaCollisionContext* dyna, s3
return;
}
#if OOT_DEBUG
if (!(dyna->polyListMax >= *polyStartIndex + pbgdata->numPolygons)) {
PRINTF(VT_FGCOL(RED));
// "do not use if %d exceeds %d"
@ -2869,6 +2889,7 @@ void DynaPoly_AddBgActorToLookup(PlayState* play, DynaCollisionContext* dyna, s3
"pdyna_poly_info->poly_num >= *pstart_poly_index + pbgdata->poly_num", "../z_bgcheck.c", 6687);
ASSERT(dyna->vtxListMax >= *vtxStartIndex + pbgdata->numVertices,
"pdyna_poly_info->vert_num >= *pstart_vert_index + pbgdata->vtx_num", "../z_bgcheck.c", 6688);
#endif
if (!(dyna->bitFlag & DYNAPOLY_INVALIDATE_LOOKUP) &&
(BgActor_IsTransformUnchanged(&dyna->bgActors[bgId]) == true)) {
@ -2898,111 +2919,111 @@ void DynaPoly_AddBgActorToLookup(PlayState* play, DynaCollisionContext* dyna, s3
*polyStartIndex += pbgdata->numPolygons;
*vtxStartIndex += pbgdata->numVertices;
} else {
SkinMatrix_SetTranslateRotateYXZScale(
&mtx, dyna->bgActors[bgId].curTransform.scale.x, dyna->bgActors[bgId].curTransform.scale.y,
dyna->bgActors[bgId].curTransform.scale.z, dyna->bgActors[bgId].curTransform.rot.x,
dyna->bgActors[bgId].curTransform.rot.y, dyna->bgActors[bgId].curTransform.rot.z,
dyna->bgActors[bgId].curTransform.pos.x, dyna->bgActors[bgId].curTransform.pos.y,
dyna->bgActors[bgId].curTransform.pos.z);
numVtxInverse = 1.0f / pbgdata->numVertices;
newCenterPoint.x = newCenterPoint.y = newCenterPoint.z = 0.0f;
for (i = 0; i < pbgdata->numVertices; i++) {
Vec3f vtx;
Vec3f vtxT; // Vtx after mtx transform
Math_Vec3s_ToVec3f(&vtx, &pbgdata->vtxList[i]);
SkinMatrix_Vec3fMtxFMultXYZ(&mtx, &vtx, &vtxT);
BgCheck_Vec3fToVec3s(&dyna->vtxList[*vtxStartIndex + i], &vtxT);
if (i == 0) {
dyna->bgActors[bgId].minY = dyna->bgActors[bgId].maxY = vtxT.y;
} else if (vtxT.y < dyna->bgActors[bgId].minY) {
dyna->bgActors[bgId].minY = vtxT.y;
} else if (dyna->bgActors[bgId].maxY < vtxT.y) {
dyna->bgActors[bgId].maxY = vtxT.y;
}
newCenterPoint.x += vtxT.x;
newCenterPoint.y += vtxT.y;
newCenterPoint.z += vtxT.z;
}
newCenterPoint.x *= numVtxInverse;
newCenterPoint.y *= numVtxInverse;
newCenterPoint.z *= numVtxInverse;
sphere->center.x = newCenterPoint.x;
sphere->center.y = newCenterPoint.y;
sphere->center.z = newCenterPoint.z;
newRadiusSq = -SQ(10.0f);
for (i = 0; i < pbgdata->numVertices; i++) {
f32 radiusSq;
newVtx.x = dyna->vtxList[*vtxStartIndex + i].x;
newVtx.y = dyna->vtxList[*vtxStartIndex + i].y;
newVtx.z = dyna->vtxList[*vtxStartIndex + i].z;
radiusSq = Math3D_Vec3fDistSq(&newVtx, &newCenterPoint);
if (newRadiusSq < radiusSq) {
newRadiusSq = radiusSq;
}
}
sphere->radius = sqrtf(newRadiusSq) * 1.1f;
for (i = 0; i < pbgdata->numPolygons; i++) {
CollisionPoly* newPoly = &dyna->polyList[*polyStartIndex + i];
f32 newNormMagnitude;
*newPoly = pbgdata->polyList[i];
// Yeah, this is all kinds of fake, but my God, it matches.
newPoly->flags_vIA = (COLPOLY_VTX_INDEX(newPoly->flags_vIA) + *vtxStartIndex) |
COLPOLY_VTX_FLAGS_MASKED((*newPoly).flags_vIA);
newPoly->flags_vIB = (COLPOLY_VTX_INDEX(newPoly->flags_vIB) + *vtxStartIndex) |
COLPOLY_VTX_FLAGS_MASKED((*newPoly).flags_vIB);
newPoly->vIC = *vtxStartIndex + newPoly->vIC;
dVtxList = dyna->vtxList;
vtxA.x = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIA)].x;
vtxA.y = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIA)].y;
vtxA.z = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIA)].z;
vtxB.x = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIB)].x;
vtxB.y = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIB)].y;
vtxB.z = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIB)].z;
vtxC.x = dVtxList[newPoly->vIC].x;
vtxC.y = dVtxList[newPoly->vIC].y;
vtxC.z = dVtxList[newPoly->vIC].z;
Math3D_SurfaceNorm(&vtxA, &vtxB, &vtxC, &newNormal);
newNormMagnitude = Math3D_Vec3fMagnitude(&newNormal);
if (!IS_ZERO(newNormMagnitude)) {
newNormal.x *= (1.0f / newNormMagnitude);
newNormal.y *= (1.0f / newNormMagnitude);
newNormal.z *= (1.0f / newNormMagnitude);
newPoly->normal.x = COLPOLY_SNORMAL(newNormal.x);
newPoly->normal.y = COLPOLY_SNORMAL(newNormal.y);
newPoly->normal.z = COLPOLY_SNORMAL(newNormal.z);
}
newPoly->dist = -DOTXYZ(newNormal, dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIA)]);
if (newNormal.y > 0.5f) {
s16 polyId = *polyStartIndex + i;
DynaSSNodeList_SetSSListHead(&dyna->polyNodes, &dyna->bgActors[bgId].dynaLookup.floor, &polyId);
} else if (newNormal.y < -0.8f) {
s16 polyId = *polyStartIndex + i;
DynaSSNodeList_SetSSListHead(&dyna->polyNodes, &dyna->bgActors[bgId].dynaLookup.ceiling, &polyId);
} else {
s16 polyId = *polyStartIndex + i;
DynaSSNodeList_SetSSListHead(&dyna->polyNodes, &dyna->bgActors[bgId].dynaLookup.wall, &polyId);
}
}
*polyStartIndex += pbgdata->numPolygons;
*vtxStartIndex += pbgdata->numVertices;
return;
}
SkinMatrix_SetTranslateRotateYXZScale(
&mtx, dyna->bgActors[bgId].curTransform.scale.x, dyna->bgActors[bgId].curTransform.scale.y,
dyna->bgActors[bgId].curTransform.scale.z, dyna->bgActors[bgId].curTransform.rot.x,
dyna->bgActors[bgId].curTransform.rot.y, dyna->bgActors[bgId].curTransform.rot.z,
dyna->bgActors[bgId].curTransform.pos.x, dyna->bgActors[bgId].curTransform.pos.y,
dyna->bgActors[bgId].curTransform.pos.z);
numVtxInverse = 1.0f / pbgdata->numVertices;
newCenterPoint.x = newCenterPoint.y = newCenterPoint.z = 0.0f;
for (i = 0; i < pbgdata->numVertices; i++) {
Vec3f vtx;
Vec3f vtxT; // Vtx after mtx transform
s32 pad2;
Math_Vec3s_ToVec3f(&vtx, &pbgdata->vtxList[i]);
SkinMatrix_Vec3fMtxFMultXYZ(&mtx, &vtx, &vtxT);
BgCheck_Vec3fToVec3s(&dyna->vtxList[*vtxStartIndex + i], &vtxT);
if (i == 0) {
dyna->bgActors[bgId].minY = dyna->bgActors[bgId].maxY = vtxT.y;
} else if (vtxT.y < dyna->bgActors[bgId].minY) {
dyna->bgActors[bgId].minY = vtxT.y;
} else if (dyna->bgActors[bgId].maxY < vtxT.y) {
dyna->bgActors[bgId].maxY = vtxT.y;
}
newCenterPoint.x += vtxT.x;
newCenterPoint.y += vtxT.y;
newCenterPoint.z += vtxT.z;
}
newCenterPoint.x *= numVtxInverse;
newCenterPoint.y *= numVtxInverse;
newCenterPoint.z *= numVtxInverse;
sphere->center.x = newCenterPoint.x;
sphere->center.y = newCenterPoint.y;
sphere->center.z = newCenterPoint.z;
newRadiusSq = -SQ(10.0f);
for (i = 0; i < pbgdata->numVertices; i++) {
newVtx.x = dyna->vtxList[*vtxStartIndex + i].x;
newVtx.y = dyna->vtxList[*vtxStartIndex + i].y;
newVtx.z = dyna->vtxList[*vtxStartIndex + i].z;
radiusSq = Math3D_Vec3fDistSq(&newVtx, &newCenterPoint);
if (newRadiusSq < radiusSq) {
newRadiusSq = radiusSq;
}
}
sphere->radius = sqrtf(newRadiusSq) * 1.1f;
for (i = 0; i < pbgdata->numPolygons; i++) {
CollisionPoly* newPoly = &dyna->polyList[*polyStartIndex + i];
f32 newNormMagnitude;
*newPoly = pbgdata->polyList[i];
// Yeah, this is all kinds of fake, but my God, it matches.
newPoly->flags_vIA =
(COLPOLY_VTX_INDEX(newPoly->flags_vIA) + *vtxStartIndex) | COLPOLY_VTX_FLAGS_MASKED((*newPoly).flags_vIA);
newPoly->flags_vIB =
(COLPOLY_VTX_INDEX(newPoly->flags_vIB) + *vtxStartIndex) | COLPOLY_VTX_FLAGS_MASKED((*newPoly).flags_vIB);
newPoly->vIC = *vtxStartIndex + newPoly->vIC;
dVtxList = dyna->vtxList;
vtxA.x = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIA)].x;
vtxA.y = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIA)].y;
vtxA.z = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIA)].z;
vtxB.x = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIB)].x;
vtxB.y = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIB)].y;
vtxB.z = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIB)].z;
vtxC.x = dVtxList[newPoly->vIC].x;
vtxC.y = dVtxList[newPoly->vIC].y;
vtxC.z = dVtxList[newPoly->vIC].z;
Math3D_SurfaceNorm(&vtxA, &vtxB, &vtxC, &newNormal);
newNormMagnitude = Math3D_Vec3fMagnitude(&newNormal);
if (!IS_ZERO(newNormMagnitude)) {
newNormal.x *= (1.0f / newNormMagnitude);
newNormal.y *= (1.0f / newNormMagnitude);
newNormal.z *= (1.0f / newNormMagnitude);
newPoly->normal.x = COLPOLY_SNORMAL(newNormal.x);
newPoly->normal.y = COLPOLY_SNORMAL(newNormal.y);
newPoly->normal.z = COLPOLY_SNORMAL(newNormal.z);
}
newPoly->dist = -DOTXYZ(newNormal, dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIA)]);
if (newNormal.y > 0.5f) {
s16 polyId = *polyStartIndex + i;
DynaSSNodeList_SetSSListHead(&dyna->polyNodes, &dyna->bgActors[bgId].dynaLookup.floor, &polyId);
} else if (newNormal.y < -0.8f) {
s16 polyId = *polyStartIndex + i;
DynaSSNodeList_SetSSListHead(&dyna->polyNodes, &dyna->bgActors[bgId].dynaLookup.ceiling, &polyId);
} else {
s16 polyId = *polyStartIndex + i;
DynaSSNodeList_SetSSListHead(&dyna->polyNodes, &dyna->bgActors[bgId].dynaLookup.wall, &polyId);
}
}
*polyStartIndex += pbgdata->numPolygons;
*vtxStartIndex += pbgdata->numVertices;
}
void DynaPoly_UnsetAllInteractFlags(PlayState* play, DynaCollisionContext* dyna, Actor* actor) {
@ -3155,7 +3176,7 @@ f32 BgCheck_RaycastDownDyna(DynaRaycastDown* dynaRaycastDown) {
s32 i2;
s32 isPaused;
DynaPolyActor* dynaActor;
s32 pad;
CollisionPoly* poly;
Vec3f polyVtx[3];
Vec3f polyNorm;
u32 polyIndex;
@ -3167,7 +3188,6 @@ f32 BgCheck_RaycastDownDyna(DynaRaycastDown* dynaRaycastDown) {
Vec3f vtx;
f32 intersect;
ScaleRotPos* curTransform;
CollisionPoly* poly;
result = BGCHECK_Y_MIN;
*dynaRaycastDown->bgId = BGCHECK_SCENE;
@ -3239,9 +3259,12 @@ f32 BgCheck_RaycastDownDyna(DynaRaycastDown* dynaRaycastDown) {
vtxList = dynaRaycastDown->dyna->bgActors[*dynaRaycastDown->bgId].colHeader->vtxList;
for (i2 = 0; i2 < 3; i2++) {
s32 pad;
Math_Vec3s_ToVec3f(&vtx, &vtxList[COLPOLY_VTX_INDEX(poly->vtxData[i2])]);
SkinMatrix_Vec3fMtxFMultXYZ(&srpMtx, &vtx, &polyVtx[i2]);
}
Math3D_SurfaceNorm(&polyVtx[0], &polyVtx[1], &polyVtx[2], &polyNorm);
magnitude = Math3D_Vec3fMagnitude(&polyNorm);
@ -3290,8 +3313,6 @@ s32 BgCheck_SphVsDynaWallInBgActor(CollisionContext* colCtx, u16 xpFlags, DynaCo
f32 invNormalXZ;
f32 planeDist;
f32 temp_f18;
f32 zIntersectDist;
f32 xIntersectDist;
f32 zMin;
f32 zMax;
f32 xMin;
@ -3360,8 +3381,10 @@ s32 BgCheck_SphVsDynaWallInBgActor(CollisionContext* colCtx, u16 xpFlags, DynaCo
}
}
if (CollisionPoly_CheckZIntersectApprox(poly, dyna->vtxList, resultPos.x, pos->y, &intersect)) {
if (fabsf(intersect - resultPos.z) <= radius / temp_f18) {
if ((intersect - resultPos.z) * nz <= 4.0f) {
f32 zIntersectDist = intersect - resultPos.z;
if (fabsf(zIntersectDist) <= radius / temp_f18) {
if (zIntersectDist * nz <= 4.0f) {
if (BgCheck_ComputeWallDisplacement(colCtx, poly, &resultPos.x, &resultPos.z, nx, ny, nz,
invNormalXZ, planeDist, radius, outPoly)) {
*outBgId = bgId;
@ -3434,7 +3457,8 @@ s32 BgCheck_SphVsDynaWallInBgActor(CollisionContext* colCtx, u16 xpFlags, DynaCo
}
if (CollisionPoly_CheckXIntersectApprox(poly, dyna->vtxList, pos->y, resultPos.z, &intersect)) {
xIntersectDist = intersect - resultPos.x;
f32 xIntersectDist = intersect - resultPos.x;
if (fabsf(xIntersectDist) <= radius / temp_f18) {
if (xIntersectDist * nx <= 4.0f) {
if (BgCheck_ComputeWallDisplacement(colCtx, poly, &resultPos.x, &resultPos.z, nx, ny, nz,
@ -4223,6 +4247,8 @@ f32 sZorasDomainWaterBoxMaxZ = -967.0f;
s32 WaterBox_GetSurface1(PlayState* play, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface,
WaterBox** outWaterBox) {
if (play->sceneId == SCENE_ZORAS_DOMAIN) {
s32 pad;
if (sZorasDomainWaterBoxMinX < x && x < sZorasDomainWaterBoxMaxX && sZorasDomainWaterBoxMinY < *ySurface &&
*ySurface < sZorasDomainWaterBoxMaxY && sZorasDomainWaterBoxMinZ < z && z < sZorasDomainWaterBoxMaxZ) {
*outWaterBox = &sZorasDomainWaterBox;