1#pragma once
2
3#include <container/seadPtrArray.h>
4#include <container/seadRingBuffer.h>
5#include <math/seadQuat.h>
6#include <math/seadVector.h>
7#include <prim/seadDelegate.h>
8
9namespace al {
10class ByamlIter;
11class CollisionParts;
12class LiveActor;
13
14struct KCPrismHeader {
15 u32 positionsOffset;
16 u32 normalsOffset;
17 u32 trianglesOffset;
18 u32 octreeOffset;
19 f32 thickness;
20 sead::Vector3f octreeOrigin;
21 sead::Vector3u widthMask;
22 sead::Vector3u widthShift;
23 f32 hitboxRadiusCap;
24};
25
26struct KCPrismData {
27 f32 length;
28 u16 posIndex;
29 u16 faceNormalIndex;
30 u16 edgeNormalIndex[3];
31 u16 collisionType;
32 u32 triIndex;
33};
34
35struct KCHitInfo {
36 const KCPrismHeader* header;
37 const KCPrismData* data;
38 f32 _16;
39 u8 _20; // collision location, enum
40};
41
42class KCollisionServer {
43public:
44 KCollisionServer();
45
46 void initKCollisionServer(void* data, const void* attributeData);
47 void setData(void* data);
48 const KCPrismHeader& getInnerKcl(s32 index) const;
49 u32 getNumInnerKcl() const;
50 const KCPrismHeader* getV1Header(s32 index) const;
51 bool calcFarthestVertexDistance();
52 s32 getTriangleNum(const KCPrismHeader* header) const;
53 const KCPrismData& getPrismData(u32 index, const KCPrismHeader* header) const;
54 bool isNearParallelNormal(const KCPrismData* data, const KCPrismHeader* header) const;
55 bool isNanPrism(const KCPrismData* data, const KCPrismHeader* header) const;
56 void calcPosLocal(sead::Vector3f* pos, const KCPrismData* data, s32 location,
57 const KCPrismHeader* header) const;
58 void getMinMax(sead::Vector3f* min, sead::Vector3f* max) const;
59 void getAreaSpaceSize(sead::Vector3f* size, const KCPrismHeader* header) const;
60 void getAreaSpaceSize(s32* sizeX, s32* sizeY, s32* sizeZ, const KCPrismHeader* header) const;
61 void getAreaSpaceSize(sead::Vector3u* size, const KCPrismHeader* header) const;
62 const KCPrismData* checkPoint(sead::Vector3f*, f32, f32*); // TODO unknown parameter usage
63 const u8* searchBlock(s32* widthShift, const sead::Vector3u& block,
64 const KCPrismHeader* header) const;
65 s32 checkSphere(const sead::Vector3f*, f32, f32, u32,
66 sead::FixedRingBuffer<KCHitInfo, 512>* hits); // TODO unknown parameter usage
67 bool outCheckAndCalcArea(sead::Vector3u* blockMin, sead::Vector3u* blockMax,
68 const sead::Vector3f& posMin, const sead::Vector3f& posMax,
69 const KCPrismHeader* header) const;
70 bool KCHitSphere(const KCPrismData* data, const KCPrismHeader* header, const sead::Vector3f*,
71 f32, f32, f32*, u8*); // TODO unknown parameter usage
72 const KCPrismData* checkArrow(const sead::Vector3f&, const sead::Vector3f&,
73 sead::FixedRingBuffer<KCHitInfo, 512>* hits, u32*,
74 u32) const; // TODO unknown parameter usage
75 void objectSpaceToAreaOffsetSpaceV3f(sead::Vector3f* areaOff, const sead::Vector3f& objSpace,
76 const KCPrismHeader* header) const;
77 bool isInsideMinMaxInAreaOffsetSpace(const sead::Vector3u& block,
78 const KCPrismHeader* header) const;
79 bool KCHitArrow(const KCPrismData* data, const KCPrismHeader* header, const sead::Vector3f&,
80 const sead::Vector3f&, f32*, u8*) const; // TODO unknown parameter usage
81 s32
82 checkSphereForPlayer(const sead::Vector3f*, f32, f32, u32,
83 sead::FixedRingBuffer<KCHitInfo, 512>*); // TODO unknown parameter usage
84 bool KCHitSphereForPlayer(const KCPrismData* data, const KCPrismHeader* header,
85 const sead::Vector3f*, f32, f32, f32*,
86 u8*); // TODO unknown parameter usage
87 s32 checkDisk(const sead::Vector3f*, f32, f32, const sead::Vector3f&, f32, u32,
88 sead::FixedRingBuffer<KCHitInfo, 512>*); // TODO unknown parameter usage
89 bool KCHitDisk(const KCPrismData* data, const KCPrismHeader* header, const sead::Vector3f*, f32,
90 f32, f32, const sead::Vector3f&, f32*, u8*); // TODO unknown parameter usage
91 void searchPrism(sead::Vector3f* pos, f32 searchRadius,
92 sead::IDelegate2<const KCPrismData*, const KCPrismHeader*>& callback);
93 void searchPrismMinMax(const sead::Vector3f& min, const sead::Vector3f& max,
94 sead::IDelegate2<const KCPrismData*, const KCPrismHeader*>& callback);
95 void searchPrismArrow(const sead::Vector3f& pos1, const sead::Vector3f& pos2,
96 sead::IDelegate2<const KCPrismData*, const KCPrismHeader*>& callback);
97 void searchPrismDisk(const sead::Vector3f&, const sead::Vector3f&, f32, f32,
98 sead::IDelegate2<const KCPrismData*, const KCPrismHeader*>&
99 callback); // TODO unknown parameter usage
100 bool isParallelNormal(const KCPrismData* data, const KCPrismHeader* header) const;
101 const sead::Vector3f& getFaceNormal(const KCPrismData* data, const KCPrismHeader* header) const;
102 const sead::Vector3f& getEdgeNormal1(const KCPrismData* data,
103 const KCPrismHeader* header) const;
104 const sead::Vector3f& getEdgeNormal2(const KCPrismData* data,
105 const KCPrismHeader* header) const;
106 const sead::Vector3f& getEdgeNormal3(const KCPrismData* data,
107 const KCPrismHeader* header) const;
108 bool KCHitDisc(const KCPrismData* data, const KCPrismHeader* header, const sead::Vector3f&,
109 const sead::Vector3f&, f32, f32, sead::Vector3f*,
110 f32*); // TODO unknown parameter usage
111 s32 toIndex(const KCPrismData* data, const KCPrismHeader* header) const;
112 const sead::Vector3f& getNormal(u32 index, const KCPrismHeader* header) const;
113
114 static void calXvec(const sead::Vector3f* a, const sead::Vector3f* b, sead::Vector3f* result);
115
116 const sead::Vector3f& getVertexData(u32 index, const KCPrismHeader* header) const;
117 u32 getVertexNum(const KCPrismHeader* header) const;
118 s32 getNormalNum(const KCPrismHeader* header) const;
119 s32 getAttributeElementNum() const;
120 bool getAttributes(ByamlIter* destIter, u32 triIndex, const KCPrismHeader* header) const;
121 bool getAttributes(ByamlIter* destIter, const KCPrismData* data) const;
122 void objectSpaceToAreaOffsetSpace(sead::Vector3u* areaOffSpace, const sead::Vector3f& objSpace,
123 const KCPrismHeader* header) const;
124 void areaOffsetSpaceToObjectSpace(sead::Vector3f* objSpace, const sead::Vector3u& areaOffSpace,
125 const KCPrismHeader* header) const;
126 bool doBoxCheck(const sead::Vector3f*, const sead::Vector3f*, sead::Vector3u*, sead::Vector3u*,
127 const KCPrismHeader* header); // TODO unknown parameter usage
128 s32 calcAreaBlockOffset(const sead::Vector3u& block, const KCPrismHeader* header) const;
129
130 static s32 calcChildBlockOffset(const sead::Vector3u& block, s32 shift);
131 static u32 getBlockData(const u32* data, u32 offset);
132
133private:
134 sead::PtrArray<KCPrismHeader> mModelsData;
135 void* mData;
136 ByamlIter* mAttributeIter;
137 void* mModelListData;
138 void* mOctreeData;
139 s32 mAreaWidthShift[3];
140 s32 mAreaWidthMask[3];
141 f32 mFarthestVertexDistance;
142};
143
144class SphereInterpolator {
145public:
146 SphereInterpolator() {}
147
148 void startInterp(const sead::Vector3f& posStart, const sead::Vector3f& posEnd, f32 sizeStart,
149 f32 sizeEnd, f32 steps);
150 void nextStep();
151 void calcInterpPos(sead::Vector3f* pos) const;
152 void calcInterp(sead::Vector3f* pos, f32* size, sead::Vector3f* remainMoveVec) const;
153 void calcRemainMoveVector(sead::Vector3f* remainMoveVec) const;
154 void getMoveVector(sead::Vector3f* moveVec);
155 void calcStepMoveVector(sead::Vector3f* moveVec) const;
156
157private:
158 sead::Vector3f mPos;
159 sead::Vector3f mMove;
160 f32 mSizeStart;
161 f32 mSizeEnd;
162 f32 mStepSize;
163 f32 mCurrentStep;
164 f32 mPrevStep;
165};
166
167class SpherePoseInterpolator {
168public:
169 SpherePoseInterpolator() {}
170
171 void startInterp(const sead::Vector3f& posStart, const sead::Vector3f& posEnd, f32 sizeStart,
172 f32 sizeEnd, const sead::Quatf& quatStart, const sead::Quatf& quatEnd,
173 f32 steps);
174 void nextStep();
175 void calcInterpPos(sead::Vector3f* pos) const;
176 void calcInterp(sead::Vector3f* pos, f32* size, sead::Quatf* quat,
177 sead::Vector3f* remainMoveVec) const;
178 void calcRemainMoveVector(sead::Vector3f* remainMoveVec) const;
179 f32 calcRadiusBaseScale(f32 unk) const;
180 void getMoveVector(sead::Vector3f* moveVec);
181
182private:
183 sead::Vector3f mPos;
184 sead::Vector3f mMove;
185 f32 mSizeStart;
186 f32 mSizeEnd;
187 sead::Quatf mQuatStart;
188 sead::Quatf mQuatEnd;
189 f32 mStepSize;
190 f32 mCurrentStep;
191 f32 mPrevStep;
192};
193
194class CollisionPartsFilterBase {
195public:
196 virtual bool isInvalidParts(CollisionParts* collisionParts) = 0;
197};
198
199class CollisionPartsFilterActor : public CollisionPartsFilterBase {
200public:
201 CollisionPartsFilterActor(LiveActor* actor) : mActor(actor) {}
202
203 bool isInvalidParts(CollisionParts* collisionParts) override;
204
205private:
206 LiveActor* mActor;
207 bool mIsCompareEqual = true;
208};
209
210class CollisionPartsFilterSpecialPurpose : public CollisionPartsFilterBase {
211public:
212 CollisionPartsFilterSpecialPurpose(const char* specialPurpose)
213 : mSpecialPurpose(specialPurpose) {}
214
215 bool isInvalidParts(CollisionParts* collisionParts) override;
216
217private:
218 const char* mSpecialPurpose;
219};
220
221} // namespace al
222