mirror of
https://github.com/MonsterDruide1/OdysseyDecomp
synced 2026-04-29 20:14:41 +00:00
162 lines
5.2 KiB
C++
162 lines
5.2 KiB
C++
#include "Library/Area/AreaObjDirector.h"
|
|
|
|
#include "Library/Area/AreaInitInfo.h"
|
|
#include "Library/Area/AreaObj.h"
|
|
#include "Library/Area/AreaObjFactory.h"
|
|
#include "Library/Area/AreaObjGroup.h"
|
|
#include "Library/Area/AreaObjMtxConnecter.h"
|
|
#include "Library/Placement/PlacementFunction.h"
|
|
#include "Library/Placement/PlacementInfo.h"
|
|
|
|
namespace al {
|
|
|
|
AreaObjDirector::AreaObjDirector() = default;
|
|
|
|
void AreaObjDirector::init(const AreaObjFactory* factory) {
|
|
mFactory = factory;
|
|
mMtxConnecterHolder = new AreaObjMtxConnecterHolder(0x100);
|
|
s32 nFactoryEntries = mFactory->getNumFactoryEntries();
|
|
mAreaGroups = new AreaObjGroup*[nFactoryEntries];
|
|
|
|
for (s32 i = 0; i < nFactoryEntries; i++)
|
|
mAreaGroups[i] = nullptr;
|
|
}
|
|
|
|
void AreaObjDirector::endInit() {}
|
|
|
|
void AreaObjDirector::update() {
|
|
if (mMtxConnecterHolder)
|
|
mMtxConnecterHolder->update();
|
|
}
|
|
|
|
void AreaObjDirector::placement(const AreaInitInfo& initInfo) {
|
|
createAreaObjGroup(initInfo);
|
|
createAreaObjGroupBuffer();
|
|
placementAreaObj(initInfo);
|
|
}
|
|
|
|
void AreaObjDirector::placement(const AreaInitInfo* initInfoArray, s32 initInfoCount) {
|
|
for (s32 i = 0; i < initInfoCount; i++)
|
|
createAreaObjGroup(initInfoArray[i]);
|
|
|
|
createAreaObjGroupBuffer();
|
|
|
|
for (s32 i = 0; i < initInfoCount; i++)
|
|
placementAreaObj(initInfoArray[i]);
|
|
}
|
|
|
|
void AreaObjDirector::createAreaObjGroup(const AreaInitInfo& initInfo) {
|
|
PlacementInfo placementInfo(initInfo);
|
|
|
|
s32 pInfoCount = getCountPlacementInfo(placementInfo);
|
|
for (s32 i = 0; i < pInfoCount; i++) {
|
|
PlacementInfo placementInfo2;
|
|
tryGetPlacementInfoByIndex(&placementInfo2, placementInfo, i);
|
|
const char* pInfoName = nullptr;
|
|
tryGetObjectName(&pInfoName, placementInfo2);
|
|
|
|
AreaCreatorFunction creatorFunc = nullptr;
|
|
s32 entryIndex = mFactory->getEntryIndex(&creatorFunc, pInfoName);
|
|
|
|
if (!creatorFunc)
|
|
continue;
|
|
if (!mAreaGroups[entryIndex]) {
|
|
s32 size = mFactory->tryFindAddBufferSize(pInfoName);
|
|
mAreaGroups[entryIndex] = new AreaObjGroup(pInfoName, size);
|
|
}
|
|
|
|
mAreaGroups[entryIndex]->incrementCount();
|
|
}
|
|
}
|
|
|
|
void AreaObjDirector::createAreaObjGroupBuffer() {
|
|
for (s32 i = 0; i < mFactory->getAreaGroupCount(); i++) {
|
|
const AreaGroupInfo& addBuffer = mFactory->getAreaGroupInfo()[i];
|
|
AreaCreatorFunction creatorFunc = nullptr;
|
|
s32 entryIndex = mFactory->getEntryIndex(&creatorFunc, addBuffer.name);
|
|
if (!mAreaGroups[entryIndex])
|
|
mAreaGroups[entryIndex] = new AreaObjGroup(addBuffer.name, addBuffer.size);
|
|
}
|
|
|
|
s32 areaGroupCount = 0;
|
|
s32 nEntries = mFactory->getNumFactoryEntries();
|
|
for (s32 i = 0; i < nEntries; i++) {
|
|
if (!mAreaGroups[i])
|
|
continue;
|
|
mAreaGroups[i]->createBuffer();
|
|
areaGroupCount++;
|
|
|
|
for (s32 areaGroupIndex = i; areaGroupIndex > 0; areaGroupIndex--) {
|
|
AreaObjGroup* prevAreaObjGroup = mAreaGroups[areaGroupIndex - 1];
|
|
if (prevAreaObjGroup) {
|
|
if (strcmp(mAreaGroups[areaGroupIndex]->getName(), prevAreaObjGroup->getName()) >
|
|
-1)
|
|
break;
|
|
}
|
|
mAreaGroups[areaGroupIndex - 1] = mAreaGroups[areaGroupIndex];
|
|
mAreaGroups[areaGroupIndex] = prevAreaObjGroup;
|
|
}
|
|
}
|
|
mAreaGroupCount = areaGroupCount;
|
|
}
|
|
|
|
void AreaObjDirector::placementAreaObj(const AreaInitInfo& initInfo) {
|
|
PlacementInfo pInfo(initInfo);
|
|
s32 pInfoCount = getCountPlacementInfo(pInfo);
|
|
for (s32 j = 0; j < pInfoCount; j++) {
|
|
PlacementInfo pInfo2;
|
|
tryGetPlacementInfoByIndex(&pInfo2, pInfo, j);
|
|
const char* pInfoName = nullptr;
|
|
tryGetObjectName(&pInfoName, pInfo2);
|
|
|
|
AreaCreatorFunction creatorFunc = nullptr;
|
|
mFactory->getEntryIndex(&creatorFunc, pInfoName);
|
|
if (!creatorFunc)
|
|
continue;
|
|
|
|
const char* displayName;
|
|
getDisplayName(&displayName, pInfo2);
|
|
AreaObj* areaObj = creatorFunc(displayName);
|
|
AreaInitInfo initInfo2(pInfo2, initInfo);
|
|
areaObj->init(initInfo2);
|
|
|
|
AreaObjGroup* areaGroup = getAreaObjGroup(pInfoName);
|
|
|
|
areaGroup->registerAreaObj(areaObj);
|
|
mMtxConnecterHolder->tryAddArea(areaObj, pInfo2);
|
|
}
|
|
}
|
|
|
|
AreaObjGroup* AreaObjDirector::getAreaObjGroup(const char* name) const {
|
|
s32 lower = 0;
|
|
s32 upper = mAreaGroupCount;
|
|
while (lower < upper) {
|
|
s32 i = (lower + upper) / 2;
|
|
s32 equalString = strcmp(name, mAreaGroups[i]->getName());
|
|
if (equalString == 0)
|
|
return mAreaGroups[i];
|
|
else if (equalString > 0)
|
|
lower = i + 1;
|
|
else
|
|
upper = i;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
bool AreaObjDirector::isExistAreaGroup(const char* name) const {
|
|
return getAreaObjGroup(name) != nullptr;
|
|
}
|
|
|
|
AreaObj* AreaObjDirector::getInVolumeAreaObj(const char* name, const sead::Vector3f& position) {
|
|
AreaObjGroup* areaGroup = getAreaObjGroup(name);
|
|
if (!areaGroup)
|
|
return nullptr;
|
|
return areaGroup->getInVolumeAreaObj(position);
|
|
}
|
|
|
|
AreaObjMtxConnecterHolder* AreaObjDirector::getMtxConnecterHolder() const {
|
|
return mMtxConnecterHolder;
|
|
}
|
|
|
|
} // namespace al
|