SMG-Decomp
A decompilation of Super Mario Galaxy 1
Loading...
Searching...
No Matches
KCollision.cpp
1#include "Game/Map/KCollision.hpp"
2#include "Game/Util/JMapInfo.hpp"
3#include "Game/Util/MathUtil.hpp"
4
5Fxyz &Fxyz::operator=(const Fxyz &rOther) {
6 x = rOther.x;
7 y = rOther.y;
8 z = rOther.z;
9
10 return *this;
11}
12
13void KCollisionServer::V3u::setUsingCast(const TVec3f &rPos) {
14 x = static_cast<s32>(rPos.x);
15 y = static_cast<s32>(rPos.y);
16 z = static_cast<s32>(rPos.z);
17}
18
19KCollisionServer::KCollisionServer() {
20 mFile = nullptr;
21 mapInfo = new JMapInfo();
22 mMaxVertexDistance = 1.0f;
23}
24
25void KCollisionServer::init(void *pData, const void *pMapData) {
26 setData(pData);
27
28 if (pMapData != nullptr) {
29 mapInfo->attach(pMapData);
30 }
31}
32
33void KCollisionServer::setData(void *pData) {
34 mFile = reinterpret_cast<KCLFile *>(pData);
35
36 if (isBinaryInitialized(pData)) {
37 mFile->mPos = reinterpret_cast<TVec3f *>(reinterpret_cast<u8 *>(mFile) + mFile->mPosOffset);
38 mFile->mNorms = reinterpret_cast<TVec3f *>(reinterpret_cast<u8 *>(mFile) + mFile->mNormOffset);
39 mFile->mPrisms = reinterpret_cast<KC_PrismData *>(reinterpret_cast<u8 *>(mFile) + mFile->mPrismOffset);
40 mFile->mOctree = reinterpret_cast<void *>(reinterpret_cast<u8 *>(mFile) + mFile->mOctreeOffset);
41 }
42}
43
44/*void KCollisionServer::calcFarthestVertexDistance() {
45 s32 triCount = getTriangleNum();
46 f32 maxDistance = 0.0f;
47
48 for (s32 i = 0; i < triCount; i++) {
49
50 }
51}*/
52
53bool KCollisionServer::isBinaryInitialized(const void *pData) {
54 return reinterpret_cast<const s32 *>(pData)[0] < 0;
55}
56
57bool KCollisionServer::isNearParallelNormal(const KC_PrismData *pPrism) const {
58 TVec3f edge0 = mFile->mNorms[pPrism->mEdgeIndices[0]];
59 TVec3f edge1 = mFile->mNorms[pPrism->mEdgeIndices[1]];
60 TVec3f edge2 = mFile->mNorms[pPrism->mEdgeIndices[2]];
61
62 bool isNear = false;
63
64 if (MR::isSameDirection(edge0, edge1, 0.01f) || MR::isSameDirection(edge0, edge2, 0.01f) || MR::isSameDirection(edge1, edge2, 0.01f)) {
65 isNear = true;
66 }
67
68 return isNear;
69}
70
71s32 KCollisionServer::toIndex(const KC_PrismData *pPrism) const {
72 return pPrism - (mFile->mPrisms + 1);
73}
74
75TVec3f *KCollisionServer::getFaceNormal(const KC_PrismData *pPrism) const {
76 return &mFile->mNorms[pPrism->mNormalIndex];
77}
78
79TVec3f *KCollisionServer::getEdgeNormal1(const KC_PrismData *pPrism) const {
80 return &mFile->mNorms[pPrism->mEdgeIndices[0]];
81}
82
83TVec3f *KCollisionServer::getEdgeNormal2(const KC_PrismData *pPrism) const {
84 return &mFile->mNorms[pPrism->mEdgeIndices[1]];
85}
86
87TVec3f *KCollisionServer::getEdgeNormal3(const KC_PrismData *pPrism) const {
88 return &mFile->mNorms[pPrism->mEdgeIndices[2]];
89}
90
91TVec3f *KCollisionServer::getNormal(unsigned long index) const {
92 return &mFile->mNorms[index];
93}
94
95void KCollisionServer::calXvec(const Fxyz *pVecA, const Fxyz *pVecB, Fxyz *pDst) const {
96 pDst->x = pVecA->z * pVecB->y - pVecA->y * pVecB->z;
97 pDst->y = pVecA->x * pVecB->z - pVecA->z * pVecB->x;
98 pDst->z = pVecA->y * pVecB->x - pVecA->x * pVecB->y;
99}
100
101TVec3f KCollisionServer::getPos(const KC_PrismData *pPrism, int vertexIndex) const {
102 switch (vertexIndex) {
103 case 0: {
104 TVec3f *pos = &mFile->mPos[pPrism->mPositionIndex];
105
106 return TVec3f(pos->x, pos->y, pos->z);
107 }
108 case 1: {
109 Fxyz *pos = reinterpret_cast<Fxyz *>(&mFile->mPos[pPrism->mPositionIndex]);
110 Fxyz *edge2 = reinterpret_cast<Fxyz *>(&mFile->mNorms[pPrism->mEdgeIndices[2]]);
111
112 Fxyz finalPos;
113
114 calXvec(
115 reinterpret_cast<Fxyz *>(&mFile->mNorms[pPrism->mEdgeIndices[1]]),
116 reinterpret_cast<Fxyz *>(&mFile->mNorms[pPrism->mNormalIndex]),
117 &finalPos
118 );
119
120 f32 sideLength = pPrism->mHeight / (finalPos.x * edge2->x + finalPos.y * edge2->y + finalPos.z * edge2->z);
121
122 finalPos.x = pos->x + sideLength * finalPos.x;
123 finalPos.y = pos->y + sideLength * finalPos.y;
124 finalPos.z = pos->z + sideLength * finalPos.z;
125
126 return TVec3f(finalPos.x, finalPos.y, finalPos.z);
127 }
128 case 2: {
129 Fxyz *pos = reinterpret_cast<Fxyz *>(&mFile->mPos[pPrism->mPositionIndex]);
130 Fxyz *edge2 = reinterpret_cast<Fxyz *>(&mFile->mNorms[pPrism->mEdgeIndices[2]]);
131
132 Fxyz finalPos;
133
134 calXvec(
135 reinterpret_cast<Fxyz *>(&mFile->mNorms[pPrism->mNormalIndex]),
136 reinterpret_cast<Fxyz *>(&mFile->mNorms[pPrism->mEdgeIndices[0]]),
137 &finalPos
138 );
139
140 f32 sideLength = pPrism->mHeight / (finalPos.x * edge2->x + finalPos.y * edge2->y + finalPos.z * edge2->z);
141
142 finalPos.x = pos->x + sideLength * finalPos.x;
143 finalPos.y = pos->y + sideLength * finalPos.y;
144 finalPos.z = pos->z + sideLength * finalPos.z;
145
146 return TVec3f(finalPos.x, finalPos.y, finalPos.z);
147 }
148 default:
149 return TVec3f(0.0f, 0.0f, 0.0f);
150 }
151}
152
153KC_PrismData *KCollisionServer::getPrismData(unsigned long index) const {
154 return &mFile->mPrisms[1 + index];
155}
156
157s32 KCollisionServer::getTriangleNum() const {
158 return (reinterpret_cast<u8 *>(mFile->mOctree) - reinterpret_cast<u8 *>(mFile->mPrisms + 1)) / sizeof(KC_PrismData);
159}
160
161JMapInfoIter KCollisionServer::getAttributes(unsigned long index) const {
162 KC_PrismData *prism = &mFile->mPrisms[1 + index];
163
164 JMapInfoIter iter;
165 iter.mInfo = mapInfo;
166 iter._4 = prism->mAttribute;
167
168 return iter;
169}
170
171#ifdef NON_MATCHING
172// Register mismatch
173s32 *KCollisionServer::searchBlock(long *a1, const unsigned long &rX, const unsigned long &rY, const unsigned long &rZ) const {
174 KCLFile *file = mFile;
175 s32 blockWidthShift = file->mBlockWidthShift;
176 u8 *octree = reinterpret_cast<u8 *>(file->mOctree);
177 *a1 = blockWidthShift;
178
179 s32 offset = ((rX >> blockWidthShift) | ((rZ >> blockWidthShift) << file->mBlockXYShift) | ((rY >> blockWidthShift) << file->mBlockXShift)) * 4;
180
181 if (file->mBlockXYShift == -1 && file->mBlockXShift == -1) {
182 offset = 0;
183 }
184
185 while ((offset = *reinterpret_cast<s32 *>(octree + offset)) >= 0) {
186 octree += offset;
187 s32 uVar7 = --(*a1);
188
189 offset = ((((rZ >> uVar7) & 1) << 2) | (((rY >> uVar7) & 1) << 1) | ((rX >> uVar7) & 1)) * 4;
190 }
191
192 return reinterpret_cast<s32 *>(octree + (offset & 0x7FFFFFFF));
193}
194#endif