Player: Implement PlayerCeilingCheck (#607)

This commit is contained in:
MonsterDruide1 2025-05-25 15:08:22 +02:00 committed by GitHub
parent a016e87a67
commit 5fdfcf9756
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 157 additions and 5 deletions

View file

@ -26449,11 +26449,11 @@ Address,Quality,Size,Name
0x000000710042f324,U,000008,_ZNK12_GLOBAL__N_125PlayerCarryKeeperNrvThrow7executeEPN2al11NerveKeeperE
0x000000710042f32c,U,000096,_ZNK12_GLOBAL__N_127PlayerCarryKeeperNrvRelease7executeEPN2al11NerveKeeperE
0x000000710042f38c,U,000164,_ZNK12_GLOBAL__N_125PlayerCarryKeeperNrvCarry7executeEPN2al11NerveKeeperE
0x000000710042f430,U,000088,_ZN18PlayerCeilingCheckC2EPN2al17CollisionDirectorE
0x000000710042f488,U,000012,_ZN18PlayerCeilingCheck23setupCeilingCheckNormalEv
0x000000710042f494,U,000728,_ZN18PlayerCeilingCheck6updateERKN4sead7Vector3IfEES4_ffff
0x000000710042f76c,U,000012,_ZN18PlayerCeilingCheck21setupCeilingCheckGrabEv
0x000000710042f778,U,000012,_ZN18PlayerCeilingCheck23setCollisionPartsFilterEPKN2al24CollisionPartsFilterBaseE
0x000000710042f430,O,000088,_ZN18PlayerCeilingCheckC2EPN2al17CollisionDirectorE
0x000000710042f488,O,000012,_ZN18PlayerCeilingCheck23setupCeilingCheckNormalEv
0x000000710042f494,O,000728,_ZN18PlayerCeilingCheck6updateERKN4sead7Vector3IfEES4_ffff
0x000000710042f76c,O,000012,_ZN18PlayerCeilingCheck21setupCeilingCheckGrabEv
0x000000710042f778,O,000012,_ZN18PlayerCeilingCheck23setCollisionPartsFilterEPKN2al24CollisionPartsFilterBaseE
0x000000710042f784,U,001776,_ZN14PlayerColliderC1EPN2al17CollisionDirectorEPKN4sead8Matrix34IfEEPKNS3_7Vector3IfEESB_b
0x000000710042fe74,U,000180,_ZN14PlayerCollider12onInvalidateEv
0x000000710042ff28,U,000056,_ZN14PlayerCollider23setCollisionShapeKeeperEP20CollisionShapeKeeper

Can't render this file because it is too large.

View file

@ -0,0 +1,81 @@
#include "Player/PlayerCeilingCheck.h"
#include "Library/Base/StringUtil.h"
#include "Library/Collision/Collider.h"
#include "Player/PlayerCollisionCheckSphereMove.h"
PlayerCeilingCheck::PlayerCeilingCheck(al::CollisionDirector* director) {
mCollisionCheckSphereMove = new PlayerCollisionCheckSphereMove(director, 16);
setupCeilingCheckNormal();
}
void PlayerCeilingCheck::setupCeilingCheckNormal() {
mIsCeilingCheckNormal = true;
mIsCeilingCheckGrab = false;
}
void PlayerCeilingCheck::update(const sead::Vector3f& trans, const sead::Vector3f& up, f32 tall,
f32 collisionRadiusSquat, f32 headClearance, f32 holdHeight) {
sead::Vector3f checkStart;
checkStart.set(trans);
f32 playerHeight;
sead::Vector3f newCheckStart;
if (mIsCeilingCheckGrab) {
newCheckStart = trans - (collisionRadiusSquat + headClearance) * up;
playerHeight = 2 * tall;
} else {
newCheckStart = trans + (collisionRadiusSquat - headClearance) * up;
playerHeight = (2 * tall) - (2 * collisionRadiusSquat);
tall -= 2 * collisionRadiusSquat;
}
checkStart = newCheckStart;
f32 checkHeight = playerHeight + headClearance + holdHeight;
f32 minTStandUp = (tall + headClearance) / checkHeight;
mCollisionCheckSphereMove->checkSphereMove(checkStart, checkHeight * up, collisionRadiusSquat);
sead::Vector3f down = -up;
f32 minTValue2 = 1.0f;
f32 minTValue = 1.0f;
s32 minIndex = -1;
for (u32 i = 0; i < mCollisionCheckSphereMove->getNum(); i++) {
if (!al::isCeilingPolygon(mCollisionCheckSphereMove->getNormal(i), down))
continue;
f32 tValue = mCollisionCheckSphereMove->getTValue(i);
if (minTValue > tValue)
minTValue = tValue;
if (mIsCeilingCheckNormal &&
al::isEqualString(mCollisionCheckSphereMove->getMapCodeName(i), "Press"))
continue;
if (al::isEqualString(mCollisionCheckSphereMove->getWallCodeName(i), "NoCeilSquat"))
continue;
minIndex = minTValue2 > tValue ? i : minIndex;
minTValue2 = sead::Mathf::clampMax(minTValue2, tValue);
}
f32 minTHoldUp = (0.99f * (checkHeight - holdHeight));
f32 maxTPressedCeil = (0.01f * (checkHeight - holdHeight));
mIsEnableStandUp = minTValue2 >= minTStandUp;
mIsEnableHoldUp = minTValue >= minTHoldUp / checkHeight;
mIsPressedCeil = minTValue2 < maxTPressedCeil / checkHeight;
mCeilCheckHeight = checkHeight + (checkStart - trans).dot(up);
mSafetyCeilSpace = mCeilCheckHeight;
if (minIndex >= 0)
mSafetyCeilSpace = (mCollisionCheckSphereMove->getPos(minIndex) - trans).dot(up);
}
void PlayerCeilingCheck::setupCeilingCheckGrab() {
mIsCeilingCheckNormal = false;
mIsCeilingCheckGrab = true;
}
void PlayerCeilingCheck::setCollisionPartsFilter(const al::CollisionPartsFilterBase* filter) {
mCollisionCheckSphereMove->setCollisionPartsFilter(filter);
}

View file

@ -0,0 +1,32 @@
#pragma once
#include <math/seadVector.h>
namespace al {
class CollisionDirector;
class CollisionPartsFilterBase;
} // namespace al
class PlayerCollisionCheckSphereMove;
class PlayerCeilingCheck {
public:
PlayerCeilingCheck(al::CollisionDirector* director);
void setupCeilingCheckNormal();
void update(const sead::Vector3f& trans, const sead::Vector3f& up, f32 tall,
f32 collisionRadiusSquat, f32 headClearance, f32 holdHeight);
void setupCeilingCheckGrab();
void setCollisionPartsFilter(const al::CollisionPartsFilterBase* filter);
private:
PlayerCollisionCheckSphereMove* mCollisionCheckSphereMove = nullptr;
f32 mSafetyCeilSpace = 0.0f;
f32 mCeilCheckHeight = 0.0f;
bool mIsCeilingCheckNormal = true;
bool mIsCeilingCheckGrab = false;
bool mIsEnableStandUp = false;
bool mIsEnableHoldUp = false;
bool mIsPressedCeil = false;
};
static_assert(sizeof(PlayerCeilingCheck) == 0x18);

View file

@ -0,0 +1,39 @@
#pragma once
#include <math/seadVector.h>
#include "Library/Collision/IUseCollision.h"
namespace al {
class CollisionDirector;
class CollisionParts;
class CollisionPartsFilterBase;
} // namespace al
class PlayerCollisionCheckSphereMove : public al::IUseCollision {
public:
PlayerCollisionCheckSphereMove(al::CollisionDirector*, s32);
al::CollisionDirector* getCollisionDirector() const override;
bool checkSphereMove(const sead::Vector3f&, const sead::Vector3f&, f32);
void gatherCollisionParts(al::CollisionParts*);
u32 getNum() const;
f32 getTValue(u32) const;
const sead::Vector3f& getPos(u32) const;
const sead::Vector3f& getNormal(u32) const;
const al::CollisionParts* getCollisionParts(u32) const;
const char* getMapCodeName(u32) const;
const char* getWallCodeName(u32) const;
const char* getMaterialCodeName(u32) const;
void setCollisionPartsFilter(const al::CollisionPartsFilterBase* filter) {
mCollisionPartsFilter = filter;
}
private:
void* _8[0x50 / 8];
const al::CollisionPartsFilterBase* mCollisionPartsFilter;
};
static_assert(sizeof(PlayerCollisionCheckSphereMove) == 0x60);