work on collider

This commit is contained in:
MonsterDruide1 2025-12-12 00:57:15 +01:00
parent c87f4a0914
commit c4e882f9c7
13 changed files with 615 additions and 137 deletions

View file

@ -230947,7 +230947,7 @@ Library/Clipping/FrustumRadar.o:
size: 12
label: _ZNK2al12FrustumRadar19judgeInAreaObbNoFarEPKN4sead8Matrix34IfEERKNS1_9BoundBox3IfEE
status: NotDecompiled
Library/Collision/Collider.o:
Library/Collision/Angle.o:
'.text':
- offset: 0x8443d8
size: 120
@ -230973,84 +230973,86 @@ Library/Collision/Collider.o:
size: 196
label: _ZN2al24calcTriangleColorByAngleEPN4sead7Color4fEPfRKNS0_7Vector3IfEE
status: NotDecompiled
Library/Collision/Collider.o:
'.text':
- offset: 0x844740
size: 316
label:
- _ZN2al8ColliderC1EPNS_17CollisionDirectorEPKN4sead8Matrix34IfEEPKNS3_7Vector3IfEESB_ffj
- _ZN2al8ColliderC2EPNS_17CollisionDirectorEPKN4sead8Matrix34IfEEPKNS3_7Vector3IfEESB_ffj
status: NotDecompiled
status: Matching
- offset: 0x84487c
size: 36
label: _ZN2al8Collider5clearEv
status: NotDecompiled
status: Matching
- offset: 0x8448a0
size: 8
label: _ZN2al8Collider17setTriangleFilterEPKNS_18TriangleFilterBaseE
status: NotDecompiled
status: Matching
- offset: 0x8448a8
size: 8
label: _ZN2al8Collider23setCollisionPartsFilterEPKNS_24CollisionPartsFilterBaseE
status: NotDecompiled
status: Matching
- offset: 0x8448b0
size: 100
label: _ZN2al8Collider24updateRecentOnGroundInfoEv
status: NotDecompiled
status: Matching
- offset: 0x844914
size: 8
label: _ZN2al8Collider19clearStoredPlaneNumEv
status: NotDecompiled
status: Matching
- offset: 0x84491c
size: 32
label: _ZN2al8Collider17clearContactPlaneEv
status: NotDecompiled
status: Matching
- offset: 0x84493c
size: 84
label: _ZN2al8Collider12onInvalidateEv
status: NotDecompiled
status: Matching
- offset: 0x844990
size: 444
label: _ZNK2al8Collider12calcCheckPosEPN4sead7Vector3IfEE
status: NotDecompiled
status: Matching
- offset: 0x844b4c
size: 48
label: _ZNK2al8Collider23getRecentOnGroundNormalEj
status: NotDecompiled
status: Matching
- offset: 0x844b7c
size: 16
label: _ZNK2al8Collider8getPlaneEi
status: NotDecompiled
status: Matching
- offset: 0x844b8c
size: 168
label: _ZN2al8Collider22calcMovePowerByContactEPN4sead7Vector3IfEERKS3_
status: NotDecompiled
status: Matching
- offset: 0x844c34
size: 428
label: _ZN2al8Collider19storeCurrentHitInfoEPNS_13SphereHitInfoEj
status: NotDecompiled
status: Matching
- offset: 0x844de0
size: 1184
label: _ZN2al8Collider23obtainMomentFixReactionEPNS_13SphereHitInfoEPN4sead7Vector3IfEES6_bj
status: NotDecompiled
status: NonMatchingMajor
- offset: 0x845280
size: 1104
label: _ZN2al8Collider17storeContactPlaneEPNS_13SphereHitInfoE
status: NotDecompiled
status: Matching
- offset: 0x8456d0
size: 1688
label: _ZN2al8Collider7collideERKN4sead7Vector3IfEE
status: NotDecompiled
status: NonMatchingMajor
- offset: 0x845d68
size: 484
label: _ZN2al8Collider10preCollideEPNS_18SphereInterpolatorEPN4sead7Vector3IfEEPfRKS5_PNS_13SphereHitInfoEj
status: NotDecompiled
status: Matching
- offset: 0x845f4c
size: 244
label: _ZN2al8Collider14findCollidePosEPiPNS_18SphereInterpolatorEPNS_13SphereHitInfoEj
status: NotDecompiled
status: Matching
- offset: 0x846040
size: 8
label: _ZNK2al8Collider20getCollisionDirectorEv
status: NotDecompiled
status: Matching
lazy: true
Library/Collision/CollisionCodeFunction.o:
'.text':

View file

@ -0,0 +1,17 @@
#pragma once
#include <gfx/seadColor.h>
#include <math/seadVector.h>
namespace al {
enum class PolygonType : s32 { /* TODO: MISSING */ };
bool isWallPolygon(const sead::Vector3f&, const sead::Vector3f&);
bool isFloorPolygon(const sead::Vector3f&, const sead::Vector3f&);
bool isFloorPolygonCos(const sead::Vector3f&, const sead::Vector3f&, f32);
bool isCeilingPolygon(const sead::Vector3f&, const sead::Vector3f&);
PolygonType calcPolygonType(const sead::Vector3f&, const sead::Vector3f&);
void calcTriangleColorByAngle(sead::Color4f*, f32*, const sead::Vector3f&);
} // namespace al

View file

@ -0,0 +1,483 @@
#include "Library/Collision/Collider.h"
#include "Library/Collision/Angle.h"
#include "Library/Collision/CollisionDirector.h"
#include "Library/Collision/CollisionPartsKeeperUtil.h"
#include "Library/Collision/KCollisionServer.h"
#include "Library/Math/MathUtil.h"
namespace al {
Collider::Collider(CollisionDirector* director, const sead::Matrix34f* actorBaseMtx,
const sead::Vector3f* actorTrans, const sead::Vector3f* actorGravity, f32 radius,
f32 offsetY, u32 planeNum)
: mCollisionDirector(director), mActorBaseMtx(actorBaseMtx), mActorTrans(actorTrans),
mActorGravity(actorGravity), mRadius(radius), mOffsetY(offsetY), mPlaneNum(planeNum) {
mCurrentTrans.set(*actorTrans);
mCurrentRadius = radius;
if (mPlaneNum != 0) {
mPlanes = new SphereHitInfo[mPlaneNum];
__asm("");
} else
mPlanes = nullptr;
clear();
flags2 = (flags2 & 0x80) | 3;
}
void Collider::clear() {
clearStoredPlaneNum();
clearContactPlane();
}
void Collider::setTriangleFilter(const TriangleFilterBase* filter) {
mTriangleFilter = filter;
}
void Collider::setCollisionPartsFilter(const CollisionPartsFilterBase* filter) {
mCollisionPartsFilter = filter;
}
void Collider::updateRecentOnGroundInfo() {
if (mFloor_70 >= 0.0f) {
mNoGroundCounter = 0;
mRecentOnGroundNormal = mFloorHit.triangle.getFaceNormal();
} else if (mNoGroundCounter != -1) {
mNoGroundCounter++;
}
}
void Collider::clearStoredPlaneNum() {
mStoredPlaneNum = 0;
}
void Collider::clearContactPlane() {
mFloor_70 = -99999.0f;
mWall_70 = -99999.0f;
mCeiling_70 = -99999.0f;
mFixReaction = {0.0f, 0.0f, 0.0f};
mMovePower = {0.0f, 0.0f, 0.0f};
}
void Collider::onInvalidate() {
clear();
mNoGroundCounter = -1;
calcCheckPos(&mCurrentTrans);
mCurrentRadius = mRadius;
}
void Collider::calcCheckPos(sead::Vector3f* outPos) const {
// many things are done manually here, which is visible in the assembly as unoptimized
// reading/writing to memory - for example, the matrix multiplication here ends up writing to
// outPos 4 times
*outPos = *mActorTrans;
if (unknown) {
if ((flags2 & 0x4) && mActorBaseMtx) {
outPos->x += mActorBaseMtx->getBase(0).x * unknown->x;
outPos->x += mActorBaseMtx->getBase(1).x * unknown->y;
outPos->x += mActorBaseMtx->getBase(2).x * unknown->z;
outPos->y += mActorBaseMtx->getBase(0).y * unknown->x;
outPos->y += mActorBaseMtx->getBase(1).y * unknown->y;
outPos->y += mActorBaseMtx->getBase(2).y * unknown->z;
outPos->z += mActorBaseMtx->getBase(0).z * unknown->x;
outPos->z += mActorBaseMtx->getBase(1).z * unknown->y;
outPos->z += mActorBaseMtx->getBase(2).z * unknown->z;
return;
}
outPos->x += unknown->x;
outPos->y += unknown->y;
outPos->z += unknown->z;
return;
}
if (mActorBaseMtx) {
outPos->x += mActorBaseMtx->getBase(1).x * mOffsetY;
outPos->y += mActorBaseMtx->getBase(1).y * mOffsetY;
outPos->z += mActorBaseMtx->getBase(1).z * mOffsetY;
return;
}
outPos->y += mOffsetY;
}
static const sead::Vector3f sDefaultGroundNormal = {0.0f, 1.0f, 0.0f};
const sead::Vector3f& Collider::getRecentOnGroundNormal(u32 coyoteTime) const {
if (mFloor_70 >= 0.0f)
return mFloorHit.triangle.getFaceNormal();
if ((u32)mNoGroundCounter <= coyoteTime)
return mRecentOnGroundNormal;
return sDefaultGroundNormal;
}
const Triangle& Collider::getPlane(s32 index) const {
return mPlanes[index].triangle;
}
bool Collider::calcMovePowerByContact(sead::Vector3f* movePower, const sead::Vector3f& pos) {
if (mFloor_70 < 0.0f)
return false;
if (!mFloorHit.triangle.isHostMoved())
return false;
mFloorHit.triangle.calcForceMovePower(movePower, pos);
const sead::Vector3f& normal = mFloorHit.triangle.getFaceNormal();
if (normal.dot(*movePower) > 0.0f)
verticalizeVec(movePower, normal, *movePower);
return true;
}
u32 Collider::storeCurrentHitInfo(SphereHitInfo* buffer, u32 bufferSize) {
u32 strikeInfoNum = alCollisionUtil::getStrikeSphereInfoNum(this);
u32 i;
for (i = 0; i < strikeInfoNum; i++) {
if (i + mStoredPlaneNum >= bufferSize) {
u32 stored = bufferSize - mStoredPlaneNum;
mStoredPlaneNum = bufferSize;
return stored;
}
const al::SphereHitInfo& info = alCollisionUtil::getStrikeSphereInfo(this, i);
buffer[i + mStoredPlaneNum] = info;
}
mStoredPlaneNum += i;
return i;
}
// TODO: cleanup
void al::Collider::obtainMomentFixReaction(al::SphereHitInfo* a2, sead::Vector3f* a3,
sead::Vector3f* a4, bool a5, u32 a6) {
flags2 &= ~(0x10 | 0x20 | 0x40);
for (u32 i = a6; i < mStoredPlaneNum; i++) {
const sead::Vector3f& normal = a2[i].triangle.getFaceNormal();
if (al::isFloorPolygon(normal, *mActorGravity)) {
if (a2[i].isCollisionAtFace())
flags2 |= 0x10;
} else if (al::isWallPolygon(normal, *mActorGravity)) {
if (a2[i].isCollisionAtFace())
flags2 |= 0x20;
} else {
if (a2[i].isCollisionAtFace())
flags2 |= 0x40;
}
}
f32 maxAX = 0.0f;
f32 maxAY = 0.0f;
f32 maxAZ = 0.0f;
f32 minAX = 0.0f;
f32 minAY = 0.0f;
f32 minAZ = 0.0f;
f32 maxBX = 0.0f;
f32 maxBY = 0.0f;
f32 maxBZ = 0.0f;
f32 minBX = 0.0f;
f32 minBY = 0.0f;
f32 minBZ = 0.0f;
for (u32 i = a6; i < mStoredPlaneNum; i++) {
const sead::Vector3f& normal = a2[i].triangle.getFaceNormal();
sead::Vector3f a;
sead::Vector3f b;
if (al::isFloorPolygon(normal, *mActorGravity))
if (!flags1 || (flags2 & 0x10) != 0)
a2[i].calcFixVectorNormal(&a, &b);
else
a2[i].calcFixVector(&a, &b);
else if (al::isWallPolygon(normal, *mActorGravity))
if ((flags2 & 0x20) == 0)
a2[i].calcFixVector(&a, &b);
else
a2[i].calcFixVectorNormal(&a, &b);
else if ((flags2 & 0x40) == 0)
a2[i].calcFixVector(&a, &b);
else
a2[i].calcFixVectorNormal(&a, &b);
if (maxAX < a.x)
maxAX = a.x;
else if (a.x < minAX)
minAX = a.x;
if (maxAY < a.y)
maxAY = a.y;
else if (a.y < minAY)
minAY = a.y;
if (maxAZ < a.z)
maxAZ = a.z;
else if (a.z < minAZ)
minAZ = a.z;
if (a4) {
if (maxBX < b.x)
maxBX = b.x;
else if (b.x < minBX)
minBX = b.x;
if (maxBY < b.y)
maxBY = b.y;
else if (b.y < minBY)
minBY = b.y;
if (maxBZ < b.z)
maxBZ = b.z;
else if (b.z < minBZ)
minBZ = b.z;
}
if ((flags2 & 2) == 0 || !a2[i].triangle.isHostMoved())
continue;
sead::Vector3f collisionMovingReaction = a2[i].collisionMovingReaction;
if (a.dot(collisionMovingReaction) < 0.0f)
continue;
if (maxAX < collisionMovingReaction.x)
maxAX = collisionMovingReaction.x;
else if (collisionMovingReaction.x < minAX)
minAX = collisionMovingReaction.x;
if (maxAY < collisionMovingReaction.y)
maxAY = collisionMovingReaction.y;
else if (collisionMovingReaction.y < minAY)
minAY = collisionMovingReaction.y;
if (maxAZ < collisionMovingReaction.z)
maxAZ = collisionMovingReaction.z;
else if (collisionMovingReaction.z < minAZ)
minAZ = collisionMovingReaction.z;
if (a4) {
if (maxBX < collisionMovingReaction.x)
maxBX = collisionMovingReaction.x;
else if (collisionMovingReaction.x < minBX)
minBX = collisionMovingReaction.x;
if (maxBY < collisionMovingReaction.y)
maxBY = collisionMovingReaction.y;
else if (collisionMovingReaction.y < minBY)
minBY = collisionMovingReaction.y;
if (maxBZ < collisionMovingReaction.z)
maxBZ = collisionMovingReaction.z;
else if (!(collisionMovingReaction.z < minBZ)) // FIXME: wrong way around?
minBZ = collisionMovingReaction.z;
}
}
a3->x = maxAX + minAX;
a3->y = maxAY + minAY;
a3->z = maxAZ + minAZ;
if (a4) {
a4->x = maxBX + minBX;
a4->y = maxBY + minBY;
a4->z = maxBZ + minBZ;
}
}
void Collider::storeContactPlane(SphereHitInfo* hitInfos) {
for (u32 i = 0; i < mStoredPlaneNum; i++) {
const sead::Vector3f& normal = hitInfos[i].triangle.getNormal(0);
if (isFloorPolygon(normal, *mActorGravity)) {
if (mFloor_70 < hitInfos[i]._70) {
mFloorHit = hitInfos[i];
mFloor_70 = hitInfos[i]._70;
}
} else if (isWallPolygon(normal, *mActorGravity)) {
if (mWall_70 < hitInfos[i]._70) {
mWallHit = hitInfos[i];
mWall_70 = hitInfos[i]._70;
}
} else if (mCeiling_70 < hitInfos[i]._70) {
mCeilingHit = hitInfos[i];
mCeiling_70 = hitInfos[i]._70;
}
}
}
// TODO: cleanup
sead::Vector3f al::Collider::collide(const sead::Vector3f& velocity) {
al::SphereHitInfo* planes;
u32 planeNum;
if (mPlaneNum) {
planes = mPlanes;
planeNum = mPlaneNum;
} else {
getCollisionDirector()->getSphereHitInfoArrayForCollider(&planes, &planeNum);
}
sead::Vector3f checkPos = {0.0f, 0.0f, 0.0f};
calcCheckPos(&checkPos);
/*-----------------*/
sead::Vector3f transStart = mCurrentTrans;
f32 currentRadius = mCurrentRadius;
f32 v8 = sead::Mathf::clampMax(sead::Mathf::min(0.9f * mRadius, 0.9f * mCurrentRadius), 35.0f);
sead::Vector3f movePower = {0.0f, 0.0f, 0.0f};
if ((flags2 & 1) != 0)
calcMovePowerByContact(&movePower, checkPos);
clear();
mMovePower = movePower;
al::SphereInterpolator interpolator;
interpolator.startInterp(mCurrentTrans, checkPos + movePower, mCurrentRadius, mRadius, v8);
s32 v56 = 0;
sead::Vector3f moveDist = (checkPos + movePower) - mCurrentTrans;
if (!al::isNearZero(moveDist) || !al::isNearZero(mCurrentRadius - mRadius))
preCollide(&interpolator, &transStart, &currentRadius, moveDist, planes, planeNum);
f32 v19 = sead::Mathf::clampMax(mCurrentRadius * 0.9f, 35.0f);
interpolator.startInterp(transStart, transStart + velocity, mRadius, mRadius, v19);
v56 = 0;
sead::Vector3f v232526;
if (!findCollidePos(&v56, &interpolator, planes, planeNum) &&
interpolator.getPrevStep() == 1.0 && interpolator.getCurrentStep() == 1.0) {
v232526 = transStart - checkPos + velocity;
} else {
sead::Vector3f v272829 = {0.0f, 0.0f, 0.0f};
s32 v30 = 0;
bool v31 = true;
sead::Vector3f v53;
do {
sead::Vector3f v55 = {0.0f, 0.0f, 0.0f};
sead::Vector3f v54 = {0.0f, 0.0f, 0.0f};
obtainMomentFixReaction(planes, &v55, &v54, v31, v30);
v30 += v56;
interpolator.calcInterp(&transStart, &currentRadius, &v53);
transStart += v55;
v272829 += v55;
sead::Vector3f a1a = v55;
if (al::isNearZero(a1a))
a1a = v54;
al::tryNormalizeOrZero(&a1a);
f32 v42 = v53.dot(a1a);
if (v42 < 0.0f)
v53 -= a1a * v42;
if (velocity.dot(v53) < 0.0f)
break;
interpolator.startInterp(transStart, transStart + v53, currentRadius, mRadius, v19);
interpolator.nextStep();
v56 = 0;
v31 = false;
bool CollidePos = findCollidePos(&v56, &interpolator, planes, planeNum);
if (!CollidePos || interpolator.getCurrentStep() >= 1.0f) {
interpolator.calcInterpPos(&transStart);
if (CollidePos && v56 > 0) {
obtainMomentFixReaction(planes, &v55, nullptr, false, v30);
transStart += v55;
v30 += v56;
}
break;
} else {
continue;
}
} while (true);
storeContactPlane(planes);
mFixReaction = v272829;
v232526 = transStart - checkPos;
}
mCurrentTrans = v232526 + checkPos;
mCurrentRadius = mRadius;
updateRecentOnGroundInfo();
return v232526;
}
// TODO: cleanup
bool Collider::preCollide(al::SphereInterpolator* interpolator, sead::Vector3f* trans,
f32* currentRadius, const sead::Vector3f& moveDist,
al::SphereHitInfo* buffer, u32 bufferSize) {
sead::Vector3f v71415 = {0.0f, 0.0f, 0.0f};
const al::TriangleFilterBase* triangleFilter = mTriangleFilter;
const al::CollisionPartsFilterBase* collisionPartsFilter = mCollisionPartsFilter;
bool foundHit = false;
u32 totalStored = 0;
while (interpolator->getPrevStep() != 1.0f || interpolator->getCurrentStep() != 1.0f) {
sead::Vector3f pos;
f32 size;
interpolator->calcInterp(&pos, &size, nullptr);
s32 hits;
if ((flags2 & 2) != 0) {
hits = alCollisionUtil::checkStrikeSphereMovingReaction(
this, v71415 + pos, size, moveDist, collisionPartsFilter, triangleFilter);
} else {
hits = alCollisionUtil::checkStrikeSphere(this, pos, size, collisionPartsFilter,
triangleFilter);
}
if (hits != 0) {
s32 stored = storeCurrentHitInfo(buffer, bufferSize);
sead::Vector3f a2a = {0.0f, 0.0f, 0.0f};
obtainMomentFixReaction(buffer, &a2a, nullptr, false, totalStored);
v71415 += a2a;
foundHit = true;
if (interpolator->getCurrentStep() >= 1.0f)
break;
if (flags2 & 0x8)
totalStored += stored;
}
interpolator->nextStep();
}
interpolator->calcInterp(trans, currentRadius, nullptr);
*trans += v71415;
if (foundHit) {
storeContactPlane(buffer);
mStoredPlaneNum = 0;
}
return foundHit;
}
bool Collider::findCollidePos(s32* bufferStored, al::SphereInterpolator* interpolator,
al::SphereHitInfo* buffer, u32 bufferSize) {
const al::TriangleFilterBase* triangleFilter = mTriangleFilter;
const al::CollisionPartsFilterBase* collisionPartsFilter = mCollisionPartsFilter;
while (interpolator->getPrevStep() != 1.0 || interpolator->getCurrentStep() != 1.0) {
sead::Vector3f pos, remainMoveVec;
f32 size;
interpolator->calcInterp(&pos, &size, &remainMoveVec);
s32 hits;
if (flags2 & 0x2) {
hits = alCollisionUtil::checkStrikeSphereMovingReaction(
this, pos, size, remainMoveVec, collisionPartsFilter, triangleFilter);
} else {
hits = alCollisionUtil::checkStrikeSphere(this, pos, size, collisionPartsFilter,
triangleFilter);
}
if (hits != 0) {
u32 stored = storeCurrentHitInfo(buffer, bufferSize);
if (bufferStored)
*bufferStored = stored;
return true;
}
interpolator->nextStep();
}
return false;
}
CollisionDirector* Collider::getCollisionDirector() const {
return mCollisionDirector;
}
} // namespace al

View file

@ -16,105 +16,99 @@ class SphereInterpolator;
class Triangle;
class TriangleFilterBase;
bool isWallPolygon(const sead::Vector3f&, const sead::Vector3f&);
bool isFloorPolygon(const sead::Vector3f&, const sead::Vector3f&);
bool isCeilingPolygon(const sead::Vector3f&, const sead::Vector3f&);
class Collider : public HioNode, public IUseCollision {
public:
Collider(CollisionDirector*, const sead::Matrix34f*, const sead::Vector3f*,
const sead::Vector3f*, f32, f32, u32);
void calcCheckPos(sead::Vector3f*) const;
void calcMovePowerByContact(sead::Vector3f*, const sead::Vector3f&);
bool calcMovePowerByContact(sead::Vector3f*, const sead::Vector3f&);
void clear();
void clearContactPlane();
void clearStoredPlaneNum();
sead::Vector3f collide(const sead::Vector3f&);
void findCollidePos(s32*, SphereInterpolator*, SphereHitInfo*, u32);
Triangle* getPlane(s32) const;
bool findCollidePos(s32*, SphereInterpolator*, SphereHitInfo*, u32);
const Triangle& getPlane(s32) const;
const sead::Vector3f& getRecentOnGroundNormal(u32) const;
void obtainMomentFixReaction(SphereHitInfo*, sead::Vector3f*, sead::Vector3f*, bool, u32);
void onInvalidate();
void preCollide(SphereInterpolator*, sead::Vector3f*, f32*, const sead::Vector3f&,
bool preCollide(SphereInterpolator*, sead::Vector3f*, f32*, const sead::Vector3f&,
SphereHitInfo*, u32);
void setCollisionPartsFilter(const CollisionPartsFilterBase*);
void setTriangleFilter(const TriangleFilterBase*);
void storeContactPlane(SphereHitInfo*);
void storeCurrentHitInfo(SphereHitInfo*, u32);
u32 storeCurrentHitInfo(SphereHitInfo*, u32);
void updateRecentOnGroundInfo();
CollisionDirector* getCollisionDirector() const override;
sead::Vector3f* get_30() const { return _30; }
const sead::Vector3f* get_30() const { return mActorGravity; }
f32 getRadius() { return mRadius; };
f32 getRadius() { return mRadius; }
void setRadius(f32 radius) { mRadius = radius; };
void setRadius(f32 radius) { mRadius = radius; }
f32 getOffsetY() { return mOffsetY; };
f32 getOffsetY() { return mOffsetY; }
void setOffsetY(f32 offsetY) { mOffsetY = offsetY; };
void setOffsetY(f32 offsetY) { mOffsetY = offsetY; }
s32 get_48() const { return _48; }
s32 get_48() const { return mPlaneNum; }
u32 getPlaneCount() const { return mPlaneCount; }
u32 getPlaneCount() const { return mStoredPlaneNum; }
const sead::Vector3f& getFixReaction() const { return mFixReaction; }
const HitInfo& getFloorHit() const { return mFloorHit; }
f32 get_110() const { return _110; }
f32 get_110() const { return mFloor_70; }
const HitInfo& getWallHit() const { return mWallHit; }
f32 get_1b8() const { return _1b8; }
f32 get_1b8() const { return mWall_70; }
const HitInfo& getCeilingHit() const { return mCeilingHit; }
f32 get_260() const { return _260; }
f32 get_260() const { return mCeiling_70; }
u32 get_264() const { return _264; }
u32 get_264() const { return mNoGroundCounter; }
void setReactMovePower(bool isEnabled) {
mFlag &= ~1;
mFlag |= isEnabled;
flags2 &= ~1;
flags2 |= isEnabled;
}
void validateRobustCheck() { mFlag |= 2; }
void validateRobustCheck() { flags2 |= 2; }
void invalidateRobustCheck() { mFlag &= ~2; }
void invalidateRobustCheck() { flags2 &= ~2; }
bool isCollidedWallFace() { return mFlag >> 5 & 1; }
bool isCollidedWallFace() { return flags2 >> 5 & 1; }
private:
CollisionDirector* _8;
TriangleFilterBase* _10;
CollisionPartsFilterBase* _18;
sead::Matrix34f* _20;
sead::Vector3f* _28;
sead::Vector3f* _30;
CollisionDirector* mCollisionDirector;
const TriangleFilterBase* mTriangleFilter = nullptr;
const CollisionPartsFilterBase* mCollisionPartsFilter = nullptr;
const sead::Matrix34f* mActorBaseMtx;
const sead::Vector3f* mActorTrans;
const sead::Vector3f* mActorGravity;
f32 mRadius;
f32 mOffsetY;
void* filler1;
u32 _48;
u32 mPlaneCount;
HitInfo* _50;
sead::Vector3f mFixReaction;
sead::Vector3f _64;
sead::Vector3f* unknown = nullptr;
u32 mPlaneNum;
u32 mStoredPlaneNum = 0;
SphereHitInfo* mPlanes = nullptr;
sead::Vector3f mFixReaction = {0.0f, 0.0f, 0.0f};
sead::Vector3f mMovePower = {0.0f, 0.0f, 0.0f};
HitInfo mFloorHit;
f32 _110;
char filler3[0x4];
f32 mFloor_70 = 0.0f;
HitInfo mWallHit;
f32 _1b8;
char filler4[0x4];
f32 mWall_70 = 0.0f;
HitInfo mCeilingHit;
f32 _260;
u32 _264;
sead::Vector3f _268;
char _274;
char mFlag;
sead::Vector3f _278;
f32 _284;
f32 mCeiling_70 = 0.0f;
s32 mNoGroundCounter = 0;
sead::Vector3f mRecentOnGroundNormal = {0.0f, 1.0f, 0.0f};
u8 flags1 = 0;
u8 flags2;
sead::Vector3f mCurrentTrans;
f32 mCurrentRadius;
};
static_assert(sizeof(Collider) == 0x288);

View file

@ -239,6 +239,7 @@ const sead::Vector3f& HitInfo::tryGetHitEdgeNormal() const {
void SphereHitInfo::calcFixVector(sead::Vector3f* a1, sead::Vector3f* a2) const {
// TODO add proper names here, once the missing names for _70 and _80 in HitInfo are found
auto* hitInfo = this;
if (hitInfo->isCollisionAtFace()) {
calcFixVectorNormal(a1, a2);
return;
@ -261,6 +262,7 @@ void SphereHitInfo::calcFixVector(sead::Vector3f* a1, sead::Vector3f* a2) const
}
void SphereHitInfo::calcFixVectorNormal(sead::Vector3f* a1, sead::Vector3f* a2) const {
auto* hitInfo = this;
f32 unk = hitInfo->_70;
a1->x = hitInfo->triangle.getFaceNormal().x * unk;
a1->y = hitInfo->triangle.getFaceNormal().y * unk;
@ -271,21 +273,21 @@ void SphereHitInfo::calcFixVectorNormal(sead::Vector3f* a1, sead::Vector3f* a2)
void DiskHitInfo::calcFixVector(sead::Vector3f* a1, sead::Vector3f* a2) const {
// TODO add proper names here, once the missing names for _70 and _80 in HitInfo are found
if (hitInfo->isCollisionAtFace()) {
if (isCollisionAtFace()) {
calcFixVectorNormal(a1, a2);
return;
}
sead::Vector3f v20;
v20.x = hitInfo->_80.x - hitInfo->collisionHitPos.x;
v20.y = hitInfo->_80.y - hitInfo->collisionHitPos.y;
v20.z = hitInfo->_80.z - hitInfo->collisionHitPos.z;
v20.x = _80.x - collisionHitPos.x;
v20.y = _80.y - collisionHitPos.y;
v20.z = _80.z - collisionHitPos.z;
tryNormalizeOrZero(&v20);
sead::Vector3f scaled_a1;
sead::Vector3f scaled_a2;
f32 v13 = v20.dot(hitInfo->triangle.getFaceNormal() * hitInfo->_70);
f32 v12 = v20.dot(hitInfo->triangle.getFaceNormal());
f32 v13 = v20.dot(triangle.getFaceNormal() * _70);
f32 v12 = v20.dot(triangle.getFaceNormal());
sead::Vector3CalcCommon<f32>::multScalar(scaled_a1, v20, v13);
sead::Vector3CalcCommon<f32>::multScalar(scaled_a2, v20, v12);
*a1 = scaled_a1;
@ -293,12 +295,12 @@ void DiskHitInfo::calcFixVector(sead::Vector3f* a1, sead::Vector3f* a2) const {
}
void DiskHitInfo::calcFixVectorNormal(sead::Vector3f* a1, sead::Vector3f* a2) const {
f32 unk = hitInfo->_70;
a1->x = hitInfo->triangle.getFaceNormal().x * unk;
a1->y = hitInfo->triangle.getFaceNormal().y * unk;
a1->z = hitInfo->triangle.getFaceNormal().z * unk;
f32 unk = _70;
a1->x = triangle.getFaceNormal().x * unk;
a1->y = triangle.getFaceNormal().y * unk;
a1->z = triangle.getFaceNormal().z * unk;
if (a2)
a2->set(hitInfo->triangle.getFaceNormal());
a2->set(triangle.getFaceNormal());
}
} // namespace al

View file

@ -91,46 +91,17 @@ struct HitInfo {
CollisionLocation collisionLocation = CollisionLocation::None;
};
struct ArrowHitInfo {
HitInfo* operator*() { return hitInfo.data(); }
const HitInfo* operator*() const { return hitInfo.data(); }
HitInfo& operator->() { return *hitInfo; }
const HitInfo& operator->() const { return *hitInfo; }
sead::StorageFor<HitInfo> hitInfo{sead::ZeroInitializeTag{}};
struct ArrowHitInfo : public HitInfo {
};
struct SphereHitInfo {
struct SphereHitInfo : public HitInfo {
void calcFixVector(sead::Vector3f* a1, sead::Vector3f* a2) const;
void calcFixVectorNormal(sead::Vector3f* a1, sead::Vector3f* a2) const;
HitInfo* operator*() { return hitInfo.data(); }
const HitInfo* operator*() const { return hitInfo.data(); }
HitInfo& operator->() { return *hitInfo; }
const HitInfo& operator->() const { return *hitInfo; }
sead::StorageFor<HitInfo> hitInfo{sead::ZeroInitializeTag{}};
};
struct DiskHitInfo {
struct DiskHitInfo : public HitInfo {
void calcFixVector(sead::Vector3f* a1, sead::Vector3f* a2) const;
void calcFixVectorNormal(sead::Vector3f* a1, sead::Vector3f* a2) const;
HitInfo* operator*() { return hitInfo.data(); }
const HitInfo* operator*() const { return hitInfo.data(); }
HitInfo& operator->() { return *hitInfo; }
const HitInfo& operator->() const { return *hitInfo; }
sead::StorageFor<HitInfo> hitInfo{sead::ZeroInitializeTag{}};
};
} // namespace al

View file

@ -154,14 +154,22 @@ public:
void getMoveVector(sead::Vector3f* moveVec);
void calcStepMoveVector(sead::Vector3f* moveVec) const;
f32 getCurrentStep() const {
return mCurrentStep;
}
f32 getPrevStep() const {
return mPrevStep;
}
private:
sead::Vector3f mPos;
sead::Vector3f mMove;
f32 mSizeStart;
f32 mSizeEnd;
f32 mStepSize;
f32 mCurrentStep;
f32 mPrevStep;
sead::Vector3f mPos = {0.0f, 0.0f, 0.0f};
sead::Vector3f mMove = {0.0f, 0.0f, 0.0f};
f32 mSizeStart = 0.0f;
f32 mSizeEnd = 0.0f;
f32 mStepSize = 0.0f;
f32 mCurrentStep = 0.0f;
f32 mPrevStep = 0.0f;
};
class SpherePoseInterpolator {

View file

@ -475,7 +475,7 @@ bool isCollidedCollisionCode(const LiveActor* actor, const char* sensorName, con
u32 size = collider->getPlaneCount();
for (u32 i = 0; i < size; i++)
if (isEqualString(name, getCollisionCodeName(*collider->getPlane(i), sensorName)))
if (isEqualString(name, getCollisionCodeName(collider->getPlane(i), sensorName)))
return true;
return false;

View file

@ -2,6 +2,7 @@
#include "Library/Area/AreaObjUtil.h"
#include "Library/Audio/System/AudioKeeper.h"
#include "Library/Collision/Angle.h"
#include "Library/Collision/Collider.h"
#include "Library/Collision/CollisionPartsKeeperUtil.h"
#include "Library/Collision/CollisionPartsTriangle.h"
@ -783,7 +784,7 @@ bool reboundVelocityFromTriangles(LiveActor* actor, f32 reboundStrength, f32 reb
bool isRebound = false;
for (s32 i = 0; i != planeCount; i++) {
sead::Vector3f normal = collider->getPlane(i)->getNormal(0);
sead::Vector3f normal = collider->getPlane(i).getNormal(0);
f32 dot = normal.dot(getVelocity(actor));
if (reboundStrength < 0.0) {
addVelocity(actor, -((reboundStrength + 1.0f) * dot * normal));

View file

@ -6,15 +6,15 @@ CollidedShapeResult::CollidedShapeResult(const CollisionShapeInfoBase* shapeInfo
: mShapeInfo(shapeInfo) {}
void CollidedShapeResult::setArrowHitInfo(const al::ArrowHitInfo& arrowHitInfo) {
*mArrowHitInfo.hitInfo = *arrowHitInfo.hitInfo;
*mArrowHitInfo.data() = arrowHitInfo;
}
void CollidedShapeResult::setSphereHitInfo(const al::SphereHitInfo& sphereHitInfo) {
*mSphereHitInfo.hitInfo = *sphereHitInfo.hitInfo;
*mSphereHitInfo.data() = sphereHitInfo;
}
void CollidedShapeResult::setDiskHitInfo(const al::DiskHitInfo& diskHitInfo) {
*mDiskHitInfo.hitInfo = *diskHitInfo.hitInfo;
*mDiskHitInfo.data() = diskHitInfo;
}
bool CollidedShapeResult::isArrow() const {
@ -30,15 +30,15 @@ bool CollidedShapeResult::isDisk() const {
}
const al::ArrowHitInfo& CollidedShapeResult::getArrowHitInfo() const {
return mArrowHitInfo;
return mArrowHitInfo.ref();
}
const al::SphereHitInfo& CollidedShapeResult::getSphereHitInfo() const {
return mSphereHitInfo;
return mSphereHitInfo.ref();
}
const al::DiskHitInfo& CollidedShapeResult::getDiskHitInfo() const {
return mDiskHitInfo;
return mDiskHitInfo.ref();
}
const CollisionShapeInfoArrow* CollidedShapeResult::getShapeInfoArrow() const {
@ -55,7 +55,7 @@ const CollisionShapeInfoDisk* CollidedShapeResult::getShapeInfoDisk() const {
void CollidedShapeResult::operator=(const CollidedShapeResult& other) {
mShapeInfo = other.mShapeInfo;
setArrowHitInfo(other.mArrowHitInfo);
setSphereHitInfo(other.mSphereHitInfo);
setDiskHitInfo(other.mDiskHitInfo);
setArrowHitInfo(other.getArrowHitInfo());
setSphereHitInfo(other.getSphereHitInfo());
setDiskHitInfo(other.getDiskHitInfo());
}

View file

@ -33,9 +33,9 @@ public:
private:
const CollisionShapeInfoBase* mShapeInfo;
al::ArrowHitInfo mArrowHitInfo;
al::SphereHitInfo mSphereHitInfo;
al::DiskHitInfo mDiskHitInfo;
sead::StorageFor<al::ArrowHitInfo> mArrowHitInfo {sead::ZeroInitializeTag{}};
sead::StorageFor<al::SphereHitInfo> mSphereHitInfo {sead::ZeroInitializeTag{}};
sead::StorageFor<al::DiskHitInfo> mDiskHitInfo {sead::ZeroInitializeTag{}};
};
static_assert(sizeof(CollidedShapeResult) == 0x1e8);

View file

@ -1,7 +1,7 @@
#include "Player/PlayerCeilingCheck.h"
#include "Library/Base/StringUtil.h"
#include "Library/Collision/Collider.h"
#include "Library/Collision/Angle.h"
#include "Player/PlayerCollisionCheckSphereMove.h"

View file

@ -117,9 +117,9 @@ void PlayerJudgeWallKeep::update() {
if (alCollisionUtil::getLastPolyOnArrow(mPlayer, &hitInfo1, nearWallPosition + sideOffset,
-sideOffset, nullptr, &filterWallOnly)) {
const sead::Vector3f& hitPos =
alCollisionUtil::getCollisionHitPos(hitInfo1->hitInfo.data());
alCollisionUtil::getCollisionHitPos(hitInfo1);
const sead::Vector3f& hitNormal =
alCollisionUtil::getCollisionHitNormal(hitInfo1->hitInfo.data());
alCollisionUtil::getCollisionHitNormal(hitInfo1);
if (!rs::calcExistCollisionBorder(mPlayer, hitPos, hitNormal)) {
if (sead::Mathf::abs(al::calcAngleOnPlaneDegree(
hitNormal, collidedWallNormal, gravity2)) > mConst->getWallFollowAngleH())
@ -134,9 +134,9 @@ void PlayerJudgeWallKeep::update() {
if (alCollisionUtil::getLastPolyOnArrow(mPlayer, &hitInfo2, nearWallPosition - sideOffset,
sideOffset, nullptr, &filterWallOnly)) {
const sead::Vector3f& hitPos =
alCollisionUtil::getCollisionHitPos(hitInfo2->hitInfo.data());
alCollisionUtil::getCollisionHitPos(hitInfo2);
const sead::Vector3f& hitNormal =
alCollisionUtil::getCollisionHitNormal(hitInfo2->hitInfo.data());
alCollisionUtil::getCollisionHitNormal(hitInfo2);
if (!rs::calcExistCollisionBorder(mPlayer, hitPos, hitNormal)) {
if (sead::Mathf::abs(al::calcAngleOnPlaneDegree(
hitNormal, collidedWallNormal, gravity2)) > mConst->getWallFollowAngleH())