mirror of
https://github.com/MonsterDruide1/OdysseyDecomp
synced 2026-04-23 09:04:21 +00:00
Player: Implement PlayerCeilingCheck (#607)
This commit is contained in:
parent
a016e87a67
commit
5fdfcf9756
|
|
@ -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.
|
81
src/Player/PlayerCeilingCheck.cpp
Normal file
81
src/Player/PlayerCeilingCheck.cpp
Normal 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);
|
||||
}
|
||||
32
src/Player/PlayerCeilingCheck.h
Normal file
32
src/Player/PlayerCeilingCheck.h
Normal 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);
|
||||
39
src/Player/PlayerCollisionCheckSphereMove.h
Normal file
39
src/Player/PlayerCollisionCheckSphereMove.h
Normal 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);
|
||||
Loading…
Reference in a new issue