Files
Petari/source/Game/Gravity/PlanetGravityManager.cpp
2024-06-27 07:49:16 -04:00

114 lines
2.8 KiB
C++

#include "Game/Gravity.hpp"
PlanetGravityManager::PlanetGravityManager(const char *pName) : NameObj(pName) {
mNumGravities = 0;
}
void PlanetGravityManager::init(const JMapInfoIter &rIter) {
}
bool PlanetGravityManager::calcTotalGravityVector(TVec3f *pGravity, GravityInfo *pInfo, const TVec3f &rPosition, u32 gravityType, u32 host) const {
TVec3f totalGravity;
totalGravity.z = 0.0f;
totalGravity.y = 0.0f;
totalGravity.x = 0.0f;
PlanetGravity** pGravities = (PlanetGravity**)&mGravities;
bool hasCalculated = false;
if (pInfo) {
pInfo->init();
}
f32 largestScalar = -1.0f;
s32 largestPriority = -1;
while (pGravities != &mGravities[mNumGravities]) {
// Is gravity valid/active?
bool validGravity = false;
if ((*pGravities)->mActivated && (*pGravities)->mValidFollower && (*pGravities)->mAppeared) {
validGravity = true;
}
// Gravity is valid, matches specified gravity type(s) and does not have same host
if (validGravity && ((gravityType & (*pGravities)->mGravityType) != 0) && (host != (u32)(*pGravities)->mHost)) {
// Is priority lower -> end of list reached as it's sorted in descending order
s32 priority = (*pGravities)->mPriority;
if (priority < largestPriority) {
break;
}
// Calculate gravity
TVec3f gravityVec;
if ((*pGravities)->calcGravity(&gravityVec, rPosition)) {
bool storeInfo = false;
f32 scalar = PSVECMag(gravityVec.toCVec());
// If same priority, add gravity vector to total result
if (priority == largestPriority) {
totalGravity.addInline(gravityVec);
hasCalculated = true;
if (largestScalar < scalar) {
storeInfo = true;
}
}
// If larger priority, total gravity gets overriden
else if (priority > largestPriority) {
largestPriority = priority;
hasCalculated = true;
storeInfo = true;
totalGravity = gravityVec;
}
// Try to store gravity info if necessary
if (pInfo && storeInfo) {
largestScalar = scalar;
pInfo->mGravityVector = gravityVec;
pInfo->mLargestPriority = largestPriority;
pInfo->mGravityInstance = *pGravities;
}
}
}
pGravities++;
}
// Store normalized vector as result if necessary
if (pGravity) {
MR::normalizeOrZero(&totalGravity);
*pGravity = totalGravity;
}
return hasCalculated;
}
void PlanetGravityManager::registerGravity(PlanetGravity *pGravity) {
pGravity->mIsRegistered = true;
int index = mNumGravities++;
mGravities[index] = pGravity;
sortGravities();
}
inline void PlanetGravityManager::sortGravities() {
for (s32 i = mNumGravities - 1; i >= 1; i--) {
if (mGravities[i]->mPriority > mGravities[i - 1]->mPriority) {
bubbleDown(i);
}
else {
break;
}
}
}
inline void PlanetGravityManager::bubbleDown(int i) {
PlanetGravity *temp = mGravities[i - 1];
mGravities[i - 1] = mGravities[i];
mGravities[i] = temp;
}