Library/Collision: Implement CollisionDirector

This commit is contained in:
MonsterDruide1 2024-05-23 22:22:46 +02:00
parent d9a89a3192
commit 7214961ac3
6 changed files with 354 additions and 46 deletions

View file

@ -52180,29 +52180,29 @@ Address,Quality,Size,Name
0x00000071008465fc,U,000360,_ZN23alCollisionCodeFunction21judgeIsBetterCodeNameEPKN2al17CollisionCodeListEPKcS5_S5_S5_
0x0000007100846764,U,000208,_ZN23alCollisionCodeFunction33judgeIsBetterCodeNameWithAreaNameEPKN2al25CollisionCodeRelationListEPKcS5_S5_S5_S5_S5_
0x0000007100846834,U,000284,
0x0000007100846950,U,001936,_ZN2al17CollisionDirectorC1EPNS_15ExecuteDirectorE
0x00000071008470e0,U,000028,_ZN2al17CollisionDirector14setPartsKeeperEPNS_21ICollisionPartsKeeperE
0x00000071008470fc,U,000016,_ZN2al17CollisionDirector7endInitEv
0x000000710084710c,U,000008,_ZN2al17CollisionDirector14setPartsFilterEPKNS_24CollisionPartsFilterBaseE
0x0000007100847114,U,000008,_ZN2al17CollisionDirector12setTriFilterEPKNS_18TriangleFilterBaseE
0x000000710084711c,U,000088,_ZN2al17CollisionDirector16checkStrikePointERKN4sead7Vector3IfEEPNS_7HitInfoE
0x0000007100847174,U,000164,_ZN2al17CollisionDirector17checkStrikeSphereERKN4sead7Vector3IfEEfbS5_
0x0000007100847218,U,000428,_ZN2al17CollisionDirector16checkStrikeArrowERKN4sead7Vector3IfEES5_
0x00000071008473c4,U,000152,_ZN2al17CollisionDirector26checkStrikeSphereForPlayerERKN4sead7Vector3IfEEf
0x000000710084745c,U,000156,_ZN2al17CollisionDirector15checkStrikeDiskERKN4sead7Vector3IfEEffS5_
0x00000071008474f8,U,000016,_ZN2al17CollisionDirector18getStrikeArrowInfoEj
0x0000007100847508,U,000012,_ZNK2al17CollisionDirector21getStrikeArrowInfoNumEv
0x0000007100847514,U,000016,_ZN2al17CollisionDirector19getStrikeSphereInfoEj
0x0000007100847524,U,000012,_ZNK2al17CollisionDirector22getStrikeSphereInfoNumEv
0x0000007100847530,U,000016,_ZN2al17CollisionDirector17getStrikeDiskInfoEj
0x0000007100847540,U,000012,_ZNK2al17CollisionDirector20getStrikeDiskInfoNumEv
0x000000710084754c,U,000020,_ZN2al17CollisionDirector32getSphereHitInfoArrayForColliderEPPNS_13SphereHitInfoEPj
0x0000007100847560,U,000020,_ZN2al17CollisionDirector30getDiskHitInfoArrayForColliderEPPNS_11DiskHitInfoEPj
0x0000007100847574,U,000024,_ZN2al17CollisionDirector7executeEv
0x000000710084758c,U,000060,_ZNK2al17CollisionDirector30searchCollisionPartsWithSphereERKN4sead7Vector3IfEEfRNS1_10IDelegate1IPNS_14CollisionPartsEEEPKNS_24CollisionPartsFilterBaseE
0x00000071008475c8,U,000020,_ZN2al17CollisionDirector30validateCollisionPartsPtrArrayEPN4sead8PtrArrayINS_14CollisionPartsEEE
0x00000071008475dc,U,000012,_ZN2al17CollisionDirector32invalidateCollisionPartsPtrArrayEv
0x00000071008475e8,U,000032,_ZNK2al17CollisionDirector25getCollisionPartsPtrArrayEv
0x0000007100846950,m,001936,_ZN2al17CollisionDirectorC2EPNS_15ExecuteDirectorE
0x00000071008470e0,O,000028,_ZN2al17CollisionDirector14setPartsKeeperEPNS_21ICollisionPartsKeeperE
0x00000071008470fc,O,000016,_ZN2al17CollisionDirector7endInitEv
0x000000710084710c,O,000008,_ZN2al17CollisionDirector14setPartsFilterEPKNS_24CollisionPartsFilterBaseE
0x0000007100847114,O,000008,_ZN2al17CollisionDirector12setTriFilterEPKNS_18TriangleFilterBaseE
0x000000710084711c,m,000088,_ZN2al17CollisionDirector16checkStrikePointERKN4sead7Vector3IfEEPNS_7HitInfoE
0x0000007100847174,m,000164,_ZN2al17CollisionDirector17checkStrikeSphereERKN4sead7Vector3IfEEfbS5_
0x0000007100847218,M,000428,_ZN2al17CollisionDirector16checkStrikeArrowERKN4sead7Vector3IfEES5_
0x00000071008473c4,m,000152,_ZN2al17CollisionDirector26checkStrikeSphereForPlayerERKN4sead7Vector3IfEEf
0x000000710084745c,M,000156,_ZN2al17CollisionDirector15checkStrikeDiskERKN4sead7Vector3IfEEffS5_
0x00000071008474f8,O,000016,_ZN2al17CollisionDirector18getStrikeArrowInfoEj
0x0000007100847508,O,000012,_ZNK2al17CollisionDirector21getStrikeArrowInfoNumEv
0x0000007100847514,O,000016,_ZN2al17CollisionDirector19getStrikeSphereInfoEj
0x0000007100847524,O,000012,_ZNK2al17CollisionDirector22getStrikeSphereInfoNumEv
0x0000007100847530,O,000016,_ZN2al17CollisionDirector17getStrikeDiskInfoEj
0x0000007100847540,O,000012,_ZNK2al17CollisionDirector20getStrikeDiskInfoNumEv
0x000000710084754c,O,000020,_ZN2al17CollisionDirector32getSphereHitInfoArrayForColliderEPPNS_13SphereHitInfoEPj
0x0000007100847560,O,000020,_ZN2al17CollisionDirector30getDiskHitInfoArrayForColliderEPPNS_11DiskHitInfoEPj
0x0000007100847574,O,000024,_ZN2al17CollisionDirector7executeEv
0x000000710084758c,O,000060,_ZNK2al17CollisionDirector30searchCollisionPartsWithSphereERKN4sead7Vector3IfEEfRNS1_10IDelegate1IPNS_14CollisionPartsEEEPKNS_24CollisionPartsFilterBaseE
0x00000071008475c8,O,000020,_ZN2al17CollisionDirector30validateCollisionPartsPtrArrayEPN4sead8PtrArrayINS_14CollisionPartsEEE
0x00000071008475dc,O,000012,_ZN2al17CollisionDirector32invalidateCollisionPartsPtrArrayEv
0x00000071008475e8,O,000032,_ZNK2al17CollisionDirector25getCollisionPartsPtrArrayEv
0x0000007100847608,U,000332,_ZN2al14CollisionPartsC1EPvPKv
0x0000007100847754,U,000084,_ZN2al14CollisionParts15calcInvMtxScaleEv
0x00000071008477a8,U,000008,_ZNK2al14CollisionParts16getConnectedHostEv

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

View file

@ -0,0 +1,67 @@
#pragma once
#include <math/seadVector.h>
#include <math/seadBoundBox.h>
#include "basis/seadTypes.h"
namespace al {
class CollisionPartsFilterBase;
class TriangleFilterBase;
struct CollisionCheckInfoBase {
public:
CollisionCheckInfoBase(const sead::Vector3f& pos, const al::CollisionPartsFilterBase* collisionFilter, const al::TriangleFilterBase* triFilter)
: mPos(pos), mCollisionPartsFilter(collisionFilter), mTriFilterBase(triFilter) {}
CollisionCheckInfoBase(const sead::Vector3f& pos)
: mPos(pos) {}
const sead::Vector3f& mPos;
const al::CollisionPartsFilterBase* mCollisionPartsFilter = nullptr;
const al::TriangleFilterBase* mTriFilterBase = nullptr;
};
struct SphereCheckInfo : public CollisionCheckInfoBase {
public:
SphereCheckInfo(const sead::Vector3f& pos, const al::CollisionPartsFilterBase* collisionFilter, const al::TriangleFilterBase* triFilter, f32 radius)
: CollisionCheckInfoBase(pos, collisionFilter, triFilter), mRadius(radius) {}
SphereCheckInfo(const sead::Vector3f& pos, f32 radius)
: CollisionCheckInfoBase(pos), mRadius(radius) {}
f32 mRadius;
};
struct ArrowCheckInfo : public CollisionCheckInfoBase {
public:
ArrowCheckInfo(const sead::Vector3f& pos, const sead::Vector3f& unk1) : CollisionCheckInfoBase(pos), unk1(unk1), unk2(pos+unk1), unk3() {
// TODO does this differently, somehow incremental
unk3.set(pos.x, pos.y, pos.z, unk2.x, unk2.y, unk2.z);
}
const sead::Vector3f& unk1;
sead::Vector3f unk2;
sead::BoundBox3f unk3;
};
struct DiskCheckInfo : public CollisionCheckInfoBase {
public:
// TODO make this a function being generated, not inlined
DiskCheckInfo(const sead::Vector3f& pos, f32 unk1, f32 unk2, const sead::Vector3f& unk3) : CollisionCheckInfoBase(pos), unk1(unk1), unk2(unk2), unk3(unk3) {
if(unk1 <= unk2)
unk4 = sead::Mathf::sqrt(sead::Mathf::square(unk2) + sead::Mathf::square(unk1));
else
unk4 = unk1 * 1.4142f;
}
f32 unk1;
f32 unk2;
const sead::Vector3f& unk3;
f32 unk4 = 0.0f;
};
} // namespace al

View file

@ -1,10 +1,12 @@
#pragma once
#include <container/seadPtrArray.h>
#include <container/seadObjArray.h>
#include <math/seadVector.h>
#include <prim/seadDelegate.h>
#include "Library/Collision/CollisionResultBuffer.h"
#include "Library/Execute/IUseExecutor.h"
#include "Library/HostIO/HioNode.h"
namespace al {
class ICollisionPartsKeeper;
@ -14,15 +16,15 @@ class CollisionPartsFilterBase;
class TriangleFilterBase;
class Strike;
struct HitInfo;
struct ArrowHitInfo;
struct DiskHitInfo;
struct SphereHitInfo;
class CollisionParts;
class ExecuteDirector;
class CollisionDirector : public IUseExecutor {
class CollisionDirector : public HioNode, public IUseExecutor {
public:
CollisionDirector(ExecuteDirector* executeDirector);
void execute() override;
void setPartsKeeper(ICollisionPartsKeeper* partsKeeper);
void endInit();
void setPartsFilter(const CollisionPartsFilterBase*);
@ -32,32 +34,33 @@ public:
bool checkStrikeArrow(const sead::Vector3f&, const sead::Vector3f&);
bool checkStrikeSphereForPlayer(const sead::Vector3f&, f32);
bool checkStrikeDisk(const sead::Vector3f&, f32, f32, const sead::Vector3f&);
sead::PtrArray<ArrowHitInfo>* getStrikeArrowInfo(u32 index);
u32 getStrikeArrowInfoNum();
sead::PtrArray<DiskHitInfo>* getStrikeSphereInfo(u32 index);
u32 getStrikeSphereInfoNum();
sead::PtrArray<SphereHitInfo>* getStrikeDiskInfo(u32 index);
u32 getStrikeDiskInfoNum();
ArrowHitInfo* getStrikeArrowInfo(u32 index);
u32 getStrikeArrowInfoNum() const;
SphereHitInfo* getStrikeSphereInfo(u32 index);
u32 getStrikeSphereInfoNum() const;
DiskHitInfo* getStrikeDiskInfo(u32 index);
u32 getStrikeDiskInfoNum() const;
void getSphereHitInfoArrayForCollider(SphereHitInfo** infoArray, u32* count);
void getDiskHitInfoArrayForCollider(DiskHitInfo** infoArray, u32* count);
void execute();
void searchCollisionPartsWithSphere(const sead::Vector3f&, f32,
sead::IDelegate1<CollisionParts*>&,
const CollisionPartsFilterBase*);
const CollisionPartsFilterBase*) const;
void validateCollisionPartsPtrArray(sead::PtrArray<CollisionParts>*);
void invalidateCollisionPartsPtrArray();
sead::PtrArray<CollisionParts>* getCollisionPartsPtrArray();
sead::PtrArray<CollisionParts>* getCollisionPartsPtrArray() const;
private:
ICollisionPartsKeeper* mActivePartsKeeper;
CollisionPartsKeeperOctree* mRootOctree;
ICollisionPartsKeeper* mActivePartsKeeper = nullptr;
ICollisionPartsKeeper* mPartsKeeper = nullptr;
CollisionPartsKeeperPtrArray* mCollisionPartsKeeperPtrArray;
CollisionPartsFilterBase* mCollisionPartsFilterBase;
TriangleFilterBase* mTriangleFilterBase;
sead::PtrArray<ArrowHitInfo>* mStrikeArrowHitInfos;
sead::PtrArray<DiskHitInfo>* mStrikeDiskHitInfos;
sead::PtrArray<SphereHitInfo>* mStrikeSphereHitInfos;
SphereHitInfo* mSphereHitArray;
DiskHitInfo* mDiskHitArray;
const CollisionPartsFilterBase* mCollisionPartsFilterBase = nullptr;
const TriangleFilterBase* mTriangleFilterBase = nullptr;
ArrowHitResultBuffer* mStrikeArrowHitInfos = nullptr;
SphereHitResultBuffer* mStrikeSphereHitInfos = nullptr;
DiskHitResultBuffer* mStrikeDiskHitInfos = nullptr;
SphereHitInfo* mSphereHitArray = nullptr;
DiskHitInfo* mDiskHitArray = nullptr;
};
static_assert(sizeof(CollisionDirector) == 0x58);
} // namespace al

View file

@ -0,0 +1,55 @@
#pragma once
#include <basis/seadTypes.h>
#include <math/seadVector.h>
#include <prim/seadDelegate.h>
#include "Library/Collision/CollisionResultBuffer.h"
#include "container/seadPtrArray.h"
namespace al {
class CollisionParts;
class HitInfo;
class CollisionCheckInfoBase;
class SphereCheckInfo;
class ArrowCheckInfo;
class DiskCheckInfo;
class ICollisionPartsKeeper {
public:
virtual void endInit();
virtual void addCollisionParts(al::CollisionParts*);
virtual void connectToCollisionPartsList(al::CollisionParts*);
virtual void disconnectToCollisionPartsList(al::CollisionParts*);
virtual void resetToCollisionPartsList(al::CollisionParts*);
virtual bool checkStrikePoint(HitInfo*, const CollisionCheckInfoBase&) const;
virtual bool checkStrikeSphere(SphereHitResultBuffer*, const SphereCheckInfo&, bool, const sead::Vector3f&) const;
virtual bool checkStrikeArrow(ArrowHitResultBuffer*, const ArrowCheckInfo&) const;
virtual bool checkStrikeSphereForPlayer(SphereHitResultBuffer*, const SphereCheckInfo&) const;
virtual bool checkStrikeDisk(DiskHitResultBuffer*, const DiskCheckInfo&) const;
virtual void searchWithSphere(const SphereCheckInfo&, sead::IDelegate1<CollisionParts*>&) const;
virtual void movement();
};
class CollisionPartsKeeperPtrArray : public ICollisionPartsKeeper {
public:
CollisionPartsKeeperPtrArray();
void setPtrArray(sead::PtrArray<CollisionParts>* ptrArray) { mPtrArray = ptrArray; }
sead::PtrArray<CollisionParts>* getPtrArray() const { return mPtrArray; }
private:
sead::PtrArray<CollisionParts>* mPtrArray;
};
static_assert(sizeof(CollisionPartsKeeperPtrArray) == 0x10);
class CollisionPartsKeeperOctree : public ICollisionPartsKeeper {
public:
CollisionPartsKeeperOctree(s32, s32, f32);
private:
void* size[0xFF/8];
};
static_assert(sizeof(CollisionPartsKeeperOctree) == 0x100);
}

View file

@ -0,0 +1,14 @@
#pragma once
#include <container/seadObjArray.h>
namespace al {
struct ArrowHitInfo;
struct SphereHitInfo;
struct DiskHitInfo;
using ArrowHitResultBuffer = sead::ObjArray<ArrowHitInfo>;
using SphereHitResultBuffer = sead::ObjArray<SphereHitInfo>;
using DiskHitResultBuffer = sead::ObjArray<DiskHitInfo>;
}

View file

@ -0,0 +1,169 @@
#include "Library/Collision/CollisionDirector.h"
#include "Library/Collision/CollisionPartsKeeper.h"
#include "Library/Collision/KTriangle.h"
#include "Library/Collision/CollisionCheckInfo.h"
#include "Library/Execute/ExecuteTableHolderUpdate.h"
#include "container/seadObjArray.h"
#include <cstdio>
#include <new>
#define DEREF_NULL *(volatile int*)0;
#define WARN_UNIMPL printf("Function not implemented: %s (%s:%d)\n", __func__, __FILE__, __LINE__)
#define CRASH {WARN_UNIMPL;DEREF_NULL}
namespace al {
// NON_MATCHING: mismatch in allocBuffer
CollisionDirector::CollisionDirector(ExecuteDirector* executeDirector) : mCollisionPartsKeeperPtrArray(new CollisionPartsKeeperPtrArray()) {
mStrikeArrowHitInfos = new ArrowHitResultBuffer();
mStrikeArrowHitInfos->allocBuffer(512, nullptr);
mStrikeSphereHitInfos = new SphereHitResultBuffer();
mStrikeSphereHitInfos->allocBuffer(512, nullptr);
mStrikeDiskHitInfos = new DiskHitResultBuffer();
mStrikeDiskHitInfos->allocBuffer(512, nullptr);
mSphereHitArray = new SphereHitInfo[64];
mDiskHitArray = new DiskHitInfo[64];
al::registerExecutorUser(this, executeDirector, "コリジョンディレクター");
setPartsKeeper(new CollisionPartsKeeperOctree(256, 8, 1000.0f));
}
void CollisionDirector::setPartsKeeper(ICollisionPartsKeeper* partsKeeper) {
mPartsKeeper = partsKeeper;
if(mActivePartsKeeper != mCollisionPartsKeeperPtrArray)
mActivePartsKeeper = mPartsKeeper;
}
void CollisionDirector::endInit() {
mActivePartsKeeper->endInit();
}
void CollisionDirector::setPartsFilter(const CollisionPartsFilterBase* filter) {
mCollisionPartsFilterBase = filter;
}
void CollisionDirector::setTriFilter(const TriangleFilterBase* filter) {
mTriangleFilterBase = filter;
}
// NON_MATCHING: additional "AND 1" at the end
bool CollisionDirector::checkStrikePoint(const sead::Vector3f& point, HitInfo* info) {
auto checkInfo = CollisionCheckInfoBase {point, mCollisionPartsFilterBase, mTriangleFilterBase };
u32 result = mActivePartsKeeper->checkStrikePoint(info, checkInfo);
mCollisionPartsFilterBase = nullptr;
mTriangleFilterBase = nullptr;
return result;
}
// NON_MATCHING: additional "AND 1" at the end
bool CollisionDirector::checkStrikeSphere(const sead::Vector3f& pos, f32 radius, bool unk3, const sead::Vector3f& unk4) {
mStrikeSphereHitInfos->clear();
auto checkInfo = SphereCheckInfo {pos, radius};
checkInfo.mCollisionPartsFilter = mCollisionPartsFilterBase;
checkInfo.mTriFilterBase = mTriangleFilterBase;
auto* infos = mStrikeSphereHitInfos;
bool result = mActivePartsKeeper->checkStrikeSphere(infos, checkInfo, unk3, unk4);
mCollisionPartsFilterBase = nullptr;
mTriangleFilterBase = nullptr;
return result;
}
// NON_MATCHING: Incremental BoundBox for ArrowCheckInfo, additional "AND 1" at the end
bool CollisionDirector::checkStrikeArrow(const sead::Vector3f& pos, const sead::Vector3f& unk2) {
mStrikeArrowHitInfos->clear();
auto checkInfo = ArrowCheckInfo {pos, unk2};
checkInfo.mCollisionPartsFilter = mCollisionPartsFilterBase;
checkInfo.mTriFilterBase = mTriangleFilterBase;
auto* infos = mStrikeArrowHitInfos;
bool result = mActivePartsKeeper->checkStrikeArrow(infos, checkInfo);
mCollisionPartsFilterBase = nullptr;
mTriangleFilterBase = nullptr;
return result;
}
// NON_MATCHING: additional "AND 1" at the end
bool CollisionDirector::checkStrikeSphereForPlayer(const sead::Vector3f& pos, f32 radius) {
mStrikeSphereHitInfos->clear();
auto checkInfo = SphereCheckInfo {pos, radius};
checkInfo.mCollisionPartsFilter = mCollisionPartsFilterBase;
checkInfo.mTriFilterBase = mTriangleFilterBase;
auto* infos = mStrikeSphereHitInfos;
bool result = mActivePartsKeeper->checkStrikeSphereForPlayer(infos, checkInfo);
mCollisionPartsFilterBase = nullptr;
mTriangleFilterBase = nullptr;
return result;
}
// NON_MATCHING: inlined constructor of DiskCheckInfo instead of explicit call
bool CollisionDirector::checkStrikeDisk(const sead::Vector3f& unk1, f32 unk2, f32 unk3, const sead::Vector3f& unk4) {
mStrikeDiskHitInfos->clear();
auto checkInfo = DiskCheckInfo {unk1, unk2, unk3, unk4};
checkInfo.mCollisionPartsFilter = mCollisionPartsFilterBase;
checkInfo.mTriFilterBase = mTriangleFilterBase;
auto* infos = mStrikeDiskHitInfos;
bool result = mActivePartsKeeper->checkStrikeDisk(infos, checkInfo);
mCollisionPartsFilterBase = nullptr;
mTriangleFilterBase = nullptr;
return result;
}
ArrowHitInfo* CollisionDirector::getStrikeArrowInfo(u32 index) {
return mStrikeArrowHitInfos->unsafeAt(index);
}
u32 CollisionDirector::getStrikeArrowInfoNum() const {
return mStrikeArrowHitInfos->size();
}
SphereHitInfo* CollisionDirector::getStrikeSphereInfo(u32 index) {
return mStrikeSphereHitInfos->unsafeAt(index);
}
u32 CollisionDirector::getStrikeSphereInfoNum() const {
return mStrikeSphereHitInfos->size();
}
DiskHitInfo* CollisionDirector::getStrikeDiskInfo(u32 index) {
return mStrikeDiskHitInfos->unsafeAt(index);
}
u32 CollisionDirector::getStrikeDiskInfoNum() const {
return mStrikeDiskHitInfos->size();
}
void CollisionDirector::getSphereHitInfoArrayForCollider(SphereHitInfo** infoArray, u32* count) {
*infoArray = mSphereHitArray;
*count = 64;
}
void CollisionDirector::getDiskHitInfoArrayForCollider(DiskHitInfo** infoArray, u32* count) {
*infoArray = mDiskHitArray;
*count = 64;
}
void CollisionDirector::execute() {
if(mActivePartsKeeper)
mActivePartsKeeper->movement();
}
void CollisionDirector::searchCollisionPartsWithSphere(const sead::Vector3f& pos, f32 radius,
sead::IDelegate1<CollisionParts*>& delegate,
const CollisionPartsFilterBase* filter) const {
auto checkInfo = SphereCheckInfo {pos, radius};
checkInfo.mCollisionPartsFilter = filter;
if(mPartsKeeper)
mPartsKeeper->searchWithSphere(checkInfo, delegate);
}
void CollisionDirector::validateCollisionPartsPtrArray(sead::PtrArray<CollisionParts>* arr) {
mCollisionPartsKeeperPtrArray->setPtrArray(arr);
mActivePartsKeeper = mCollisionPartsKeeperPtrArray;
}
void CollisionDirector::invalidateCollisionPartsPtrArray() {
mActivePartsKeeper = mPartsKeeper;
}
sead::PtrArray<CollisionParts>* CollisionDirector::getCollisionPartsPtrArray() const {
if(mActivePartsKeeper == mPartsKeeper)
return nullptr;
return mCollisionPartsKeeperPtrArray->getPtrArray();
}
}