mirror of
https://github.com/zeldaret/oot.git
synced 2024-12-26 14:46:16 +00:00
parent
e48cdaf598
commit
63f0033fe5
1 changed files with 208 additions and 182 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue