1#include "Game/Map/KCollision.hpp"
2#include "Game/Util/JMapInfo.hpp"
3#include "Game/Util/MathUtil.hpp"
5Fxyz &Fxyz::operator=(
const Fxyz &rOther) {
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);
19KCollisionServer::KCollisionServer() {
22 mMaxVertexDistance = 1.0f;
25void KCollisionServer::init(
void *pData,
const void *pMapData) {
28 if (pMapData !=
nullptr) {
29 mapInfo->attach(pMapData);
33void KCollisionServer::setData(
void *pData) {
34 mFile =
reinterpret_cast<KCLFile *
>(pData);
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);
53bool KCollisionServer::isBinaryInitialized(
const void *pData) {
54 return reinterpret_cast<const s32 *
>(pData)[0] < 0;
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]];
64 if (MR::isSameDirection(edge0, edge1, 0.01f) || MR::isSameDirection(edge0, edge2, 0.01f) || MR::isSameDirection(edge1, edge2, 0.01f)) {
71s32 KCollisionServer::toIndex(
const KC_PrismData *pPrism)
const {
72 return pPrism - (mFile->mPrisms + 1);
75TVec3f *KCollisionServer::getFaceNormal(
const KC_PrismData *pPrism)
const {
76 return &mFile->mNorms[pPrism->mNormalIndex];
79TVec3f *KCollisionServer::getEdgeNormal1(
const KC_PrismData *pPrism)
const {
80 return &mFile->mNorms[pPrism->mEdgeIndices[0]];
83TVec3f *KCollisionServer::getEdgeNormal2(
const KC_PrismData *pPrism)
const {
84 return &mFile->mNorms[pPrism->mEdgeIndices[1]];
87TVec3f *KCollisionServer::getEdgeNormal3(
const KC_PrismData *pPrism)
const {
88 return &mFile->mNorms[pPrism->mEdgeIndices[2]];
91TVec3f *KCollisionServer::getNormal(
unsigned long index)
const {
92 return &mFile->mNorms[index];
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;
101TVec3f KCollisionServer::getPos(
const KC_PrismData *pPrism,
int vertexIndex)
const {
102 switch (vertexIndex) {
104 TVec3f *pos = &mFile->mPos[pPrism->mPositionIndex];
106 return TVec3f(pos->x, pos->y, pos->z);
109 Fxyz *pos =
reinterpret_cast<Fxyz *
>(&mFile->mPos[pPrism->mPositionIndex]);
110 Fxyz *edge2 =
reinterpret_cast<Fxyz *
>(&mFile->mNorms[pPrism->mEdgeIndices[2]]);
115 reinterpret_cast<Fxyz *
>(&mFile->mNorms[pPrism->mEdgeIndices[1]]),
116 reinterpret_cast<Fxyz *
>(&mFile->mNorms[pPrism->mNormalIndex]),
120 f32 sideLength = pPrism->mHeight / (finalPos.x * edge2->x + finalPos.y * edge2->y + finalPos.z * edge2->z);
122 finalPos.x = pos->x + sideLength * finalPos.x;
123 finalPos.y = pos->y + sideLength * finalPos.y;
124 finalPos.z = pos->z + sideLength * finalPos.z;
126 return TVec3f(finalPos.x, finalPos.y, finalPos.z);
129 Fxyz *pos =
reinterpret_cast<Fxyz *
>(&mFile->mPos[pPrism->mPositionIndex]);
130 Fxyz *edge2 =
reinterpret_cast<Fxyz *
>(&mFile->mNorms[pPrism->mEdgeIndices[2]]);
135 reinterpret_cast<Fxyz *
>(&mFile->mNorms[pPrism->mNormalIndex]),
136 reinterpret_cast<Fxyz *
>(&mFile->mNorms[pPrism->mEdgeIndices[0]]),
140 f32 sideLength = pPrism->mHeight / (finalPos.x * edge2->x + finalPos.y * edge2->y + finalPos.z * edge2->z);
142 finalPos.x = pos->x + sideLength * finalPos.x;
143 finalPos.y = pos->y + sideLength * finalPos.y;
144 finalPos.z = pos->z + sideLength * finalPos.z;
146 return TVec3f(finalPos.x, finalPos.y, finalPos.z);
149 return TVec3f(0.0f, 0.0f, 0.0f);
153KC_PrismData *KCollisionServer::getPrismData(
unsigned long index)
const {
154 return &mFile->mPrisms[1 + index];
157s32 KCollisionServer::getTriangleNum()
const {
158 return (
reinterpret_cast<u8 *
>(mFile->mOctree) -
reinterpret_cast<u8 *
>(mFile->mPrisms + 1)) /
sizeof(
KC_PrismData);
161JMapInfoIter KCollisionServer::getAttributes(
unsigned long index)
const {
165 iter.mInfo = mapInfo;
166 iter._4 = prism->mAttribute;
173s32 *KCollisionServer::searchBlock(
long *a1,
const unsigned long &rX,
const unsigned long &rY,
const unsigned long &rZ)
const {
175 s32 blockWidthShift = file->mBlockWidthShift;
176 u8 *octree =
reinterpret_cast<u8 *
>(file->mOctree);
177 *a1 = blockWidthShift;
179 s32 offset = ((rX >> blockWidthShift) | ((rZ >> blockWidthShift) << file->mBlockXYShift) | ((rY >> blockWidthShift) << file->mBlockXShift)) * 4;
181 if (file->mBlockXYShift == -1 && file->mBlockXShift == -1) {
185 while ((offset = *
reinterpret_cast<s32 *
>(octree + offset)) >= 0) {
189 offset = ((((rZ >> uVar7) & 1) << 2) | (((rY >> uVar7) & 1) << 1) | ((rX >> uVar7) & 1)) * 4;
192 return reinterpret_cast<s32 *
>(octree + (offset & 0x7FFFFFFF));