Merge remote-tracking branch 'origin/master' into chozoghosts

This commit is contained in:
Luke Street 2020-03-09 10:12:40 -04:00
commit 830db8772d
40 changed files with 430 additions and 366 deletions

View File

@ -1,14 +1,26 @@
#include "Runtime/CObjectList.hpp" #include "Runtime/CObjectList.hpp"
#include <logvisor/logvisor.hpp>
namespace urde { namespace urde {
namespace {
logvisor::Module Log("urde::CObjectList");
}
CObjectList::CObjectList(EGameObjectList listEnum) : x2004_listEnum(listEnum) {} CObjectList::CObjectList(EGameObjectList listEnum) : x2004_listEnum(listEnum) {}
void CObjectList::AddObject(CEntity& entity) { void CObjectList::AddObject(CEntity& entity) {
if (IsQualified(entity)) { if (IsQualified(entity)) {
if (x2008_firstId != -1) #ifndef NDEBUG
if (x0_list[entity.GetUniqueId().Value()].entity != nullptr &&
x0_list[entity.GetUniqueId().Value()].entity != &entity)
Log.report(logvisor::Level::Fatal, fmt("INVALID USAGE DETECTED: Attempting to assign entity '{} ({})' to existing node '{}'!!!"),
entity.GetName(), entity.GetEditorId(), entity.GetUniqueId().Value());
#endif
s16 prevFirst = -1;
if (x2008_firstId != -1) {
x0_list[x2008_firstId].prev = entity.GetUniqueId().Value(); x0_list[x2008_firstId].prev = entity.GetUniqueId().Value();
s16 prevFirst = x2008_firstId; prevFirst = x2008_firstId;
}
x2008_firstId = entity.GetUniqueId().Value(); x2008_firstId = entity.GetUniqueId().Value();
SObjectListEntry& newEnt = x0_list[x2008_firstId]; SObjectListEntry& newEnt = x0_list[x2008_firstId];
newEnt.entity = &entity; newEnt.entity = &entity;
@ -91,6 +103,6 @@ CEntity* CObjectList::GetValidObjectById(TUniqueId uid) {
return ent.entity; return ent.entity;
} }
bool CObjectList::IsQualified(const CEntity&) { return true; } bool CObjectList::IsQualified(const CEntity&) const { return true; }
} // namespace urde } // namespace urde

View File

@ -80,7 +80,7 @@ public:
CEntity* GetValidObjectById(TUniqueId uid); CEntity* GetValidObjectById(TUniqueId uid);
s16 GetFirstObjectIndex() const { return x2008_firstId; } s16 GetFirstObjectIndex() const { return x2008_firstId; }
s16 GetNextObjectIndex(s16 prev) const { return x0_list[prev].next; } s16 GetNextObjectIndex(s16 prev) const { return x0_list[prev].next; }
virtual bool IsQualified(const CEntity&); virtual bool IsQualified(const CEntity&) const;
u16 size() const { return x200a_count; } u16 size() const { return x200a_count; }
}; };

View File

@ -7,7 +7,8 @@ namespace urde {
static logvisor::Module Log("CResFactory"); static logvisor::Module Log("CResFactory");
void CResFactory::AddToLoadList(SLoadingData&& data) { void CResFactory::AddToLoadList(SLoadingData&& data) {
m_loadMap[data.x0_tag] = m_loadList.insert(m_loadList.end(), std::move(data)); const SObjectTag tag = data.x0_tag;
m_loadMap.insert_or_assign(tag, m_loadList.insert(m_loadList.end(), std::move(data)));
} }
CFactoryFnReturn CResFactory::BuildSync(const SObjectTag& tag, const CVParamTransfer& xfer, CObjectReference* selfRef) { CFactoryFnReturn CResFactory::BuildSync(const SObjectTag& tag, const CVParamTransfer& xfer, CObjectReference* selfRef) {

View File

@ -97,7 +97,7 @@ private:
std::unique_ptr<CAiWaypointList> x83c_aiWaypointObjs; std::unique_ptr<CAiWaypointList> x83c_aiWaypointObjs;
std::unique_ptr<CPlatformAndDoorList> x844_platformAndDoorObjs; std::unique_ptr<CPlatformAndDoorList> x844_platformAndDoorObjs;
*/ */
std::unique_ptr<CObjectList> x808_objLists[8] = {std::make_unique<CObjectList>(EGameObjectList::All), std::array<std::unique_ptr<CObjectList>, 8> x808_objLists = {std::make_unique<CObjectList>(EGameObjectList::All),
std::make_unique<CActorList>(), std::make_unique<CActorList>(),
std::make_unique<CPhysicsActorList>(), std::make_unique<CPhysicsActorList>(),
std::make_unique<CGameCameraList>(), std::make_unique<CGameCameraList>(),

View File

@ -74,7 +74,9 @@ class CToken {
public: public:
/* Added to test for non-null state */ /* Added to test for non-null state */
operator bool() const { return x0_objRef != nullptr; } explicit operator bool() const { return HasReference(); }
bool HasReference() const { return x0_objRef != nullptr; }
void Unlock(); void Unlock();
void Lock(); void Lock();
bool IsLocked() const { return x4_lockHeld; } bool IsLocked() const { return x4_lockHeld; }

View File

@ -1004,8 +1004,6 @@ zeus::CVector3f CBallCamera::AvoidGeometry(const zeus::CTransform& xf,
UpdateColliders(xf, x274_mediumColliders, x2d4_mediumColliderIt, 3, 4.f, nearList, dt, mgr); UpdateColliders(xf, x274_mediumColliders, x2d4_mediumColliderIt, 3, 4.f, nearList, dt, mgr);
break; break;
case 2: case 2:
UpdateColliders(xf, x284_largeColliders, x2d8_largeColliderIt, 4, 4.f, nearList, dt, mgr);
break;
case 3: case 3:
UpdateColliders(xf, x284_largeColliders, x2d8_largeColliderIt, 4, 4.f, nearList, dt, mgr); UpdateColliders(xf, x284_largeColliders, x2d8_largeColliderIt, 4, 4.f, nearList, dt, mgr);
break; break;

View File

@ -10,7 +10,7 @@ namespace urde {
CAnimSourceInfo::CAnimSourceInfo(const TSubAnimTypeToken<CAnimSource>& token) : x4_token(token) {} CAnimSourceInfo::CAnimSourceInfo(const TSubAnimTypeToken<CAnimSource>& token) : x4_token(token) {}
bool CAnimSourceInfo::HasPOIData() const { return x4_token->x58_evntData; } bool CAnimSourceInfo::HasPOIData() const { return x4_token->x58_evntData.HasReference(); }
const std::vector<CBoolPOINode>& CAnimSourceInfo::GetBoolPOIStream() const { return x4_token->GetBoolPOIStream(); } const std::vector<CBoolPOINode>& CAnimSourceInfo::GetBoolPOIStream() const { return x4_token->GetBoolPOIStream(); }

View File

@ -38,7 +38,7 @@ void CBoneTracking::PreRender(const CStateManager& mgr, CAnimData& animData, con
TCastToConstPtr<CActor> targetAct = mgr.GetObjectById(x34_target); TCastToConstPtr<CActor> targetAct = mgr.GetObjectById(x34_target);
if (x36_24_active && tracking && (targetAct || x24_targetPosition)) { if (x36_24_active && tracking && (targetAct || x24_targetPosition)) {
x36_25_hasTrackedRotation = true; x36_25_hasTrackedRotation = true;
auto layoutInfo = pb.CharLayoutInfo(); const auto& layoutInfo = pb.CharLayoutInfo();
CSegId bone; CSegId bone;
if (x36_26_noParent) if (x36_26_noParent)
bone = x14_segId; bone = x14_segId;

View File

@ -75,7 +75,7 @@ public:
CCharAnimTime GetAnimationDuration() const { return MainHeader().duration; } CCharAnimTime GetAnimationDuration() const { return MainHeader().duration; }
float GetAverageVelocity() const { return x10_averageVelocity; } float GetAverageVelocity() const { return x10_averageVelocity; }
const zeus::CVector3f& GetRootOffset() const { return x14_rootOffset; } const zeus::CVector3f& GetRootOffset() const { return x14_rootOffset; }
bool HasPOIData() const { return x8_evntToken; } bool HasPOIData() const { return x8_evntToken.HasReference(); }
const std::vector<CBoolPOINode>& GetBoolPOIStream() const { return x8_evntToken->GetBoolPOIStream(); } const std::vector<CBoolPOINode>& GetBoolPOIStream() const { return x8_evntToken->GetBoolPOIStream(); }
const std::vector<CInt32POINode>& GetInt32POIStream() const { return x8_evntToken->GetInt32POIStream(); } const std::vector<CInt32POINode>& GetInt32POIStream() const { return x8_evntToken->GetInt32POIStream(); }
const std::vector<CParticlePOINode>& GetParticlePOIStream() const { return x8_evntToken->GetParticlePOIStream(); } const std::vector<CParticlePOINode>& GetParticlePOIStream() const { return x8_evntToken->GetParticlePOIStream(); }

View File

@ -38,7 +38,7 @@ class CHierarchyPoseBuilder {
public: public:
CHierarchyPoseBuilder(const CLayoutDescription& layout); CHierarchyPoseBuilder(const CLayoutDescription& layout);
const TLockedToken<CCharLayoutInfo> CharLayoutInfo() const { return x0_layoutDesc.ScaledLayout(); } const TLockedToken<CCharLayoutInfo>& CharLayoutInfo() const { return x0_layoutDesc.ScaledLayout(); }
bool HasRoot() const { return xcf0_hasRoot; } bool HasRoot() const { return xcf0_hasRoot; }
void BuildTransform(const CSegId& boneId, zeus::CTransform& xfOut) const; void BuildTransform(const CSegId& boneId, zeus::CTransform& xfOut) const;
void BuildNoScale(CPoseAsTransforms& pose); void BuildNoScale(CPoseAsTransforms& pose);

View File

@ -15,7 +15,7 @@ void CIkChain::Deactivate() { x44_24_activated = false; }
void CIkChain::Activate(const CAnimData& animData, const CSegId& segId, const zeus::CTransform& xf) { void CIkChain::Activate(const CAnimData& animData, const CSegId& segId, const zeus::CTransform& xf) {
x0_bone = segId; x0_bone = segId;
auto info = animData.GetPoseBuilder().CharLayoutInfo(); const auto& info = animData.GetPoseBuilder().CharLayoutInfo();
x1_p1 = info->GetRootNode()->GetBoneMap()[x0_bone].x0_parentId; x1_p1 = info->GetRootNode()->GetBoneMap()[x0_bone].x0_parentId;
if (x1_p1 != 2) { if (x1_p1 != 2) {
x2_p2 = info->GetRootNode()->GetBoneMap()[x1_p1].x0_parentId; x2_p2 = info->GetRootNode()->GetBoneMap()[x1_p1].x0_parentId;

View File

@ -27,12 +27,12 @@ class CStaticRes {
zeus::CVector3f x4_scale; zeus::CVector3f x4_scale;
public: public:
constexpr CStaticRes()=default; constexpr CStaticRes() = default;
CStaticRes(CAssetId id, const zeus::CVector3f& scale) : x0_cmdlId(id), x4_scale(scale) {} CStaticRes(CAssetId id, const zeus::CVector3f& scale) : x0_cmdlId(id), x4_scale(scale) {}
CAssetId GetId() const { return x0_cmdlId; } CAssetId GetId() const { return x0_cmdlId; }
const zeus::CVector3f& GetScale() const { return x4_scale; } const zeus::CVector3f& GetScale() const { return x4_scale; }
operator bool() const { return x0_cmdlId != 0; } explicit operator bool() const { return x0_cmdlId.IsValid(); }
}; };
class CAnimRes { class CAnimRes {
@ -148,16 +148,16 @@ public:
const zeus::CVector3f& GetScale() const { return x0_scale; } const zeus::CVector3f& GetScale() const { return x0_scale; }
void SetScale(const zeus::CVector3f& scale) { x0_scale = scale; } void SetScale(const zeus::CVector3f& scale) { x0_scale = scale; }
bool HasAnimData() const { return x10_animData != nullptr; } bool HasAnimData() const { return x10_animData != nullptr; }
bool HasNormalModel() const { return x1c_normalModel; } bool HasNormalModel() const { return x1c_normalModel.HasReference(); }
bool HasModel(EWhichModel which) const { bool HasModel(EWhichModel which) const {
if (x10_animData) { if (x10_animData) {
switch (which) { switch (which) {
case EWhichModel::Normal: case EWhichModel::Normal:
return true; return true;
case EWhichModel::XRay: case EWhichModel::XRay:
return x10_animData->GetXRayModel().operator bool(); return x10_animData->GetXRayModel() != nullptr;
case EWhichModel::Thermal: case EWhichModel::Thermal:
return x10_animData->GetInfraModel().operator bool(); return x10_animData->GetInfraModel() != nullptr;
default: default:
return false; return false;
} }
@ -165,11 +165,11 @@ public:
switch (which) { switch (which) {
case EWhichModel::Normal: case EWhichModel::Normal:
return x1c_normalModel; return x1c_normalModel.HasReference();
case EWhichModel::XRay: case EWhichModel::XRay:
return x2c_xrayModel; return x2c_xrayModel.HasReference();
case EWhichModel::Thermal: case EWhichModel::Thermal:
return x3c_infraModel; return x3c_infraModel.HasReference();
default: default:
return false; return false;
} }

View File

@ -306,7 +306,7 @@ void CParticleDatabase::SetParticleEffectState(std::string_view name, bool activ
void CParticleDatabase::SetCEXTValue(std::string_view name, int idx, float value) { void CParticleDatabase::SetCEXTValue(std::string_view name, int idx, float value) {
if (CParticleGenInfo* info = GetParticleEffect(name)) { if (CParticleGenInfo* info = GetParticleEffect(name)) {
static_cast<CElementGen*>(static_cast<CParticleGenInfoGeneric*>(info)->GetParticleSystem().get()) std::static_pointer_cast<CElementGen>(static_cast<CParticleGenInfoGeneric*>(info)->GetParticleSystem())
->SetExternalVar(idx, value); ->SetExternalVar(idx, value);
} }
} }

View File

@ -106,6 +106,6 @@ public:
TUniqueId GetLightId() const override; TUniqueId GetLightId() const override;
void DeleteLight(CStateManager& mgr) override; void DeleteLight(CStateManager& mgr) override;
void SetModulationColor(const zeus::CColor& color) override; void SetModulationColor(const zeus::CColor& color) override;
const std::shared_ptr<CParticleGen> GetParticleSystem() const { return x84_system; } const std::shared_ptr<CParticleGen>& GetParticleSystem() const { return x84_system; }
}; };
} // namespace urde } // namespace urde

View File

@ -14,39 +14,39 @@ namespace urde {
CActorList::CActorList() : CObjectList(EGameObjectList::Actor) {} CActorList::CActorList() : CObjectList(EGameObjectList::Actor) {}
bool CActorList::IsQualified(const CEntity& ent) { return TCastToConstPtr<CActor>(ent); } bool CActorList::IsQualified(const CEntity& ent) const { return TCastToConstPtr<CActor>(ent); }
CPhysicsActorList::CPhysicsActorList() : CObjectList(EGameObjectList::PhysicsActor) {} CPhysicsActorList::CPhysicsActorList() : CObjectList(EGameObjectList::PhysicsActor) {}
bool CPhysicsActorList::IsQualified(const CEntity& ent) { return TCastToConstPtr<CPhysicsActor>(ent); } bool CPhysicsActorList::IsQualified(const CEntity& ent) const { return TCastToConstPtr<CPhysicsActor>(ent); }
CGameCameraList::CGameCameraList() : CObjectList(EGameObjectList::GameCamera) {} CGameCameraList::CGameCameraList() : CObjectList(EGameObjectList::GameCamera) {}
bool CGameCameraList::IsQualified(const CEntity& ent) { return TCastToConstPtr<CGameCamera>(ent); } bool CGameCameraList::IsQualified(const CEntity& ent) const { return TCastToConstPtr<CGameCamera>(ent); }
CListeningAiList::CListeningAiList() : CObjectList(EGameObjectList::ListeningAi) {} CListeningAiList::CListeningAiList() : CObjectList(EGameObjectList::ListeningAi) {}
bool CListeningAiList::IsQualified(const CEntity& ent) { bool CListeningAiList::IsQualified(const CEntity& ent) const {
TCastToConstPtr<CAi> ai(ent); const TCastToConstPtr<CAi> ai(ent);
return ai && ai->IsListening(); return ai && ai->IsListening();
} }
CAiWaypointList::CAiWaypointList() : CObjectList(EGameObjectList::AiWaypoint) {} CAiWaypointList::CAiWaypointList() : CObjectList(EGameObjectList::AiWaypoint) {}
bool CAiWaypointList::IsQualified(const CEntity& ent) { bool CAiWaypointList::IsQualified(const CEntity& ent) const {
return TCastToConstPtr<CScriptCoverPoint>(ent) || TCastToConstPtr<CScriptAiJumpPoint>(ent); return TCastToConstPtr<CScriptCoverPoint>(ent) || TCastToConstPtr<CScriptAiJumpPoint>(ent);
} }
CPlatformAndDoorList::CPlatformAndDoorList() : CObjectList(EGameObjectList::PlatformAndDoor) {} CPlatformAndDoorList::CPlatformAndDoorList() : CObjectList(EGameObjectList::PlatformAndDoor) {}
bool CPlatformAndDoorList::IsQualified(const CEntity& ent) { return IsDoor(ent) || IsPlatform(ent); } bool CPlatformAndDoorList::IsQualified(const CEntity& ent) const { return IsDoor(ent) || IsPlatform(ent); }
bool CPlatformAndDoorList::IsDoor(const CEntity& ent) { return TCastToConstPtr<CScriptDoor>(ent); } bool CPlatformAndDoorList::IsDoor(const CEntity& ent) const { return TCastToConstPtr<CScriptDoor>(ent); }
bool CPlatformAndDoorList::IsPlatform(const CEntity& ent) { return TCastToConstPtr<CScriptPlatform>(ent); } bool CPlatformAndDoorList::IsPlatform(const CEntity& ent) const { return TCastToConstPtr<CScriptPlatform>(ent); }
CGameLightList::CGameLightList() : CObjectList(EGameObjectList::GameLight) {} CGameLightList::CGameLightList() : CObjectList(EGameObjectList::GameLight) {}
bool CGameLightList::IsQualified(const CEntity& lt) { return TCastToConstPtr<CGameLight>(lt); } bool CGameLightList::IsQualified(const CEntity& lt) const { return TCastToConstPtr<CGameLight>(lt); }
} // namespace urde } // namespace urde

View File

@ -8,47 +8,47 @@ class CActorList : public CObjectList {
public: public:
CActorList(); CActorList();
bool IsQualified(const CEntity&) override; bool IsQualified(const CEntity&) const override;
}; };
class CPhysicsActorList : public CObjectList { class CPhysicsActorList : public CObjectList {
public: public:
CPhysicsActorList(); CPhysicsActorList();
bool IsQualified(const CEntity&) override; bool IsQualified(const CEntity&) const override;
}; };
class CGameCameraList : public CObjectList { class CGameCameraList : public CObjectList {
public: public:
CGameCameraList(); CGameCameraList();
bool IsQualified(const CEntity&) override; bool IsQualified(const CEntity&) const override;
}; };
class CListeningAiList : public CObjectList { class CListeningAiList : public CObjectList {
public: public:
CListeningAiList(); CListeningAiList();
bool IsQualified(const CEntity&) override; bool IsQualified(const CEntity&) const override;
}; };
class CAiWaypointList : public CObjectList { class CAiWaypointList : public CObjectList {
public: public:
CAiWaypointList(); CAiWaypointList();
bool IsQualified(const CEntity&) override; bool IsQualified(const CEntity&) const override;
}; };
class CPlatformAndDoorList : public CObjectList { class CPlatformAndDoorList : public CObjectList {
public: public:
CPlatformAndDoorList(); CPlatformAndDoorList();
bool IsQualified(const CEntity&) override; bool IsQualified(const CEntity&) const override;
bool IsDoor(const CEntity&); bool IsDoor(const CEntity&) const;
bool IsPlatform(const CEntity&); bool IsPlatform(const CEntity&) const;
}; };
class CGameLightList : public CObjectList { class CGameLightList : public CObjectList {
public: public:
CGameLightList(); CGameLightList();
bool IsQualified(const CEntity&) override; bool IsQualified(const CEntity&) const override;
}; };
} // namespace urde } // namespace urde

View File

@ -13,6 +13,7 @@
#include "Runtime/World/CActor.hpp" #include "Runtime/World/CActor.hpp"
#include <algorithm> #include <algorithm>
#include <array>
#include <boo/System.hpp> #include <boo/System.hpp>
#include <logvisor/logvisor.hpp> #include <logvisor/logvisor.hpp>
@ -27,31 +28,66 @@
#define SPHERE_RAMP_RES 32 #define SPHERE_RAMP_RES 32
namespace urde { namespace urde {
namespace {
struct FogVolumeControl {
std::array<std::array<u32, 2>, 12> xfc_{
{{0, 1}, {1, 3}, {3, 2}, {2, 0}, {4, 5}, {5, 7}, {7, 6}, {6, 4}, {0, 4}, {1, 5}, {3, 7}, {2, 6}},
};
std::array<u32, 8> x15c_{};
// GXVtxDescList x17c_; {{POS, DIRECT}, {TEX0, DIRECT}}
};
static logvisor::Module Log("CBooRenderer"); logvisor::Module Log("CBooRenderer");
static rstl::reserved_vector<CDrawable, 512> sDataHolder; rstl::reserved_vector<CDrawable, 512> sDataHolder;
static rstl::reserved_vector<rstl::reserved_vector<CDrawable*, 128>, 50> sBucketsHolder; rstl::reserved_vector<rstl::reserved_vector<CDrawable*, 128>, 50> sBucketsHolder;
static rstl::reserved_vector<CDrawablePlaneObject, 8> sPlaneObjectDataHolder; rstl::reserved_vector<CDrawablePlaneObject, 8> sPlaneObjectDataHolder;
static rstl::reserved_vector<u16, 8> sPlaneObjectBucketHolder; rstl::reserved_vector<u16, 8> sPlaneObjectBucketHolder;
rstl::reserved_vector<u16, 50> Buckets::sBucketIndex; constexpr FogVolumeControl s_FogVolumeCtrl{};
rstl::reserved_vector<CDrawable, 512>* Buckets::sData = nullptr;
rstl::reserved_vector<rstl::reserved_vector<CDrawable*, 128>, 50>* Buckets::sBuckets = nullptr; constexpr std::array<std::array<int, 2>, 3> OrthogonalAxis{
rstl::reserved_vector<CDrawablePlaneObject, 8>* Buckets::sPlaneObjectData = nullptr; {{1, 2}, {0, 2}, {0, 1}},
rstl::reserved_vector<u16, 8>* Buckets::sPlaneObjectBucket = nullptr; };
const float Buckets::skWorstMinMaxDistance[2] = {99999.f, -99999.f};
float Buckets::sMinMaxDistance[2]; constexpr bool TestBit(const u32* words, size_t bit) { return (words[bit / 32] & (1U << (bit & 0x1f))) != 0; }
float GetPlaneInterpolant(const zeus::CPlane& plane, const zeus::CVector3f& vert1, const zeus::CVector3f& vert2) {
return zeus::clamp(0.f, -plane.pointToPlaneDist(vert1) / (vert2 - vert1).dot(plane.normal()), 1.f);
}
} // Anonymous namespace
class Buckets {
friend class CBooRenderer;
static inline rstl::reserved_vector<u16, 50> sBucketIndex;
static inline rstl::reserved_vector<CDrawable, 512>* sData = nullptr;
static inline rstl::reserved_vector<rstl::reserved_vector<CDrawable*, 128>, 50>* sBuckets = nullptr;
static inline rstl::reserved_vector<CDrawablePlaneObject, 8>* sPlaneObjectData = nullptr;
static inline rstl::reserved_vector<u16, 8>* sPlaneObjectBucket = nullptr;
static constexpr std::array skWorstMinMaxDistance{99999.0f, -99999.0f};
static inline std::array sMinMaxDistance{0.0f, 0.0f};
public:
static void Clear();
static void Sort();
static void InsertPlaneObject(float closeDist, float farDist, const zeus::CAABox& aabb, bool invertTest,
const zeus::CPlane& plane, bool zOnly, EDrawableType dtype, const void* data);
static void Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype, const void* data,
const zeus::CPlane& plane, u16 extraSort);
static void Shutdown();
static void Init();
};
void Buckets::Clear() { void Buckets::Clear() {
sData->clear(); sData->clear();
sBucketIndex.clear(); sBucketIndex.clear();
sPlaneObjectData->clear(); sPlaneObjectData->clear();
sPlaneObjectBucket->clear(); sPlaneObjectBucket->clear();
for (rstl::reserved_vector<CDrawable*, 128>& bucket : *sBuckets) for (rstl::reserved_vector<CDrawable*, 128>& bucket : *sBuckets) {
bucket.clear(); bucket.clear();
sMinMaxDistance[0] = skWorstMinMaxDistance[0]; }
sMinMaxDistance[1] = skWorstMinMaxDistance[1]; sMinMaxDistance = skWorstMinMaxDistance;
} }
void Buckets::Sort() { void Buckets::Sort() {
@ -153,12 +189,8 @@ void Buckets::Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDraw
const float dist = plane.pointToPlaneDist(pos); const float dist = plane.pointToPlaneDist(pos);
sData->emplace_back(dtype, extraSort, dist, aabb, data); sData->emplace_back(dtype, extraSort, dist, aabb, data);
if (sMinMaxDistance[0] > dist) { sMinMaxDistance[0] = std::min(sMinMaxDistance[0], dist);
sMinMaxDistance[0] = dist; sMinMaxDistance[1] = std::max(sMinMaxDistance[1], dist);
}
if (sMinMaxDistance[1] < dist) {
sMinMaxDistance[1] = dist;
}
} }
void Buckets::Shutdown() { void Buckets::Shutdown() {
@ -174,8 +206,7 @@ void Buckets::Init() {
sBuckets->resize(50); sBuckets->resize(50);
sPlaneObjectData = &sPlaneObjectDataHolder; sPlaneObjectData = &sPlaneObjectDataHolder;
sPlaneObjectBucket = &sPlaneObjectBucketHolder; sPlaneObjectBucket = &sPlaneObjectBucketHolder;
sMinMaxDistance[0] = skWorstMinMaxDistance[0]; sMinMaxDistance = skWorstMinMaxDistance;
sMinMaxDistance[1] = skWorstMinMaxDistance[1];
} }
CBooRenderer::CAreaListItem::CAreaListItem(const std::vector<CMetroidModelInstance>* geom, CBooRenderer::CAreaListItem::CAreaListItem(const std::vector<CMetroidModelInstance>* geom,
@ -191,50 +222,56 @@ CBooRenderer::CAreaListItem::CAreaListItem(const std::vector<CMetroidModelInstan
CBooRenderer::CAreaListItem::~CAreaListItem() {} CBooRenderer::CAreaListItem::~CAreaListItem() {}
static inline bool TestBit(const u32* words, int bit) { return (words[bit / 32] & (1 << (bit & 0x1f))) != 0; }
void CBooRenderer::ActivateLightsForModel(CAreaListItem* item, CBooModel& model) { void CBooRenderer::ActivateLightsForModel(CAreaListItem* item, CBooModel& model) {
std::vector<CLight> thisLights; std::vector<CLight> thisLights;
thisLights.reserve(4); thisLights.reserve(4);
if (x300_dynamicLights.size()) { if (x300_dynamicLights.size()) {
u32 lightOctreeWordCount = 0; u32 lightOctreeWordCount = 0;
u32* lightOctreeWords = nullptr; const u32* lightOctreeWords = nullptr;
if (item && model.x44_areaInstanceIdx != UINT32_MAX) { if (item && model.x44_areaInstanceIdx != UINT32_MAX) {
lightOctreeWordCount = item->x4_octTree->x14_bitmapWordCount; lightOctreeWordCount = item->x4_octTree->x14_bitmapWordCount;
lightOctreeWords = item->x1c_lightOctreeWords.data(); lightOctreeWords = item->x1c_lightOctreeWords.data();
} }
float lightRads[4] = {-1.f, -1.f, -1.f, -1.f}; std::array<float, 4> lightRads{-1.f, -1.f, -1.f, -1.f};
CLight* lightRefs[4] = {}; std::array<CLight*, 4> lightRefs{};
auto it = x300_dynamicLights.begin(); auto it = x300_dynamicLights.begin();
for (int i = 0; i < 4 && it != x300_dynamicLights.end(); ++it, lightOctreeWords += lightOctreeWordCount) { for (size_t i = 0; i < thisLights.size() && it != x300_dynamicLights.end();
++it, lightOctreeWords += lightOctreeWordCount) {
CLight& refLight = *it; CLight& refLight = *it;
if (lightOctreeWords && !TestBit(lightOctreeWords, model.x44_areaInstanceIdx)) if (lightOctreeWords && !TestBit(lightOctreeWords, model.x44_areaInstanceIdx)) {
continue; continue;
}
float radius = model.x20_aabb.intersectionRadius(zeus::CSphere(refLight.GetPosition(), refLight.GetRadius())); const float radius =
model.x20_aabb.intersectionRadius(zeus::CSphere(refLight.GetPosition(), refLight.GetRadius()));
bool foundLight = false; bool foundLight = false;
for (int j = 0; j < i; ++j) { for (size_t j = 0; j < i; ++j) {
if (lightRefs[j] == &refLight) if (lightRefs[j] == &refLight) {
continue; continue;
if (radius < 0.f) }
if (radius < 0.f) {
break; break;
if (lightRads[j] <= radius) }
if (lightRads[j] <= radius) {
break; break;
}
lightRads[j] = radius; lightRads[j] = radius;
thisLights.push_back(refLight); thisLights.push_back(refLight);
foundLight = true; foundLight = true;
break; break;
} }
if (foundLight) if (foundLight) {
continue; continue;
}
lightRads[i] = radius; lightRads[i] = radius;
if (radius < 0.f) if (radius < 0.f) {
continue; continue;
}
lightRefs[i] = &refLight; lightRefs[i] = &refLight;
thisLights.push_back(refLight); thisLights.push_back(refLight);
++i; ++i;
@ -287,23 +324,8 @@ void CBooRenderer::HandleUnsortedModel(CAreaListItem* item, CBooModel& model, co
} }
} }
static const struct FogVolumeControl { void CBooRenderer::CalcDrawFogFan(const zeus::CPlane* planes, size_t numPlanes, const zeus::CVector3f* verts,
size_t numVerts, size_t iteration, size_t level, CFogVolumePlaneShader& fogVol) {
u32 xfc_[12][2] = {{0, 1}, {1, 3}, {3, 2}, {2, 0}, {4, 5}, {5, 7}, {7, 6}, {6, 4}, {0, 4}, {1, 5}, {3, 7}, {2, 6}};
u32 x15c_[8] = {};
// GXVtxDescList x17c_; {{POS, DIRECT}, {TEX0, DIRECT}}
} s_FogVolumeCtrl = {};
static const int OrthogonalAxis[3][2] = {{1, 2}, {0, 2}, {0, 1}};
static float GetPlaneInterpolant(const zeus::CPlane& plane, const zeus::CVector3f& vert1,
const zeus::CVector3f& vert2) {
return zeus::clamp(0.f, -plane.pointToPlaneDist(vert1) / (vert2 - vert1).dot(plane.normal()), 1.f);
}
void CBooRenderer::CalcDrawFogFan(const zeus::CPlane* planes, int numPlanes, const zeus::CVector3f* verts, int numVerts,
int iteration, int level, CFogVolumePlaneShader& fogVol) {
if (level == iteration) { if (level == iteration) {
CalcDrawFogFan(planes, numPlanes, verts, numVerts, iteration, level + 1, fogVol); CalcDrawFogFan(planes, numPlanes, verts, numVerts, iteration, level + 1, fogVol);
return; return;
@ -315,48 +337,56 @@ void CBooRenderer::CalcDrawFogFan(const zeus::CPlane* planes, int numPlanes, con
} }
const zeus::CPlane& plane = planes[level]; const zeus::CPlane& plane = planes[level];
u32 insidePlaneCount = 0; size_t insidePlaneCount = 0;
bool outsidePlane[20]; std::array<bool, 20> outsidePlane;
for (int i = 0; i < numVerts; ++i) for (size_t i = 0; i < numVerts; ++i) {
outsidePlane[insidePlaneCount++] = plane.normal().dot(verts[i]) < plane.d(); outsidePlane[insidePlaneCount++] = plane.normal().dot(verts[i]) < plane.d();
}
u32 numUseVerts = 0; size_t numUseVerts = 0;
zeus::CVector3f useVerts[20]; std::array<zeus::CVector3f, 20> useVerts;
for (int i = 0; i < numVerts; ++i) { for (size_t i = 0; i < numVerts; ++i) {
int nextIdx = (i + 1) % numVerts; const size_t nextIdx = (i + 1) % numVerts;
int insidePair = int(outsidePlane[i]) | (int(outsidePlane[nextIdx]) << 1); const int insidePair = int(outsidePlane[i]) | (int(outsidePlane[nextIdx]) << 1);
if (!(insidePair & 0x1)) if ((insidePair & 0x1) == 0) {
useVerts[numUseVerts++] = verts[i]; useVerts[numUseVerts++] = verts[i];
}
if (insidePair == 1 || insidePair == 2) { if (insidePair == 1 || insidePair == 2) {
/* Inside/outside transition; clip verts to other plane boundary */ /* Inside/outside transition; clip verts to other plane boundary */
const zeus::CVector3f vert1 = verts[i]; const zeus::CVector3f vert1 = verts[i];
const zeus::CVector3f vert2 = verts[nextIdx]; const zeus::CVector3f vert2 = verts[nextIdx];
float interp = GetPlaneInterpolant(plane, vert1, vert2); const float interp = GetPlaneInterpolant(plane, vert1, vert2);
if (interp > 0.f || interp < 1.f) if (interp > 0.f || interp < 1.f) {
useVerts[numUseVerts++] = (vert1 * (1.f - interp)) + (vert2 * interp); useVerts[numUseVerts++] = (vert1 * (1.f - interp)) + (vert2 * interp);
} }
} }
}
if (numUseVerts >= 3) if (numUseVerts < 3) {
CalcDrawFogFan(planes, numPlanes, useVerts, numUseVerts, iteration, level + 1, fogVol); return;
}
CalcDrawFogFan(planes, numPlanes, useVerts.data(), numUseVerts, iteration, level + 1, fogVol);
} }
void CBooRenderer::DrawFogSlices(const zeus::CPlane* planes, int numPlanes, int iteration, void CBooRenderer::DrawFogSlices(const zeus::CPlane* planes, size_t numPlanes, size_t iteration,
const zeus::CVector3f& center, float longestAxis, CFogVolumePlaneShader& fogVol) { const zeus::CVector3f& center, float longestAxis, CFogVolumePlaneShader& fogVol) {
u32 vertCount = 0; u32 vertCount = 0;
zeus::CVector3d verts[4]; std::array<zeus::CVector3d, 4> verts;
u32 vert2Count = 0; u32 vert2Count = 0;
zeus::CVector3f verts2[4]; std::array<zeus::CVector3f, 4> verts2;
const zeus::CPlane& plane = planes[iteration]; const zeus::CPlane& plane = planes[iteration];
int longestNormAxis = std::fabs(plane[1]) > std::fabs(plane[0]); int longestNormAxis = std::fabs(plane[1]) > std::fabs(plane[0]);
if (std::fabs(plane[2]) > std::fabs(plane[longestNormAxis])) if (std::fabs(plane[2]) > std::fabs(plane[longestNormAxis])) {
longestNormAxis = 2; longestNormAxis = 2;
}
zeus::CVector3d pointOnPlane = center - (plane.pointToPlaneDist(center) * plane.normal()); const zeus::CVector3d pointOnPlane = center - (plane.pointToPlaneDist(center) * plane.normal());
float deltaSign = plane[longestNormAxis] >= 0.f ? -1.f : 1.f; float deltaSign = plane[longestNormAxis] >= 0.f ? -1.f : 1.f;
if (longestNormAxis == 1) if (longestNormAxis == 1) {
deltaSign = -deltaSign; deltaSign = -deltaSign;
}
zeus::CVector3d vec1; zeus::CVector3d vec1;
zeus::CVector3d vec2; zeus::CVector3d vec2;
@ -369,11 +399,12 @@ void CBooRenderer::DrawFogSlices(const zeus::CPlane* planes, int numPlanes, int
verts[vertCount++] = pointOnPlane + vec1 + vec2; verts[vertCount++] = pointOnPlane + vec1 + vec2;
verts[vertCount++] = pointOnPlane - vec1 + vec2; verts[vertCount++] = pointOnPlane - vec1 + vec2;
zeus::CVector3d planeNormal = plane.normal(); const zeus::CVector3d planeNormal = plane.normal();
for (const zeus::CVector3d& vert : verts) for (const zeus::CVector3d& vert : verts) {
verts2[vert2Count++] = vert - (planeNormal * zeus::CVector3f(planeNormal.dot(vert) - plane.d())); verts2[vert2Count++] = vert - (planeNormal * zeus::CVector3f(planeNormal.dot(vert) - plane.d()));
}
CalcDrawFogFan(planes, numPlanes, verts2, vert2Count, iteration, 0, fogVol); CalcDrawFogFan(planes, numPlanes, verts2.data(), vert2Count, iteration, 0, fogVol);
} }
void CBooRenderer::RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model, const zeus::CTransform& modelMtx, void CBooRenderer::RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model, const zeus::CTransform& modelMtx,
@ -383,23 +414,26 @@ void CBooRenderer::RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel*
if (pass == 0) { if (pass == 0) {
zeus::CAABox xfAABB = aabb.getTransformedAABox(modelMtx); zeus::CAABox xfAABB = aabb.getTransformedAABox(modelMtx);
zeus::CUnitVector3f viewNormal(viewMtx.basis[1]); zeus::CUnitVector3f viewNormal(viewMtx.basis[1]);
zeus::CPlane planes[7] = {{zeus::skRight, xfAABB.min.x()}, const std::array<zeus::CPlane, 7> planes{{
{zeus::skRight, xfAABB.min.x()},
{zeus::skLeft, -xfAABB.max.x()}, {zeus::skLeft, -xfAABB.max.x()},
{zeus::skForward, xfAABB.min.y()}, {zeus::skForward, xfAABB.min.y()},
{zeus::skBack, -xfAABB.max.y()}, {zeus::skBack, -xfAABB.max.y()},
{zeus::skUp, xfAABB.min.z()}, {zeus::skUp, xfAABB.min.z()},
{zeus::skDown, -xfAABB.max.z()}, {zeus::skDown, -xfAABB.max.z()},
{viewNormal, viewNormal.dot(viewMtx.origin) + 0.2f + 0.1f}}; {viewNormal, viewNormal.dot(viewMtx.origin) + 0.2f + 0.1f},
}};
CGraphics::SetModelMatrix(zeus::CTransform()); CGraphics::SetModelMatrix(zeus::CTransform());
float longestAxis = std::max(std::max(xfAABB.max.x() - xfAABB.min.x(), xfAABB.max.y() - xfAABB.min.y()), const float longestAxis = std::max(std::max(xfAABB.max.x() - xfAABB.min.x(), xfAABB.max.y() - xfAABB.min.y()),
xfAABB.max.z() - xfAABB.min.z()) * xfAABB.max.z() - xfAABB.min.z()) *
2.f; 2.f;
fvs->reset(7 * 6); fvs->reset(7 * 6);
for (int i = 0; i < 7; ++i) for (size_t i = 0; i < planes.size(); ++i) {
DrawFogSlices(planes, 7, i, xfAABB.center(), longestAxis, *fvs); DrawFogSlices(planes.data(), planes.size(), i, xfAABB.center(), longestAxis, *fvs);
}
fvs->draw(0); fvs->draw(0);
} else { } else {
fvs->draw(pass); fvs->draw(pass);
@ -444,45 +478,47 @@ void CBooRenderer::ReallyRenderFogVolume(const zeus::CColor& color, const zeus::
const CSkinnedModel* sModel) { const CSkinnedModel* sModel) {
SCOPED_GRAPHICS_DEBUG_GROUP("CBooRenderer::ReallyRenderFogVolume", zeus::skPurple); SCOPED_GRAPHICS_DEBUG_GROUP("CBooRenderer::ReallyRenderFogVolume", zeus::skPurple);
zeus::CMatrix4f proj = CGraphics::GetPerspectiveProjectionMatrix(false); zeus::CMatrix4f proj = CGraphics::GetPerspectiveProjectionMatrix(false);
zeus::CVector4f points[8]; std::array<zeus::CVector4f, 8> points;
for (int i = 0; i < 8; ++i) { for (size_t i = 0; i < points.size(); ++i) {
zeus::CVector3f xfPt = CGraphics::g_GXModelView * aabb.getPoint(i); const zeus::CVector3f xfPt = CGraphics::g_GXModelView * aabb.getPoint(i);
points[i] = proj * zeus::CVector4f(xfPt); points[i] = proj * zeus::CVector4f(xfPt);
} }
zeus::CVector2i vpMax(0, 0); zeus::CVector2i vpMax(0, 0);
zeus::CVector2i vpMin(g_Viewport.x8_width, g_Viewport.xc_height); zeus::CVector2i vpMin(g_Viewport.x8_width, g_Viewport.xc_height);
for (int i = 0; i < 20; ++i) { for (size_t i = 0; i < 20; ++i) {
zeus::CVector3f overW; zeus::CVector3f overW;
if (i < 8) { if (i < points.size()) {
overW = points[i].toVec3f() * (1.f / points[i].w()); overW = points[i].toVec3f() * (1.f / points[i].w());
} else { } else {
const zeus::CVector4f& pt1 = points[s_FogVolumeCtrl.xfc_[i - 8][0]]; const zeus::CVector4f& pt1 = points[s_FogVolumeCtrl.xfc_[i - 8][0]];
const zeus::CVector4f& pt2 = points[s_FogVolumeCtrl.xfc_[i - 8][1]]; const zeus::CVector4f& pt2 = points[s_FogVolumeCtrl.xfc_[i - 8][1]];
bool eq1 = (pt1.z() / pt1.w()) == 1.f; const bool eq1 = (pt1.z() / pt1.w()) == 1.f;
bool eq2 = (pt2.z() / pt2.w()) == 1.f; const bool eq2 = (pt2.z() / pt2.w()) == 1.f;
if (eq1 == eq2) if (eq1 == eq2) {
continue; continue;
}
float interp = -(pt1.w() - 1.f) / (pt2.w() - pt1.w()); const float interp = -(pt1.w() - 1.f) / (pt2.w() - pt1.w());
if (interp <= 0.f || interp >= 1.f) if (interp <= 0.f || interp >= 1.f) {
continue; continue;
}
float wRecip = 1.f / (interp * (pt2.w() - pt1.w()) + pt1.w()); const float wRecip = 1.f / (interp * (pt2.w() - pt1.w()) + pt1.w());
zeus::CVector3f pt1_3 = pt1.toVec3f(); const zeus::CVector3f pt1_3 = pt1.toVec3f();
zeus::CVector3f pt2_3 = pt2.toVec3f(); const zeus::CVector3f pt2_3 = pt2.toVec3f();
overW = (pt1_3 + interp * (pt2_3 - pt1_3)) * wRecip; overW = (pt1_3 + interp * (pt2_3 - pt1_3)) * wRecip;
} }
// if (overW.z > 1.001f) // if (overW.z > 1.001f)
// continue; // continue;
int vpX = zeus::clamp(0, int(g_Viewport.x8_width * overW.x() * 0.5f + (g_Viewport.x8_width / 2)), const int vpX = zeus::clamp(0, int(g_Viewport.x8_width * overW.x() * 0.5f + (g_Viewport.x8_width / 2)),
int(g_Viewport.x8_width)); int(g_Viewport.x8_width));
int vpY = zeus::clamp(0, int(g_Viewport.xc_height * overW.y() * 0.5f + (g_Viewport.xc_height / 2)), const int vpY = zeus::clamp(0, int(g_Viewport.xc_height * overW.y() * 0.5f + (g_Viewport.xc_height / 2)),
int(g_Viewport.xc_height)); int(g_Viewport.xc_height));
vpMax.x = std::max(vpMax.x, vpX); vpMax.x = std::max(vpMax.x, vpX);
vpMin.x = std::min(vpMin.x, vpX); vpMin.x = std::min(vpMin.x, vpX);
@ -541,11 +577,11 @@ void CBooRenderer::ReallyRenderFogVolume(const zeus::CColor& color, const zeus::
} }
void CBooRenderer::GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context& ctx) { void CBooRenderer::GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context& ctx) {
u16 data[FOGVOL_RAMP_RES][FOGVOL_RAMP_RES] = {}; std::array<std::array<u16, FOGVOL_RAMP_RES>, FOGVOL_RAMP_RES> data{};
for (int y = 0; y < FOGVOL_RAMP_RES; ++y) { for (size_t y = 0; y < data.size(); ++y) {
for (int x = 0; x < FOGVOL_RAMP_RES; ++x) { for (size_t x = 0; x < data[y].size(); ++x) {
int tmp = y << 16 | x << 8 | 0x7f; const int tmp = int(y << 16 | x << 8 | 0x7f);
double a = const double a =
zeus::clamp(0.0, zeus::clamp(0.0,
(-150.0 / (tmp / double(0xffffff) * (FOGVOL_FAR - FOGVOL_NEAR) - FOGVOL_FAR) - FOGVOL_NEAR) * (-150.0 / (tmp / double(0xffffff) * (FOGVOL_FAR - FOGVOL_NEAR) - FOGVOL_FAR) - FOGVOL_NEAR) *
3.0 / (FOGVOL_FAR - FOGVOL_NEAR), 3.0 / (FOGVOL_FAR - FOGVOL_NEAR),
@ -555,21 +591,21 @@ void CBooRenderer::GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context&
} }
x1b8_fogVolumeRamp = x1b8_fogVolumeRamp =
ctx.newStaticTexture(FOGVOL_RAMP_RES, FOGVOL_RAMP_RES, 1, boo::TextureFormat::I16, boo::TextureClampMode::Repeat, ctx.newStaticTexture(FOGVOL_RAMP_RES, FOGVOL_RAMP_RES, 1, boo::TextureFormat::I16, boo::TextureClampMode::Repeat,
data[0], FOGVOL_RAMP_RES * FOGVOL_RAMP_RES * 2); data[0].data(), FOGVOL_RAMP_RES * FOGVOL_RAMP_RES * 2);
} }
void CBooRenderer::GenerateSphereRampTex(boo::IGraphicsDataFactory::Context& ctx) { void CBooRenderer::GenerateSphereRampTex(boo::IGraphicsDataFactory::Context& ctx) {
u8 data[SPHERE_RAMP_RES][SPHERE_RAMP_RES] = {}; std::array<std::array<u8, SPHERE_RAMP_RES>, SPHERE_RAMP_RES> data{};
float halfRes = SPHERE_RAMP_RES / 2.f; constexpr float halfRes = SPHERE_RAMP_RES / 2.f;
for (int y = 0; y < SPHERE_RAMP_RES; ++y) { for (size_t y = 0; y < data.size(); ++y) {
for (int x = 0; x < SPHERE_RAMP_RES; ++x) { for (size_t x = 0; x < data[y].size(); ++x) {
zeus::CVector2f vec((x - halfRes) / halfRes, (y - halfRes) / halfRes); const zeus::CVector2f vec((float(x) - halfRes) / halfRes, (float(y) - halfRes) / halfRes);
data[y][x] = 255 - zeus::clamp(0.f, vec.canBeNormalized() ? vec.magnitude() : 0.f, 1.f) * 255; data[y][x] = 255 - zeus::clamp(0.f, vec.canBeNormalized() ? vec.magnitude() : 0.f, 1.f) * 255;
} }
} }
x220_sphereRamp = ctx.newStaticTexture(SPHERE_RAMP_RES, SPHERE_RAMP_RES, 1, boo::TextureFormat::I8, x220_sphereRamp =
boo::TextureClampMode::ClampToEdge, data[0], ctx.newStaticTexture(SPHERE_RAMP_RES, SPHERE_RAMP_RES, 1, boo::TextureFormat::I8,
SPHERE_RAMP_RES * SPHERE_RAMP_RES); boo::TextureClampMode::ClampToEdge, data[0].data(), SPHERE_RAMP_RES * SPHERE_RAMP_RES);
} }
void CBooRenderer::GenerateScanLinesVBO(boo::IGraphicsDataFactory::Context& ctx) { void CBooRenderer::GenerateScanLinesVBO(boo::IGraphicsDataFactory::Context& ctx) {
@ -610,18 +646,21 @@ void CBooRenderer::GenerateScanLinesVBO(boo::IGraphicsDataFactory::Context& ctx)
} }
boo::ObjToken<boo::ITexture> CBooRenderer::GetColorTexture(const zeus::CColor& color) { boo::ObjToken<boo::ITexture> CBooRenderer::GetColorTexture(const zeus::CColor& color) {
auto search = m_colorTextures.find(color); const auto search = m_colorTextures.find(color);
if (search != m_colorTextures.end()) if (search != m_colorTextures.end()) {
return search->second; return search->second;
u8 pixel[4]; }
std::array<u8, 4> pixel;
color.toRGBA8(pixel[0], pixel[1], pixel[2], pixel[3]); color.toRGBA8(pixel[0], pixel[1], pixel[2], pixel[3]);
boo::ObjToken<boo::ITexture> tex; boo::ObjToken<boo::ITexture> tex;
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
tex = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, tex = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, pixel.data(),
boo::TextureClampMode::Repeat, pixel, 4).get(); pixel.size())
.get();
return true; return true;
} BooTrace); } BooTrace);
m_colorTextures.insert(std::make_pair(color, tex)); m_colorTextures.emplace(color, tex);
return tex; return tex;
} }
@ -649,15 +688,18 @@ CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac)
m_staticEntropy = store.GetObj("RandomStaticEntropy"); m_staticEntropy = store.GetObj("RandomStaticEntropy");
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
u8 clearPixel[] = {0, 0, 0, 0}; constexpr std::array<u8, 4> clearPixel{0, 0, 0, 0};
m_clearTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, m_clearTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat,
boo::TextureClampMode::Repeat, clearPixel, 4).get(); clearPixel.data(), clearPixel.size())
u8 blackPixel[] = {0, 0, 0, 255}; .get();
m_blackTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, constexpr std::array<u8, 4> blackPixel{0, 0, 0, 255};
boo::TextureClampMode::Repeat, blackPixel, 4).get(); m_blackTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat,
u8 whitePixel[] = {255, 255, 255, 255}; blackPixel.data(), blackPixel.size())
m_whiteTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, .get();
boo::TextureClampMode::Repeat, whitePixel, 4).get(); constexpr std::array<u8, 4> whitePixel{255, 255, 255, 255};
m_whiteTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat,
whitePixel.data(), whitePixel.size())
.get();
GenerateFogVolumeRampTex(ctx); GenerateFogVolumeRampTex(ctx);
GenerateSphereRampTex(ctx); GenerateSphereRampTex(ctx);
@ -694,7 +736,7 @@ void CBooRenderer::AddWorldSurfaces(CBooModel& model) {
std::list<CBooRenderer::CAreaListItem>::iterator std::list<CBooRenderer::CAreaListItem>::iterator
CBooRenderer::FindStaticGeometry(const std::vector<CMetroidModelInstance>* geometry) { CBooRenderer::FindStaticGeometry(const std::vector<CMetroidModelInstance>* geometry) {
return std::find_if(x1c_areaListItems.begin(), x1c_areaListItems.end(), return std::find_if(x1c_areaListItems.begin(), x1c_areaListItems.end(),
[&](CAreaListItem& item) -> bool { return item.x0_geometry == geometry; }); [&](const CAreaListItem& item) { return item.x0_geometry == geometry; });
} }
void CBooRenderer::AddStaticGeometry(const std::vector<CMetroidModelInstance>* geometry, void CBooRenderer::AddStaticGeometry(const std::vector<CMetroidModelInstance>* geometry,

View File

@ -38,27 +38,7 @@ class CTexture;
class IFactory; class IFactory;
class IObjectStore; class IObjectStore;
class Buckets { class Buckets;
friend class CBooRenderer;
static rstl::reserved_vector<u16, 50> sBucketIndex;
static rstl::reserved_vector<CDrawable, 512>* sData;
static rstl::reserved_vector<rstl::reserved_vector<CDrawable*, 128>, 50>* sBuckets;
static rstl::reserved_vector<CDrawablePlaneObject, 8>* sPlaneObjectData;
static rstl::reserved_vector<u16, 8>* sPlaneObjectBucket;
static const float skWorstMinMaxDistance[2];
static float sMinMaxDistance[2];
public:
static void Clear();
static void Sort();
static void InsertPlaneObject(float closeDist, float farDist, const zeus::CAABox& aabb, bool invertTest,
const zeus::CPlane& plane, bool zOnly, EDrawableType dtype, const void* data);
static void Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype, const void* data,
const zeus::CPlane& plane, u16 extraSort);
static void Shutdown();
static void Init();
};
enum class EWorldShadowMode { enum class EWorldShadowMode {
None, None,
@ -196,10 +176,10 @@ class CBooRenderer final : public IRenderer {
void ActivateLightsForModel(CAreaListItem* item, CBooModel& model); void ActivateLightsForModel(CAreaListItem* item, CBooModel& model);
void RenderBucketItems(CAreaListItem* item); void RenderBucketItems(CAreaListItem* item);
void HandleUnsortedModel(CAreaListItem* item, CBooModel& model, const CModelFlags& flags); void HandleUnsortedModel(CAreaListItem* item, CBooModel& model, const CModelFlags& flags);
static void CalcDrawFogFan(const zeus::CPlane* planes, int numPlanes, const zeus::CVector3f* verts, int numVerts, static void CalcDrawFogFan(const zeus::CPlane* planes, size_t numPlanes, const zeus::CVector3f* verts,
int iteration, int level, CFogVolumePlaneShader& fogVol); size_t numVerts, size_t iteration, size_t level, CFogVolumePlaneShader& fogVol);
static void DrawFogSlices(const zeus::CPlane* planes, int numPlanes, int iteration, const zeus::CVector3f& center, static void DrawFogSlices(const zeus::CPlane* planes, size_t numPlanes, size_t iteration,
float delta, CFogVolumePlaneShader& fogVol); const zeus::CVector3f& center, float delta, CFogVolumePlaneShader& fogVol);
static void RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model, const zeus::CTransform& modelMtx, static void RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model, const zeus::CTransform& modelMtx,
const zeus::CTransform& viewMtx, const CSkinnedModel* sModel, int pass, const zeus::CTransform& viewMtx, const CSkinnedModel* sModel, int pass,
CFogVolumePlaneShader* fvs); CFogVolumePlaneShader* fvs);

View File

@ -18,10 +18,32 @@
#include <logvisor/logvisor.hpp> #include <logvisor/logvisor.hpp>
namespace urde { namespace urde {
static logvisor::Module Log("urde::CBooModel"); namespace {
bool CBooModel::g_DrawingOccluders = false; logvisor::Module Log("urde::CBooModel");
CBooModel* g_FirstModel = nullptr;
static CBooModel* g_FirstModel = nullptr; constexpr zeus::CMatrix4f ReflectBaseMtx{
0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f,
};
constexpr zeus::CMatrix4f ReflectPostGL{
1.f, 0.f, 0.f, 0.f, 0.f, -1.f, 0.f, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f,
};
constexpr zeus::CMatrix4f MBShadowPost0{
1.f, 0.f, 0.f, 0.f, 0.f, -1.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f,
};
constexpr zeus::CMatrix4f MBShadowPost1{
0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, -0.0625f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f,
};
constexpr zeus::CMatrix4f DisintegratePost{
1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f,
};
} // Anonymous namespace
bool CBooModel::g_DrawingOccluders = false;
void CBooModel::Shutdown() { void CBooModel::Shutdown() {
g_shadowMap.reset(); g_shadowMap.reset();
@ -59,12 +81,6 @@ bool CBooModel::g_RenderModelBlack = false;
zeus::CVector3f CBooModel::g_ReflectViewPos = {}; zeus::CVector3f CBooModel::g_ReflectViewPos = {};
static const zeus::CMatrix4f ReflectBaseMtx = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f};
static const zeus::CMatrix4f ReflectPostGL = {1.f, 0.f, 0.f, 0.f, 0.f, -1.f, 0.f, 1.f,
0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f};
void CBooModel::EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf, zeus::CMatrix4f* mtxsOut, void CBooModel::EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf, zeus::CMatrix4f* mtxsOut,
float& alphaOut) { float& alphaOut) {
zeus::CVector3f modelToPlayer = g_PlayerPosition - CGraphics::g_GXModelMatrix.origin; zeus::CVector3f modelToPlayer = g_PlayerPosition - CGraphics::g_GXModelMatrix.origin;
@ -359,7 +375,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
std::vector<boo::ObjToken<boo::IShaderDataBinding>>& extendeds = newInst.m_shaderDataBindings.back(); std::vector<boo::ObjToken<boo::IShaderDataBinding>>& extendeds = newInst.m_shaderDataBindings.back();
extendeds.reserve(pipelines->size()); extendeds.reserve(pipelines->size());
int idx = 0; EExtendedShader idx{};
for (const auto& pipeline : *pipelines) { for (const auto& pipeline : *pipelines) {
if (idx == EExtendedShader::Thermal) { if (idx == EExtendedShader::Thermal) {
texs[8] = g_Renderer->x220_sphereRamp.get(); texs[8] = g_Renderer->x220_sphereRamp.get();
@ -387,7 +403,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf) {
extendeds.push_back(ctx.newShaderDataBinding(pipeline, newInst.GetBooVBO(*this, ctx), nullptr, extendeds.push_back(ctx.newShaderDataBinding(pipeline, newInst.GetBooVBO(*this, ctx), nullptr,
m_staticIbo.get(), 4, bufs, stages, thisOffs, thisSizes, 12, texs, m_staticIbo.get(), 4, bufs, stages, thisOffs, thisSizes, 12, texs,
nullptr, nullptr)); nullptr, nullptr));
++idx; idx = EExtendedShader(size_t(idx) + 1);
} }
} }
return true; return true;
@ -626,7 +642,7 @@ void CBooModel::DrawSurface(const CBooSurface& surf, const CModelFlags& flags) c
const std::vector<boo::ObjToken<boo::IShaderDataBinding>>& extendeds = inst.m_shaderDataBindings[surf.selfIdx]; const std::vector<boo::ObjToken<boo::IShaderDataBinding>>& extendeds = inst.m_shaderDataBindings[surf.selfIdx];
EExtendedShader extended = ResolveExtendedShader(data, flags); EExtendedShader extended = ResolveExtendedShader(data, flags);
boo::ObjToken<boo::IShaderDataBinding> binding = extendeds[extended]; boo::ObjToken<boo::IShaderDataBinding> binding = extendeds[size_t(extended)];
CGraphics::SetShaderDataBinding(binding); CGraphics::SetShaderDataBinding(binding);
CGraphics::DrawArrayIndexed(surf.m_data.idxStart, surf.m_data.idxCount); CGraphics::DrawArrayIndexed(surf.m_data.idxStart, surf.m_data.idxCount);
} }
@ -747,17 +763,6 @@ void CBooModel::UVAnimationBuffer::PadOutBuffer(u8*& bufStart, u8*& bufOut) {
bufOut = bufStart + ROUND_UP_256(bufOut - bufStart); bufOut = bufStart + ROUND_UP_256(bufOut - bufStart);
} }
static const zeus::CMatrix4f MBShadowPost0(1.f, 0.f, 0.f, 0.f,
0.f, -1.f, 0.f, 1.f,
0.f, 0.f, 0.f, 1.f,
0.f, 0.f, 0.f, 1.f);
static const zeus::CMatrix4f MBShadowPost1(0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f, -0.0625f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f,
0.f, 1.f);
static const zeus::CMatrix4f DisintegratePost(1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f,
1.f);
void CBooModel::UVAnimationBuffer::Update(u8*& bufOut, const MaterialSet* matSet, const CModelFlags& flags, void CBooModel::UVAnimationBuffer::Update(u8*& bufOut, const MaterialSet* matSet, const CModelFlags& flags,
const CBooModel* parent) { const CBooModel* parent) {
u8* start = bufOut; u8* start = bufOut;

View File

@ -1,25 +1,32 @@
#include "Runtime/Graphics/CPVSVisOctree.hpp" #include "Runtime/Graphics/CPVSVisOctree.hpp"
#include <array>
namespace urde { namespace urde {
CPVSVisOctree CPVSVisOctree::MakePVSVisOctree(const u8* data) { CPVSVisOctree CPVSVisOctree::MakePVSVisOctree(const u8* data) {
CMemoryInStream r(data, 68); CMemoryInStream r(data, 68);
zeus::CAABox aabb = aabb.ReadBoundingBoxBig(r); const zeus::CAABox aabb = zeus::CAABox::ReadBoundingBoxBig(r);
u32 numObjects = r.readUint32Big(); const u32 numObjects = r.readUint32Big();
u32 numLights = r.readUint32Big(); const u32 numLights = r.readUint32Big();
r.readUint32Big(); r.readUint32Big();
return CPVSVisOctree(aabb, numObjects, numLights, data + r.position()); return CPVSVisOctree(aabb, numObjects, numLights, data + r.position());
} }
CPVSVisOctree::CPVSVisOctree(const zeus::CAABox& aabb, u32 numObjects, u32 numLights, const u8* c) CPVSVisOctree::CPVSVisOctree(const zeus::CAABox& aabb, u32 numObjects, u32 numLights, const u8* c)
: x0_aabb(aabb), x18_numObjects(numObjects), x1c_numLights(numLights), x20_bufferFlag(c != nullptr), x24_octreeData(c) { : x0_aabb(aabb)
x2c_searchAabb = x0_aabb; , x18_numObjects(numObjects)
x20_bufferFlag = 0; , x1c_numLights(numLights)
, x20_bufferFlag(c != nullptr)
, x24_octreeData(c)
, x2c_searchAabb(x0_aabb) {
x20_bufferFlag = false;
} }
static const u32 NumChildTable[] = {0, 2, 2, 4, 2, 4, 4, 8}; u32 CPVSVisOctree::GetNumChildren(u8 byte) const {
static constexpr std::array<u32, 8> numChildTable{0, 2, 2, 4, 2, 4, 4, 8};
u32 CPVSVisOctree::GetNumChildren(u8 byte) const { return NumChildTable[byte & 0x7]; } return numChildTable[byte & 0x7];
}
u32 CPVSVisOctree::GetChildIndex(const u8*, const zeus::CVector3f&) const { return 0; } u32 CPVSVisOctree::GetChildIndex(const u8*, const zeus::CVector3f&) const { return 0; }
@ -29,7 +36,7 @@ s32 CPVSVisOctree::IterateSearch(u8 nodeData, const zeus::CVector3f& tp) const {
zeus::CVector3f newMin = x2c_searchAabb.center(); zeus::CVector3f newMin = x2c_searchAabb.center();
zeus::CVector3f newMax; zeus::CVector3f newMax;
bool highFlags[3]; std::array<bool, 3> highFlags{};
if (tp.x() > newMin.x()) { if (tp.x() > newMin.x()) {
newMax.x() = x2c_searchAabb.max.x(); newMax.x() = x2c_searchAabb.max.x();
@ -58,7 +65,7 @@ s32 CPVSVisOctree::IterateSearch(u8 nodeData, const zeus::CVector3f& tp) const {
highFlags[2] = false; highFlags[2] = false;
} }
u8 axisCounts[2] = {1, 1}; std::array<u8, 2> axisCounts{1, 1};
if (nodeData & 0x1) if (nodeData & 0x1)
axisCounts[0] = 2; axisCounts[0] = 2;
if (nodeData & 0x2) if (nodeData & 0x2)

View File

@ -10,10 +10,10 @@ namespace urde {
class CPVSVisOctree { class CPVSVisOctree {
zeus::CAABox x0_aabb; zeus::CAABox x0_aabb;
u32 x18_numObjects; u32 x18_numObjects = 0;
u32 x1c_numLights; u32 x1c_numLights = 0;
bool x20_bufferFlag; bool x20_bufferFlag = false;
const u8* x24_octreeData; const u8* x24_octreeData = nullptr;
zeus::CAABox x2c_searchAabb; zeus::CAABox x2c_searchAabb;
public: public:

View File

@ -21,7 +21,7 @@ class ShaderTag;
namespace urde { namespace urde {
class CLight; class CLight;
enum EExtendedShader : uint8_t { enum class EExtendedShader : uint8_t {
Flat, Flat,
Lighting, Lighting,
Thermal, Thermal,
@ -96,7 +96,7 @@ public:
static void Initialize(); static void Initialize();
static void Shutdown(); static void Shutdown();
using ShaderPipelinesData = std::array<boo::ObjToken<boo::IShaderPipeline>, EExtendedShader::MAX>; using ShaderPipelinesData = std::array<boo::ObjToken<boo::IShaderPipeline>, size_t(EExtendedShader::MAX)>;
using ShaderPipelines = std::shared_ptr<ShaderPipelinesData>; using ShaderPipelines = std::shared_ptr<ShaderPipelinesData>;
using Material = DataSpec::DNAMP1::HMDLMaterialSet::Material; using Material = DataSpec::DNAMP1::HMDLMaterialSet::Material;

View File

@ -50,12 +50,10 @@ void CFontRenderState::RefreshColor(EColorType tp) {
return; return;
switch (x48_font->GetMode()) { switch (x48_font->GetMode()) {
case EColorType::Main: case EColorType::Main:
if (!x64_colorOverrides[0])
x0_drawStrOpts.x4_colors[0] = ConvertToTextureSpace(x54_colors[0]);
break;
case EColorType::Outline: case EColorType::Outline:
if (!x64_colorOverrides[0]) if (!x64_colorOverrides[0]) {
x0_drawStrOpts.x4_colors[0] = ConvertToTextureSpace(x54_colors[0]); x0_drawStrOpts.x4_colors[0] = ConvertToTextureSpace(x54_colors[0]);
}
break; break;
default: default:
break; break;

View File

@ -35,10 +35,7 @@ protected:
EVerticalJustification x84_vjust = EVerticalJustification::Top; EVerticalJustification x84_vjust = EVerticalJustification::Top;
public: public:
CSaveableState() { CSaveableState() : x54_colors(3, zeus::skBlack), x64_colorOverrides(16) {}
x54_colors.resize(3, zeus::skBlack);
x64_colorOverrides.resize(16);
}
bool IsFinishedLoading() const; bool IsFinishedLoading() const;
}; };

View File

@ -1,5 +1,7 @@
#include "Runtime/MP1/CInGameGuiManager.hpp" #include "Runtime/MP1/CInGameGuiManager.hpp"
#include <array>
#include "Runtime/CDependencyGroup.hpp" #include "Runtime/CDependencyGroup.hpp"
#include "Runtime/CSimplePool.hpp" #include "Runtime/CSimplePool.hpp"
#include "Runtime/GameGlobalObjects.hpp" #include "Runtime/GameGlobalObjects.hpp"
@ -20,23 +22,26 @@
namespace urde::MP1 { namespace urde::MP1 {
static const char* InGameGuiDGRPs[] = {"InGameGui_DGRP", "Ice_DGRP", "Phazon_DGRP", "Plasma_DGRP", constexpr std::array InGameGuiDGRPs{
"Power_DGRP", "Wave_DGRP", "BallTransition_DGRP", "GravitySuit_DGRP", "InGameGui_DGRP", "Ice_DGRP", "Phazon_DGRP", "Plasma_DGRP", "Power_DGRP", "Wave_DGRP",
"Ice_Anim_DGRP", "Plasma_Anim_DGRP", "PowerSuit_DGRP", "Power_Anim_DGRP", "BallTransition_DGRP", "GravitySuit_DGRP", "Ice_Anim_DGRP", "Plasma_Anim_DGRP", "PowerSuit_DGRP", "Power_Anim_DGRP",
"VariaSuit_DGRP", "Wave_Anim_DGRP"}; "VariaSuit_DGRP", "Wave_Anim_DGRP",
};
static const char* PauseScreenDGRPs[] = { constexpr std::array PauseScreenDGRPs{
"InventorySuitPower_DGRP", "InventorySuitVaria_DGRP", "InventorySuitGravity_DGRP", "InventorySuitPower_DGRP", "InventorySuitVaria_DGRP", "InventorySuitGravity_DGRP",
"InventorySuitPhazon_DGRP", "InventorySuitFusionPower_DGRP", "InventorySuitFusionVaria_DGRP", "InventorySuitPhazon_DGRP", "InventorySuitFusionPower_DGRP", "InventorySuitFusionVaria_DGRP",
"InventorySuitFusionGravity_DGRP", "InventorySuitFusionPhazon_DGRP", "SamusBallANCS_DGRP", "InventorySuitFusionGravity_DGRP", "InventorySuitFusionPhazon_DGRP", "SamusBallANCS_DGRP",
"SamusSpiderBallANCS_DGRP", "PauseScreenDontDump_DGRP", "PauseScreenDontDump_NoARAM_DGRP", "SamusSpiderBallANCS_DGRP", "PauseScreenDontDump_DGRP", "PauseScreenDontDump_NoARAM_DGRP",
"PauseScreenTokens_DGRP"}; "PauseScreenTokens_DGRP",
};
std::vector<TLockedToken<CDependencyGroup>> CInGameGuiManager::LockPauseScreenDependencies() { std::vector<TLockedToken<CDependencyGroup>> CInGameGuiManager::LockPauseScreenDependencies() {
std::vector<TLockedToken<CDependencyGroup>> ret; std::vector<TLockedToken<CDependencyGroup>> ret;
ret.reserve(13); ret.reserve(PauseScreenDGRPs.size());
for (int i = 0; i < 13; ++i) for (const char* const dgrp : PauseScreenDGRPs) {
ret.push_back(g_SimplePool->GetObj(PauseScreenDGRPs[i])); ret.emplace_back(g_SimplePool->GetObj(dgrp));
}
return ret; return ret;
} }
@ -103,8 +108,8 @@ void CInGameGuiManager::DoStateTransition(CStateManager& stateMgr) {
case EInGameGuiState::PauseGame: case EInGameGuiState::PauseGame:
case EInGameGuiState::PauseLogBook: case EInGameGuiState::PauseLogBook:
if (!x48_pauseScreen) { if (!x48_pauseScreen) {
auto pState = stateMgr.GetPlayerState(); const auto& pState = stateMgr.GetPlayerState();
CPlayerState::EPlayerSuit suit = pState->GetCurrentSuitRaw(); const CPlayerState::EPlayerSuit suit = pState->GetCurrentSuitRaw();
int suitResIdx; int suitResIdx;
if (pState->IsFusionEnabled()) { if (pState->IsFusionEnabled()) {
switch (suit) { switch (suit) {
@ -185,9 +190,10 @@ CInGameGuiManager::CInGameGuiManager(CStateManager& stateMgr, CArchitectureQueue
x1f8_25_playerAlive = true; x1f8_25_playerAlive = true;
x1f8_27_exitSaveUI = true; x1f8_27_exitSaveUI = true;
xc8_inGameGuiDGRPs.reserve(14); xc8_inGameGuiDGRPs.reserve(InGameGuiDGRPs.size());
for (int i = 0; i < 14; ++i) for (const char* const dgrp : InGameGuiDGRPs) {
xc8_inGameGuiDGRPs.push_back(g_SimplePool->GetObj(InGameGuiDGRPs[i])); xc8_inGameGuiDGRPs.emplace_back(g_SimplePool->GetObj(dgrp));
}
} }
bool CInGameGuiManager::CheckLoadComplete(CStateManager& stateMgr) { bool CInGameGuiManager::CheckLoadComplete(CStateManager& stateMgr) {
@ -598,18 +604,20 @@ void CInGameGuiManager::Draw(CStateManager& stateMgr) {
float z = 0.5f * (zT * zT * zT * zT * zT * (g_Viewport.xc_height - 12.f) + 12.f); float z = 0.5f * (zT * zT * zT * zT * zT * (g_Viewport.xc_height - 12.f) + 12.f);
float x = 0.5f * (xT * (g_Viewport.x8_width - 12.f) + 12.f); float x = 0.5f * (xT * (g_Viewport.x8_width - 12.f) + 12.f);
CTexturedQuadFilter::Vert verts[] = {{{-x, 0.f, z}, {0.f, 0.f}}, const std::array<CTexturedQuadFilter::Vert, 4> verts{{
{{-x, 0.f, z}, {0.f, 0.f}},
{{-x, 0.f, -z}, {0.f, 1.f}}, {{-x, 0.f, -z}, {0.f, 1.f}},
{{x, 0.f, z}, {1.f, 0.f}}, {{x, 0.f, z}, {1.f, 0.f}},
{{x, 0.f, -z}, {1.f, 1.f}}}; {{x, 0.f, -z}, {1.f, 1.f}},
}};
if (!m_deathRenderTexQuad) if (!m_deathRenderTexQuad)
m_deathRenderTexQuad.emplace(EFilterType::Blend, CGraphics::g_SpareTexture.get()); m_deathRenderTexQuad.emplace(EFilterType::Blend, CGraphics::g_SpareTexture.get());
m_deathRenderTexQuad->drawVerts(zeus::CColor(1.f, colT), verts); m_deathRenderTexQuad->drawVerts(zeus::CColor(1.f, colT), verts.data());
if (!m_deathDotQuad) if (!m_deathDotQuad)
m_deathDotQuad.emplace(EFilterType::Multiply, x50_deathDot); m_deathDotQuad.emplace(EFilterType::Multiply, x50_deathDot);
m_deathDotQuad->drawVerts(zeus::CColor(1.f, colT), verts); m_deathDotQuad->drawVerts(zeus::CColor(1.f, colT), verts.data());
} }
} }
} }

View File

@ -31,12 +31,12 @@ CLogBookScreen::~CLogBookScreen() {
bool CLogBookScreen::IsScanComplete(CSaveWorld::EScanCategory category, CAssetId scan, bool CLogBookScreen::IsScanComplete(CSaveWorld::EScanCategory category, CAssetId scan,
const CPlayerState& playerState) { const CPlayerState& playerState) {
return true; const float time = playerState.GetScanTime(scan);
float time = playerState.GetScanTime(scan); if (category == CSaveWorld::EScanCategory::Artifact) {
if (category == CSaveWorld::EScanCategory::Artifact)
return time >= 0.5f; return time >= 0.5f;
else } else {
return time >= 1.f; return time >= 1.f;
}
} }
void CLogBookScreen::InitializeLogBook() { void CLogBookScreen::InitializeLogBook() {

View File

@ -83,17 +83,22 @@ void CEyeball::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa
CPatterned::AcceptScriptMsg(msg, uid, mgr); CPatterned::AcceptScriptMsg(msg, uid, mgr);
} }
static float kMinAngle = std::cos(zeus::degToRad(45.f));
void CEyeball::Think(float dt, CStateManager& mgr) { void CEyeball::Think(float dt, CStateManager& mgr) {
CPatterned::Think(dt, mgr); CPatterned::Think(dt, mgr);
if (!GetActive())
return;
CPlayer& player = mgr.GetPlayer(); if (!GetActive()) {
zeus::CVector3f direction = (player.GetTranslation() - GetTranslation()).normalized(); return;
}
const CPlayer& player = mgr.GetPlayer();
const zeus::CVector3f direction = (player.GetTranslation() - GetTranslation()).normalized();
// Used to be directly calculated as std::cos(zeus::degToRad(45.f));
// but was converted into the exact constant to avoid unnecessary runtime initialization.
constexpr float minAngle = 0.707106769f;
x60c_25_playerInRange = (player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed && x60c_25_playerInRange = (player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed &&
direction.dot(GetTransform().frontVector()) > kMinAngle); direction.dot(GetTransform().frontVector()) > minAngle);
if (x60c_25_playerInRange) { if (x60c_25_playerInRange) {
x570_boneTracking.SetActive(true); x570_boneTracking.SetActive(true);
@ -102,9 +107,10 @@ void CEyeball::Think(float dt, CStateManager& mgr) {
x570_boneTracking.Update(dt); x570_boneTracking.Update(dt);
GetModelData()->GetAnimationData()->PreRender(); GetModelData()->GetAnimationData()->PreRender();
x570_boneTracking.PreRender(mgr, *GetModelData()->GetAnimationData(), GetTransform(), GetModelData()->GetScale(), x570_boneTracking.PreRender(mgr, *GetModelData()->GetAnimationData(), GetTransform(), GetModelData()->GetScale(),
*x450_bodyController.get()); *x450_bodyController);
} else } else {
x570_boneTracking.SetActive(false); x570_boneTracking.SetActive(false);
}
if (GetActive()) { if (GetActive()) {
CPlasmaProjectile* projectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId)); CPlasmaProjectile* projectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId));

View File

@ -1,5 +1,7 @@
#include "Runtime/MP1/World/CThardus.hpp" #include "Runtime/MP1/World/CThardus.hpp"
#include <array>
#include "Runtime/Camera/CCameraManager.hpp" #include "Runtime/Camera/CCameraManager.hpp"
#include "Runtime/Camera/CFirstPersonCamera.hpp" #include "Runtime/Camera/CFirstPersonCamera.hpp"
#include "Runtime/Collision/CCollisionActor.hpp" #include "Runtime/Collision/CCollisionActor.hpp"
@ -21,9 +23,8 @@
#include <DataSpec/DNAMP1/SFX/IceWorld.h> #include <DataSpec/DNAMP1/SFX/IceWorld.h>
namespace urde::MP1 { namespace urde::MP1 {
namespace { namespace {
constexpr SSphereJointInfo skDamageableSphereJointInfoList1[7] = { constexpr std::array<SSphereJointInfo, 7> skDamageableSphereJointInfoList1{{
{"R_Knee", 1.f}, {"R_Knee", 1.f},
{"R_Elbow_Collision_LCTR", 1.5f}, {"R_Elbow_Collision_LCTR", 1.5f},
{"L_Elbow_Collision_LCTR", 1.5f}, {"L_Elbow_Collision_LCTR", 1.5f},
@ -31,19 +32,22 @@ constexpr SSphereJointInfo skDamageableSphereJointInfoList1[7] = {
{"R_Back_Rock_Collision_LCTR", 2.5f}, {"R_Back_Rock_Collision_LCTR", 2.5f},
{"L_Back_Rock_Collision_LCTR", 1.5f}, {"L_Back_Rock_Collision_LCTR", 1.5f},
{"Head_Collision_LCTR", 1.5f}, {"Head_Collision_LCTR", 1.5f},
}; }};
constexpr SSphereJointInfo skDamageableSphereJointInfoList2[5] = { constexpr std::array<SSphereJointInfo, 5> skDamageableSphereJointInfoList2{{
{"R_Shoulder_Collision_LCTR", 0.75f}, {"L_Shoulder_Collision_LCTR", 0.75f}, {"Spine_Collision_LCTR", 0.75f}, {"R_Shoulder_Collision_LCTR", 0.75f},
{"R_Hand_Collision_LCTR", 2.25f}, {"L_Hand_Collision_LCTR", 2.f}, {"L_Shoulder_Collision_LCTR", 0.75f},
}; {"Spine_Collision_LCTR", 0.75f},
{"R_Hand_Collision_LCTR", 2.25f},
{"L_Hand_Collision_LCTR", 2.f},
}};
constexpr SAABoxJointInfo skFootCollision[2] = { constexpr std::array<SAABoxJointInfo, 2> skFootCollision{{
{"R_Foot_Collision_LCTR", zeus::CVector3f(3.f, 3.f, 1.f)}, {"R_Foot_Collision_LCTR", zeus::CVector3f(3.f, 3.f, 1.f)},
{"L_Foot_Collision_LCTR", zeus::CVector3f(3.f, 2.f, 3.f)}, {"L_Foot_Collision_LCTR", zeus::CVector3f(3.f, 2.f, 3.f)},
}; }};
constexpr std::array<std::string_view, 7> skSearchJointNames = { constexpr std::array skSearchJointNames{
"R_Knee"sv, "R_Knee"sv,
"R_Elbow_Collision_LCTR"sv, "R_Elbow_Collision_LCTR"sv,
"L_Elbow_Collision_LCTR"sv, "L_Elbow_Collision_LCTR"sv,
@ -53,13 +57,14 @@ constexpr std::array<std::string_view, 7> skSearchJointNames = {
"Head_Collision_LCTR"sv, "Head_Collision_LCTR"sv,
}; };
constexpr std::array<std::string_view, 7> skRockJoints = { constexpr std::array skRockJoints{
"R_knee"sv, "R_forearm"sv, "L_elbow"sv, "L_hip"sv, "R_collar_BigRock_SDK"sv, "collar_rock4_SDK"sv, "Neck_1"sv, "R_knee"sv, "R_forearm"sv, "L_elbow"sv, "L_hip"sv, "R_collar_BigRock_SDK"sv, "collar_rock4_SDK"sv, "Neck_1"sv,
}; };
} // namespace } // Anonymous namespace
CThardus::CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CThardus::CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo, CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo,
const std::vector<CStaticRes>& mData1, const std::vector<CStaticRes>& mData2, CAssetId particle1, std::vector<CStaticRes> mData1, std::vector<CStaticRes> mData2, CAssetId particle1,
CAssetId particle2, CAssetId particle3, float f1, float f2, float f3, float f4, float f5, float f6, CAssetId particle2, CAssetId particle3, float f1, float f2, float f3, float f4, float f5, float f6,
CAssetId stateMachine, CAssetId particle4, CAssetId particle5, CAssetId particle6, CAssetId stateMachine, CAssetId particle4, CAssetId particle5, CAssetId particle6,
CAssetId particle7, CAssetId particle8, CAssetId particle9, CAssetId texture, u32 sfxId1, CAssetId particle7, CAssetId particle8, CAssetId particle9, CAssetId texture, u32 sfxId1,
@ -797,7 +802,7 @@ void CThardus::GatherWaypoints(urde::CScriptWaypoint* wp, urde::CStateManager& m
} }
} }
void CThardus::_BuildSphereJointList(const SSphereJointInfo* arr, int count, void CThardus::_BuildSphereJointList(const SSphereJointInfo* arr, size_t count,
std::vector<CJointCollisionDescription>& list) { std::vector<CJointCollisionDescription>& list) {
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
const auto& jInfo = arr[i]; const auto& jInfo = arr[i];
@ -806,7 +811,7 @@ void CThardus::_BuildSphereJointList(const SSphereJointInfo* arr, int count,
} }
} }
void CThardus::_BuildAABoxJointList(const SAABoxJointInfo* arr, int count, void CThardus::_BuildAABoxJointList(const SAABoxJointInfo* arr, size_t count,
std::vector<CJointCollisionDescription>& list) { std::vector<CJointCollisionDescription>& list) {
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
const auto& jInfo = arr[i]; const auto& jInfo = arr[i];
@ -835,16 +840,16 @@ void CThardus::_SetupCollisionActorMaterials(const std::unique_ptr<CCollisionAct
void CThardus::_SetupCollisionManagers(CStateManager& mgr) { void CThardus::_SetupCollisionManagers(CStateManager& mgr) {
std::vector<CJointCollisionDescription> list; std::vector<CJointCollisionDescription> list;
_BuildSphereJointList(skDamageableSphereJointInfoList1, 7, list); _BuildSphereJointList(skDamageableSphereJointInfoList1.data(), skDamageableSphereJointInfoList1.size(), list);
x5f0_rockColliders.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), list, true)); x5f0_rockColliders = std::make_unique<CCollisionActorManager>(mgr, GetUniqueId(), GetAreaIdAlways(), list, true);
_SetupCollisionActorMaterials(x5f0_rockColliders, mgr); _SetupCollisionActorMaterials(x5f0_rockColliders, mgr);
list.clear(); list.clear();
_BuildSphereJointList(skDamageableSphereJointInfoList2, 5, list); _BuildSphereJointList(skDamageableSphereJointInfoList2.data(), skDamageableSphereJointInfoList2.size(), list);
x5f4_.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), list, true)); x5f4_ = std::make_unique<CCollisionActorManager>(mgr, GetUniqueId(), GetAreaIdAlways(), list, true);
_SetupCollisionActorMaterials(x5f4_, mgr); _SetupCollisionActorMaterials(x5f4_, mgr);
list.clear(); list.clear();
_BuildAABoxJointList(skFootCollision, 2, list); _BuildAABoxJointList(skFootCollision.data(), skFootCollision.size(), list);
x5f8_.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), list, true)); x5f8_ = std::make_unique<CCollisionActorManager>(mgr, GetUniqueId(), GetAreaIdAlways(), list, true);
_SetupCollisionActorMaterials(x5f8_, mgr); _SetupCollisionActorMaterials(x5f8_, mgr);
list.clear(); list.clear();
x634_nonDestroyableActors.reserve(x5f4_->GetNumCollisionActors() + x5f0_rockColliders->GetNumCollisionActors() + x634_nonDestroyableActors.reserve(x5f4_->GetNumCollisionActors() + x5f0_rockColliders->GetNumCollisionActors() +

View File

@ -157,8 +157,8 @@ class CThardus : public CPatterned {
EMaterialTypes mat, CStateManager& mgr); EMaterialTypes mat, CStateManager& mgr);
void _SetupCollisionActorMaterials(const std::unique_ptr<CCollisionActorManager>& colMgr, CStateManager& mgr); void _SetupCollisionActorMaterials(const std::unique_ptr<CCollisionActorManager>& colMgr, CStateManager& mgr);
void _SetupCollisionManagers(CStateManager& mgr); void _SetupCollisionManagers(CStateManager& mgr);
void _BuildSphereJointList(const SSphereJointInfo* arr, int count, std::vector<CJointCollisionDescription>& list); void _BuildSphereJointList(const SSphereJointInfo* arr, size_t count, std::vector<CJointCollisionDescription>& list);
void _BuildAABoxJointList(const SAABoxJointInfo* arr, int count, std::vector<CJointCollisionDescription>& list); void _BuildAABoxJointList(const SAABoxJointInfo* arr, size_t count, std::vector<CJointCollisionDescription>& list);
void RenderFlare(const CStateManager& mgr, float t) const; void RenderFlare(const CStateManager& mgr, float t) const;
zeus::CVector3f sub801de550(const CStateManager& mgr) const; zeus::CVector3f sub801de550(const CStateManager& mgr) const;
zeus::CVector3f sub801de434(const CStateManager& mgr) const { return {}; } zeus::CVector3f sub801de434(const CStateManager& mgr) const { return {}; }
@ -169,11 +169,10 @@ public:
DEFINE_PATTERNED(Thardus) DEFINE_PATTERNED(Thardus)
CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo, CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo,
const std::vector<CStaticRes>& mData1, const std::vector<CStaticRes>& mData2, CAssetId particle1, std::vector<CStaticRes> mData1, std::vector<CStaticRes> mData2, CAssetId particle1, CAssetId particle2,
CAssetId particle2, CAssetId particle3, float f1, float f2, float f3, float f4, float f5, float f6, CAssetId particle3, float f1, float f2, float f3, float f4, float f5, float f6, CAssetId stateMachine,
CAssetId stateMachine, CAssetId particle4, CAssetId particle5, CAssetId particle6, CAssetId particle7, CAssetId particle4, CAssetId particle5, CAssetId particle6, CAssetId particle7, CAssetId particle8,
CAssetId particle8, CAssetId particle9, CAssetId texture, u32 sfxId1, CAssetId particle10, u32 sfxId2, CAssetId particle9, CAssetId texture, u32 sfxId1, CAssetId particle10, u32 sfxId2, u32 sfxId3, u32 sfxId4);
u32 sfxId3, u32 sfxId4);
void Think(float dt, CStateManager& mgr) override; void Think(float dt, CStateManager& mgr) override;
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override;

View File

@ -18,9 +18,10 @@ CProjectileInfo::CProjectileInfo(CAssetId proj, const CDamageInfo& dInfo)
zeus::CVector3f CProjectileInfo::PredictInterceptPos(const zeus::CVector3f& gunPos, const zeus::CVector3f& aimPos, zeus::CVector3f CProjectileInfo::PredictInterceptPos(const zeus::CVector3f& gunPos, const zeus::CVector3f& aimPos,
const CPlayer& player, bool gravity, float speed, float dt) { const CPlayer& player, bool gravity, float speed, float dt) {
zeus::CVector3f ret; zeus::CVector3f ret;
zeus::CVector3f playerVel = player.GetDampedClampedVelocityWR(); const zeus::CVector3f playerVel = player.GetDampedClampedVelocityWR();
zeus::CVector3f gravVec(0.f, 0.f, player.GetGravity()); const zeus::CVector3f gravVec(0.f, 0.f, player.GetGravity());
bool result; bool result = false;
switch (player.GetOrbitState()) { switch (player.GetOrbitState()) {
case CPlayer::EPlayerOrbitState::OrbitObject: case CPlayer::EPlayerOrbitState::OrbitObject:
case CPlayer::EPlayerOrbitState::OrbitPoint: case CPlayer::EPlayerOrbitState::OrbitPoint:
@ -33,22 +34,28 @@ zeus::CVector3f CProjectileInfo::PredictInterceptPos(const zeus::CVector3f& gunP
break; break;
} }
zeus::CVector3f vel; zeus::CVector3f vel;
if (playerVel.canBeNormalized()) if (playerVel.canBeNormalized()) {
vel = playerVel.normalized() * player.GetAverageSpeed(); vel = playerVel.normalized() * player.GetAverageSpeed();
else } else {
vel = playerVel; vel = playerVel;
}
result = CSteeringBehaviors::ProjectOrbitalIntersection(gunPos, speed, dt, aimPos, vel, result = CSteeringBehaviors::ProjectOrbitalIntersection(gunPos, speed, dt, aimPos, vel,
player.GetOrbitPoint(), ret); player.GetOrbitPoint(), ret);
break; break;
} }
case CPlayer::EPlayerOrbitState::NoOrbit: case CPlayer::EPlayerOrbitState::NoOrbit:
if (gravity && player.GetPlayerMovementState() == CPlayer::EPlayerMovementState::ApplyJump) if (gravity && player.GetPlayerMovementState() == CPlayer::EPlayerMovementState::ApplyJump) {
result = CSteeringBehaviors::ProjectLinearIntersection(gunPos, speed, aimPos, playerVel, gravVec, ret); result = CSteeringBehaviors::ProjectLinearIntersection(gunPos, speed, aimPos, playerVel, gravVec, ret);
else } else {
result = CSteeringBehaviors::ProjectLinearIntersection(gunPos, speed, aimPos, playerVel, ret); result = CSteeringBehaviors::ProjectLinearIntersection(gunPos, speed, aimPos, playerVel, ret);
} }
if (!result) break;
}
if (!result) {
ret = playerVel * 1.5f + aimPos; ret = playerVel * 1.5f + aimPos;
}
return ret; return ret;
} }

View File

@ -3,8 +3,8 @@
namespace urde { namespace urde {
void CWeaponMgr::Add(TUniqueId uid, EWeaponType type) { void CWeaponMgr::Add(TUniqueId uid, EWeaponType type) {
x0_weapons.insert(std::make_pair(uid, rstl::reserved_vector<s32, 10>())); x0_weapons.insert(std::make_pair(uid, rstl::reserved_vector<s32, 15>()));
x0_weapons[uid].resize(10); x0_weapons[uid].resize(15);
++x0_weapons[uid][u32(type)]; ++x0_weapons[uid][u32(type)];
} }

View File

@ -9,7 +9,7 @@
namespace urde { namespace urde {
class CWeaponMgr { class CWeaponMgr {
std::map<TUniqueId, rstl::reserved_vector<s32, 10>> x0_weapons; std::map<TUniqueId, rstl::reserved_vector<s32, 15>> x0_weapons;
public: public:
void Add(TUniqueId, EWeaponType); void Add(TUniqueId, EWeaponType);

View File

@ -1183,7 +1183,7 @@ void CGameArea::SetAreaAttributes(const CScriptAreaAttributes* areaAttributes) {
x12c_postConstructed->x1128_worldLightingLevel = areaAttributes->GetWorldLightingLevel(); x12c_postConstructed->x1128_worldLightingLevel = areaAttributes->GetWorldLightingLevel();
} }
bool CGameArea::CAreaObjectList::IsQualified(const CEntity& ent) { return (ent.GetAreaIdAlways() == x200c_areaIdx); } bool CGameArea::CAreaObjectList::IsQualified(const CEntity& ent) const { return (ent.GetAreaIdAlways() == x200c_areaIdx); }
void CGameArea::WarmupShaders(const SObjectTag& mreaTag) { void CGameArea::WarmupShaders(const SObjectTag& mreaTag) {
// Calling this version of the constructor performs warmup implicitly // Calling this version of the constructor performs warmup implicitly
CGameArea area(mreaTag.id); CGameArea area(mreaTag.id);

View File

@ -167,7 +167,7 @@ public:
public: public:
CAreaObjectList(TAreaId areaIdx) : CObjectList(EGameObjectList::Invalid), x200c_areaIdx(areaIdx) {} CAreaObjectList(TAreaId areaIdx) : CObjectList(EGameObjectList::Invalid), x200c_areaIdx(areaIdx) {}
bool IsQualified(const CEntity& ent) override; bool IsQualified(const CEntity& ent) const override;
}; };
enum class EOcclusionState { Occluded, Visible }; enum class EOcclusionState { Occluded, Visible };

View File

@ -1688,17 +1688,17 @@ void CPlayer::ProcessInput(const CFinalInput& input, CStateManager& mgr) {
if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphed && x4a0_failsafeTest->Passes()) { if (x2f8_morphBallState == EPlayerMorphBallState::Unmorphed && x4a0_failsafeTest->Passes()) {
auto* prim = static_cast<const CCollidableAABox*>(GetCollisionPrimitive()); auto* prim = static_cast<const CCollidableAABox*>(GetCollisionPrimitive());
zeus::CAABox tmpAABB(prim->GetBox().min - 0.2f, prim->GetBox().max + 0.2f); const zeus::CAABox tmpAABB(prim->GetBox().min - 0.2f, prim->GetBox().max + 0.2f);
CCollidableAABox tmpBox(tmpAABB, prim->GetMaterial()); const CCollidableAABox tmpBox(tmpAABB, prim->GetMaterial());
CPhysicsActor::Stop(); CPhysicsActor::Stop();
zeus::CAABox testBounds = prim->GetBox().getTransformedAABox(x34_transform); const zeus::CAABox testBounds = prim->GetBox().getTransformedAABox(x34_transform);
zeus::CAABox expandedBounds(testBounds.min - 3.f, testBounds.max + 3.f); const zeus::CAABox expandedBounds(testBounds.min - 3.f, testBounds.max + 3.f);
CAreaCollisionCache cache(expandedBounds); CAreaCollisionCache cache(expandedBounds);
CGameCollision::BuildAreaCollisionCache(mgr, cache); CGameCollision::BuildAreaCollisionCache(mgr, cache);
rstl::reserved_vector<TUniqueId, 1024> nearList; rstl::reserved_vector<TUniqueId, 1024> nearList;
mgr.BuildColliderList(nearList, *this, expandedBounds); mgr.BuildColliderList(nearList, *this, expandedBounds);
std::optional<zeus::CVector3f> nonIntVec = const std::optional<zeus::CVector3f> nonIntVec =
CGameCollision::FindNonIntersectingVector(mgr, cache, *this, *prim, nearList); CGameCollision::FindNonIntersectingVector(mgr, cache, *this, tmpBox, nearList);
if (nonIntVec) { if (nonIntVec) {
x4a0_failsafeTest->Reset(); x4a0_failsafeTest->Reset();
SetTranslation(GetTranslation() + *nonIntVec); SetTranslation(GetTranslation() + *nonIntVec);

View File

@ -44,8 +44,8 @@ void CScriptBeam::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CSt
x154_projectileId = mgr.AllocateUniqueId(); x154_projectileId = mgr.AllocateUniqueId();
mgr.AddObject(new CPlasmaProjectile(xe8_weaponDescription, x10_name + "-Projectile", mgr.AddObject(new CPlasmaProjectile(xe8_weaponDescription, x10_name + "-Projectile",
x138_damageInfo.GetWeaponMode().GetType(), xf4_beamInfo, x34_transform, x138_damageInfo.GetWeaponMode().GetType(), xf4_beamInfo, x34_transform,
EMaterialTypes::Projectile, x138_damageInfo, x8_uid, x4_areaId, EMaterialTypes::Projectile, x138_damageInfo, x154_projectileId, x4_areaId,
x154_projectileId, {}, false, EProjectileAttrib::PlasmaProjectile)); GetUniqueId(), {}, false, EProjectileAttrib::PlasmaProjectile));
} else if (msg == EScriptObjectMessage::Deleted) { } else if (msg == EScriptObjectMessage::Deleted) {
mgr.FreeScriptObject(x154_projectileId); mgr.FreeScriptObject(x154_projectileId);
} }

View File

@ -34,13 +34,13 @@ void CScriptCameraHint::InitializeInArea(CStateManager& mgr) {
if (conn.x4_msg != EScriptObjectMessage::Increment && conn.x4_msg != EScriptObjectMessage::Decrement) if (conn.x4_msg != EScriptObjectMessage::Increment && conn.x4_msg != EScriptObjectMessage::Decrement)
continue; continue;
for (auto it = ent->GetConnectionList().begin(); it != ent->GetConnectionList().cend(); ++it) { for (auto it = ent->GetConnectionList().begin(); it != ent->GetConnectionList().end(); ++it) {
const SConnection& conn2 = *it; const SConnection& conn2 = *it;
if (conn2.x4_msg != EScriptObjectMessage::Increment && conn2.x4_msg != EScriptObjectMessage::Decrement) if (conn2.x4_msg != EScriptObjectMessage::Increment && conn2.x4_msg != EScriptObjectMessage::Decrement)
continue; continue;
TUniqueId id = mgr.GetIdForScript(conn2.x8_objId); TUniqueId id = mgr.GetIdForScript(conn2.x8_objId);
if (TCastToPtr<CPathCamera>(mgr.ObjectById(id)) || TCastToPtr<CScriptSpindleCamera>(mgr.ObjectById((id)))) { if (TCastToPtr<CPathCamera>(mgr.ObjectById(id)) || TCastToPtr<CScriptSpindleCamera>(mgr.ObjectById((id)))) {
ent->ConnectionList().erase(it); it = ent->ConnectionList().erase(it);
if (x164_delegatedCamera != id) if (x164_delegatedCamera != id)
x164_delegatedCamera = id; x164_delegatedCamera = id;
break; break;

View File

@ -46,24 +46,23 @@ void CScriptDistanceFog::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId obj
else else
fog->SetFogExplicit(x34_mode, x38_color, x3c_range); fog->SetFogExplicit(x34_mode, x38_color, x3c_range);
} else if (msg == EScriptObjectMessage::Action) { } else if (msg == EScriptObjectMessage::Action) {
if (!x61_nonZero) if (x61_nonZero) {
return;
CGameArea::CAreaFog* fog = stateMgr.GetWorld()->GetArea(x4_areaId)->GetAreaFog(); CGameArea::CAreaFog* fog = stateMgr.GetWorld()->GetArea(x4_areaId)->GetAreaFog();
if (x34_mode == ERglFogMode::None) if (x34_mode == ERglFogMode::None)
fog->RollFogOut(x48_rangeDelta.x(), x44_colorDelta, x38_color); fog->RollFogOut(x48_rangeDelta.x(), x44_colorDelta, x38_color);
else else
fog->FadeFog(x34_mode, x38_color, x3c_range, x44_colorDelta, x48_rangeDelta); fog->FadeFog(x34_mode, x38_color, x3c_range, x44_colorDelta, x48_rangeDelta);
}
if (zeus::close_enough(x54_thermalSpeed, 0.f) && !zeus::close_enough(x5c_xraySpeed, 0.f)) {
CWorld* world = stateMgr.GetWorld();
CGameArea* area = world->GetArea(x4_areaId);
area->SetXRaySpeedAndTarget(x5c_xraySpeed, x58_xrayTarget);
} else {
CWorld* world = stateMgr.GetWorld(); CWorld* world = stateMgr.GetWorld();
CGameArea* area = world->GetArea(x4_areaId); CGameArea* area = world->GetArea(x4_areaId);
if (!zeus::close_enough(x54_thermalSpeed, 0.f)) {
area->SetThermalSpeedAndTarget(x54_thermalSpeed, x50_thermalTarget); area->SetThermalSpeedAndTarget(x54_thermalSpeed, x50_thermalTarget);
} }
if (!zeus::close_enough(x5c_xraySpeed, 0.f)) {
area->SetXRaySpeedAndTarget(x5c_xraySpeed, x58_xrayTarget);
}
} }
} }
} // namespace urde } // namespace urde

View File

@ -46,13 +46,13 @@ void CVisorFlare::Update(float dt, const zeus::CVector3f& pos, const CActor* act
zeus::CVector3f camPos = mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTranslation(); zeus::CVector3f camPos = mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTranslation();
zeus::CVector3f camDiff = pos - camPos; zeus::CVector3f camDiff = pos - camPos;
const float mag = (camDiff.magnitude()); const float mag = (camDiff.magnitude());
rstl::reserved_vector<TUniqueId, 1024> near; rstl::reserved_vector<TUniqueId, 1024> nearVec;
mgr.BuildNearList(near, camPos, camDiff * (1.f / mag), mag, mgr.BuildNearList(nearVec, camPos, camDiff * (1.f / mag), mag,
CMaterialFilter::MakeInclude({EMaterialTypes::Occluder}), act); CMaterialFilter::MakeInclude({EMaterialTypes::Occluder}), act);
TUniqueId id; TUniqueId id;
CRayCastResult result = mgr.RayWorldIntersection( CRayCastResult result = mgr.RayWorldIntersection(
id, camPos, camDiff, mag, id, camPos, camDiff, mag,
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::SeeThrough}), near); CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::SeeThrough}), nearVec);
if (result.IsValid()) { if (result.IsValid()) {
x28_ -= mag; x28_ -= mag;

View File

@ -2574,16 +2574,14 @@ CEntity* ScriptLoader::LoadThardus(CStateManager& mgr, CInputStream& in, int pro
int sfxID2 = in.readUint32Big(); int sfxID2 = in.readUint32Big();
int sfxID3 = in.readUint32Big(); int sfxID3 = in.readUint32Big();
int sfxID4 = in.readUint32Big(); int sfxID4 = in.readUint32Big();
std::vector<CStaticRes> mData1(7); std::vector<CStaticRes> mData1(std::rbegin(staticRes[0]), std::rend(staticRes[0]));
std::vector<CStaticRes> mData2(7); std::vector<CStaticRes> mData2(std::rbegin(staticRes[1]), std::rend(staticRes[1]));
mData1.assign(std::rbegin(staticRes[0]), std::rend(staticRes[0]));
mData2.assign(std::rbegin(staticRes[1]), std::rend(staticRes[1]));
CModelData mData(CAnimRes(animParms.GetACSFile(), 0, actHead.x40_scale, animParms.GetInitialAnimation(), true)); CModelData mData(CAnimRes(animParms.GetACSFile(), 0, actHead.x40_scale, animParms.GetInitialAnimation(), true));
return new MP1::CThardus(mgr.AllocateUniqueId(), actHead.x0_name, info, actHead.x10_transform, std::move(mData), return new MP1::CThardus(mgr.AllocateUniqueId(), actHead.x0_name, info, actHead.x10_transform, std::move(mData),
actParms, pInfo, mData1, mData2, particle1, particle2, particle3, f1, f2, f3, f4, f5, f6, actParms, pInfo, std::move(mData1), std::move(mData2), particle1, particle2, particle3, f1,
stateMachine, particle4, particle5, particle6, particle7, particle8, particle9, texture, f2, f3, f4, f5, f6, stateMachine, particle4, particle5, particle6, particle7, particle8,
sfxID1, particle10, sfxID2, sfxID3, sfxID4); particle9, texture, sfxID1, particle10, sfxID2, sfxID3, sfxID4);
} }
CEntity* ScriptLoader::LoadWallCrawlerSwarm(CStateManager& mgr, CInputStream& in, int propCount, CEntity* ScriptLoader::LoadWallCrawlerSwarm(CStateManager& mgr, CInputStream& in, int propCount,