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 <logvisor/logvisor.hpp>
namespace urde {
namespace {
logvisor::Module Log("urde::CObjectList");
}
CObjectList::CObjectList(EGameObjectList listEnum) : x2004_listEnum(listEnum) {}
void CObjectList::AddObject(CEntity& 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();
s16 prevFirst = x2008_firstId;
prevFirst = x2008_firstId;
}
x2008_firstId = entity.GetUniqueId().Value();
SObjectListEntry& newEnt = x0_list[x2008_firstId];
newEnt.entity = &entity;
@ -91,6 +103,6 @@ CEntity* CObjectList::GetValidObjectById(TUniqueId uid) {
return ent.entity;
}
bool CObjectList::IsQualified(const CEntity&) { return true; }
bool CObjectList::IsQualified(const CEntity&) const { return true; }
} // namespace urde

View File

@ -80,7 +80,7 @@ public:
CEntity* GetValidObjectById(TUniqueId uid);
s16 GetFirstObjectIndex() const { return x2008_firstId; }
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; }
};

View File

@ -7,7 +7,8 @@ namespace urde {
static logvisor::Module Log("CResFactory");
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) {

View File

@ -97,14 +97,14 @@ private:
std::unique_ptr<CAiWaypointList> x83c_aiWaypointObjs;
std::unique_ptr<CPlatformAndDoorList> x844_platformAndDoorObjs;
*/
std::unique_ptr<CObjectList> x808_objLists[8] = {std::make_unique<CObjectList>(EGameObjectList::All),
std::make_unique<CActorList>(),
std::make_unique<CPhysicsActorList>(),
std::make_unique<CGameCameraList>(),
std::make_unique<CGameLightList>(),
std::make_unique<CListeningAiList>(),
std::make_unique<CAiWaypointList>(),
std::make_unique<CPlatformAndDoorList>()};
std::array<std::unique_ptr<CObjectList>, 8> x808_objLists = {std::make_unique<CObjectList>(EGameObjectList::All),
std::make_unique<CActorList>(),
std::make_unique<CPhysicsActorList>(),
std::make_unique<CGameCameraList>(),
std::make_unique<CGameLightList>(),
std::make_unique<CListeningAiList>(),
std::make_unique<CAiWaypointList>(),
std::make_unique<CPlatformAndDoorList>()};
std::unique_ptr<CPlayer> x84c_player;
std::unique_ptr<CWorld> x850_world;

View File

@ -74,7 +74,9 @@ class CToken {
public:
/* 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 Lock();
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);
break;
case 2:
UpdateColliders(xf, x284_largeColliders, x2d8_largeColliderIt, 4, 4.f, nearList, dt, mgr);
break;
case 3:
UpdateColliders(xf, x284_largeColliders, x2d8_largeColliderIt, 4, 4.f, nearList, dt, mgr);
break;

View File

@ -10,7 +10,7 @@ namespace urde {
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(); }

View File

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

View File

@ -75,7 +75,7 @@ public:
CCharAnimTime GetAnimationDuration() const { return MainHeader().duration; }
float GetAverageVelocity() const { return x10_averageVelocity; }
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<CInt32POINode>& GetInt32POIStream() const { return x8_evntToken->GetInt32POIStream(); }
const std::vector<CParticlePOINode>& GetParticlePOIStream() const { return x8_evntToken->GetParticlePOIStream(); }

View File

@ -38,7 +38,7 @@ class CHierarchyPoseBuilder {
public:
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; }
void BuildTransform(const CSegId& boneId, zeus::CTransform& xfOut) const;
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) {
x0_bone = segId;
auto info = animData.GetPoseBuilder().CharLayoutInfo();
const auto& info = animData.GetPoseBuilder().CharLayoutInfo();
x1_p1 = info->GetRootNode()->GetBoneMap()[x0_bone].x0_parentId;
if (x1_p1 != 2) {
x2_p2 = info->GetRootNode()->GetBoneMap()[x1_p1].x0_parentId;

View File

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

View File

@ -106,6 +106,6 @@ public:
TUniqueId GetLightId() const override;
void DeleteLight(CStateManager& mgr) 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

View File

@ -14,39 +14,39 @@ namespace urde {
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) {}
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) {}
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) {}
bool CListeningAiList::IsQualified(const CEntity& ent) {
TCastToConstPtr<CAi> ai(ent);
bool CListeningAiList::IsQualified(const CEntity& ent) const {
const TCastToConstPtr<CAi> ai(ent);
return ai && ai->IsListening();
}
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);
}
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) {}
bool CGameLightList::IsQualified(const CEntity& lt) { return TCastToConstPtr<CGameLight>(lt); }
bool CGameLightList::IsQualified(const CEntity& lt) const { return TCastToConstPtr<CGameLight>(lt); }
} // namespace urde

View File

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

View File

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

View File

@ -38,27 +38,7 @@ class CTexture;
class IFactory;
class IObjectStore;
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();
};
class Buckets;
enum class EWorldShadowMode {
None,
@ -196,10 +176,10 @@ class CBooRenderer final : public IRenderer {
void ActivateLightsForModel(CAreaListItem* item, CBooModel& model);
void RenderBucketItems(CAreaListItem* item);
void HandleUnsortedModel(CAreaListItem* item, CBooModel& model, const CModelFlags& flags);
static void CalcDrawFogFan(const zeus::CPlane* planes, int numPlanes, const zeus::CVector3f* verts, int numVerts,
int iteration, int level, CFogVolumePlaneShader& fogVol);
static void DrawFogSlices(const zeus::CPlane* planes, int numPlanes, int iteration, const zeus::CVector3f& center,
float delta, CFogVolumePlaneShader& fogVol);
static void CalcDrawFogFan(const zeus::CPlane* planes, size_t numPlanes, const zeus::CVector3f* verts,
size_t numVerts, size_t iteration, size_t level, CFogVolumePlaneShader& fogVol);
static void DrawFogSlices(const zeus::CPlane* planes, size_t numPlanes, size_t iteration,
const zeus::CVector3f& center, float delta, CFogVolumePlaneShader& fogVol);
static void RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model, const zeus::CTransform& modelMtx,
const zeus::CTransform& viewMtx, const CSkinnedModel* sModel, int pass,
CFogVolumePlaneShader* fvs);

View File

@ -18,10 +18,32 @@
#include <logvisor/logvisor.hpp>
namespace urde {
static logvisor::Module Log("urde::CBooModel");
bool CBooModel::g_DrawingOccluders = false;
namespace {
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() {
g_shadowMap.reset();
@ -59,12 +81,6 @@ bool CBooModel::g_RenderModelBlack = false;
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,
float& alphaOut) {
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();
extendeds.reserve(pipelines->size());
int idx = 0;
EExtendedShader idx{};
for (const auto& pipeline : *pipelines) {
if (idx == EExtendedShader::Thermal) {
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,
m_staticIbo.get(), 4, bufs, stages, thisOffs, thisSizes, 12, texs,
nullptr, nullptr));
++idx;
idx = EExtendedShader(size_t(idx) + 1);
}
}
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];
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::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);
}
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,
const CBooModel* parent) {
u8* start = bufOut;

View File

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

View File

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

View File

@ -21,7 +21,7 @@ class ShaderTag;
namespace urde {
class CLight;
enum EExtendedShader : uint8_t {
enum class EExtendedShader : uint8_t {
Flat,
Lighting,
Thermal,
@ -96,7 +96,7 @@ public:
static void Initialize();
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 Material = DataSpec::DNAMP1::HMDLMaterialSet::Material;

View File

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

View File

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

View File

@ -1,5 +1,7 @@
#include "Runtime/MP1/CInGameGuiManager.hpp"
#include <array>
#include "Runtime/CDependencyGroup.hpp"
#include "Runtime/CSimplePool.hpp"
#include "Runtime/GameGlobalObjects.hpp"
@ -20,23 +22,26 @@
namespace urde::MP1 {
static const char* InGameGuiDGRPs[] = {"InGameGui_DGRP", "Ice_DGRP", "Phazon_DGRP", "Plasma_DGRP",
"Power_DGRP", "Wave_DGRP", "BallTransition_DGRP", "GravitySuit_DGRP",
"Ice_Anim_DGRP", "Plasma_Anim_DGRP", "PowerSuit_DGRP", "Power_Anim_DGRP",
"VariaSuit_DGRP", "Wave_Anim_DGRP"};
constexpr std::array InGameGuiDGRPs{
"InGameGui_DGRP", "Ice_DGRP", "Phazon_DGRP", "Plasma_DGRP", "Power_DGRP", "Wave_DGRP",
"BallTransition_DGRP", "GravitySuit_DGRP", "Ice_Anim_DGRP", "Plasma_Anim_DGRP", "PowerSuit_DGRP", "Power_Anim_DGRP",
"VariaSuit_DGRP", "Wave_Anim_DGRP",
};
static const char* PauseScreenDGRPs[] = {
constexpr std::array PauseScreenDGRPs{
"InventorySuitPower_DGRP", "InventorySuitVaria_DGRP", "InventorySuitGravity_DGRP",
"InventorySuitPhazon_DGRP", "InventorySuitFusionPower_DGRP", "InventorySuitFusionVaria_DGRP",
"InventorySuitFusionGravity_DGRP", "InventorySuitFusionPhazon_DGRP", "SamusBallANCS_DGRP",
"SamusSpiderBallANCS_DGRP", "PauseScreenDontDump_DGRP", "PauseScreenDontDump_NoARAM_DGRP",
"PauseScreenTokens_DGRP"};
"PauseScreenTokens_DGRP",
};
std::vector<TLockedToken<CDependencyGroup>> CInGameGuiManager::LockPauseScreenDependencies() {
std::vector<TLockedToken<CDependencyGroup>> ret;
ret.reserve(13);
for (int i = 0; i < 13; ++i)
ret.push_back(g_SimplePool->GetObj(PauseScreenDGRPs[i]));
ret.reserve(PauseScreenDGRPs.size());
for (const char* const dgrp : PauseScreenDGRPs) {
ret.emplace_back(g_SimplePool->GetObj(dgrp));
}
return ret;
}
@ -103,8 +108,8 @@ void CInGameGuiManager::DoStateTransition(CStateManager& stateMgr) {
case EInGameGuiState::PauseGame:
case EInGameGuiState::PauseLogBook:
if (!x48_pauseScreen) {
auto pState = stateMgr.GetPlayerState();
CPlayerState::EPlayerSuit suit = pState->GetCurrentSuitRaw();
const auto& pState = stateMgr.GetPlayerState();
const CPlayerState::EPlayerSuit suit = pState->GetCurrentSuitRaw();
int suitResIdx;
if (pState->IsFusionEnabled()) {
switch (suit) {
@ -185,9 +190,10 @@ CInGameGuiManager::CInGameGuiManager(CStateManager& stateMgr, CArchitectureQueue
x1f8_25_playerAlive = true;
x1f8_27_exitSaveUI = true;
xc8_inGameGuiDGRPs.reserve(14);
for (int i = 0; i < 14; ++i)
xc8_inGameGuiDGRPs.push_back(g_SimplePool->GetObj(InGameGuiDGRPs[i]));
xc8_inGameGuiDGRPs.reserve(InGameGuiDGRPs.size());
for (const char* const dgrp : InGameGuiDGRPs) {
xc8_inGameGuiDGRPs.emplace_back(g_SimplePool->GetObj(dgrp));
}
}
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 x = 0.5f * (xT * (g_Viewport.x8_width - 12.f) + 12.f);
CTexturedQuadFilter::Vert verts[] = {{{-x, 0.f, z}, {0.f, 0.f}},
{{-x, 0.f, -z}, {0.f, 1.f}},
{{x, 0.f, z}, {1.f, 0.f}},
{{x, 0.f, -z}, {1.f, 1.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}, {1.f, 0.f}},
{{x, 0.f, -z}, {1.f, 1.f}},
}};
if (!m_deathRenderTexQuad)
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)
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,
const CPlayerState& playerState) {
return true;
float time = playerState.GetScanTime(scan);
if (category == CSaveWorld::EScanCategory::Artifact)
const float time = playerState.GetScanTime(scan);
if (category == CSaveWorld::EScanCategory::Artifact) {
return time >= 0.5f;
else
} else {
return time >= 1.f;
}
}
void CLogBookScreen::InitializeLogBook() {

View File

@ -83,17 +83,22 @@ void CEyeball::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa
CPatterned::AcceptScriptMsg(msg, uid, mgr);
}
static float kMinAngle = std::cos(zeus::degToRad(45.f));
void CEyeball::Think(float dt, CStateManager& mgr) {
CPatterned::Think(dt, mgr);
if (!GetActive())
return;
CPlayer& player = mgr.GetPlayer();
zeus::CVector3f direction = (player.GetTranslation() - GetTranslation()).normalized();
if (!GetActive()) {
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 &&
direction.dot(GetTransform().frontVector()) > kMinAngle);
direction.dot(GetTransform().frontVector()) > minAngle);
if (x60c_25_playerInRange) {
x570_boneTracking.SetActive(true);
@ -102,9 +107,10 @@ void CEyeball::Think(float dt, CStateManager& mgr) {
x570_boneTracking.Update(dt);
GetModelData()->GetAnimationData()->PreRender();
x570_boneTracking.PreRender(mgr, *GetModelData()->GetAnimationData(), GetTransform(), GetModelData()->GetScale(),
*x450_bodyController.get());
} else
*x450_bodyController);
} else {
x570_boneTracking.SetActive(false);
}
if (GetActive()) {
CPlasmaProjectile* projectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId));

View File

@ -1,5 +1,7 @@
#include "Runtime/MP1/World/CThardus.hpp"
#include <array>
#include "Runtime/Camera/CCameraManager.hpp"
#include "Runtime/Camera/CFirstPersonCamera.hpp"
#include "Runtime/Collision/CCollisionActor.hpp"
@ -21,9 +23,8 @@
#include <DataSpec/DNAMP1/SFX/IceWorld.h>
namespace urde::MP1 {
namespace {
constexpr SSphereJointInfo skDamageableSphereJointInfoList1[7] = {
constexpr std::array<SSphereJointInfo, 7> skDamageableSphereJointInfoList1{{
{"R_Knee", 1.f},
{"R_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},
{"L_Back_Rock_Collision_LCTR", 1.5f},
{"Head_Collision_LCTR", 1.5f},
};
}};
constexpr SSphereJointInfo skDamageableSphereJointInfoList2[5] = {
{"R_Shoulder_Collision_LCTR", 0.75f}, {"L_Shoulder_Collision_LCTR", 0.75f}, {"Spine_Collision_LCTR", 0.75f},
{"R_Hand_Collision_LCTR", 2.25f}, {"L_Hand_Collision_LCTR", 2.f},
};
constexpr std::array<SSphereJointInfo, 5> skDamageableSphereJointInfoList2{{
{"R_Shoulder_Collision_LCTR", 0.75f},
{"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)},
{"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_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,
};
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,
};
} // namespace
} // Anonymous namespace
CThardus::CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
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 stateMachine, CAssetId particle4, CAssetId particle5, CAssetId particle6,
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) {
for (size_t i = 0; i < count; ++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) {
for (size_t i = 0; i < count; ++i) {
const auto& jInfo = arr[i];
@ -835,16 +840,16 @@ void CThardus::_SetupCollisionActorMaterials(const std::unique_ptr<CCollisionAct
void CThardus::_SetupCollisionManagers(CStateManager& mgr) {
std::vector<CJointCollisionDescription> list;
_BuildSphereJointList(skDamageableSphereJointInfoList1, 7, list);
x5f0_rockColliders.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), list, true));
_BuildSphereJointList(skDamageableSphereJointInfoList1.data(), skDamageableSphereJointInfoList1.size(), list);
x5f0_rockColliders = std::make_unique<CCollisionActorManager>(mgr, GetUniqueId(), GetAreaIdAlways(), list, true);
_SetupCollisionActorMaterials(x5f0_rockColliders, mgr);
list.clear();
_BuildSphereJointList(skDamageableSphereJointInfoList2, 5, list);
x5f4_.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), list, true));
_BuildSphereJointList(skDamageableSphereJointInfoList2.data(), skDamageableSphereJointInfoList2.size(), list);
x5f4_ = std::make_unique<CCollisionActorManager>(mgr, GetUniqueId(), GetAreaIdAlways(), list, true);
_SetupCollisionActorMaterials(x5f4_, mgr);
list.clear();
_BuildAABoxJointList(skFootCollision, 2, list);
x5f8_.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), list, true));
_BuildAABoxJointList(skFootCollision.data(), skFootCollision.size(), list);
x5f8_ = std::make_unique<CCollisionActorManager>(mgr, GetUniqueId(), GetAreaIdAlways(), list, true);
_SetupCollisionActorMaterials(x5f8_, mgr);
list.clear();
x634_nonDestroyableActors.reserve(x5f4_->GetNumCollisionActors() + x5f0_rockColliders->GetNumCollisionActors() +

View File

@ -157,8 +157,8 @@ class CThardus : public CPatterned {
EMaterialTypes mat, CStateManager& mgr);
void _SetupCollisionActorMaterials(const std::unique_ptr<CCollisionActorManager>& colMgr, CStateManager& mgr);
void _SetupCollisionManagers(CStateManager& mgr);
void _BuildSphereJointList(const SSphereJointInfo* arr, int count, std::vector<CJointCollisionDescription>& list);
void _BuildAABoxJointList(const SAABoxJointInfo* arr, int count, std::vector<CJointCollisionDescription>& list);
void _BuildSphereJointList(const SSphereJointInfo* arr, size_t 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;
zeus::CVector3f sub801de550(const CStateManager& mgr) const;
zeus::CVector3f sub801de434(const CStateManager& mgr) const { return {}; }
@ -169,11 +169,10 @@ public:
DEFINE_PATTERNED(Thardus)
CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo,
const std::vector<CStaticRes>& mData1, const std::vector<CStaticRes>& mData2, CAssetId particle1,
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 particle7,
CAssetId particle8, CAssetId particle9, CAssetId texture, u32 sfxId1, CAssetId particle10, u32 sfxId2,
u32 sfxId3, u32 sfxId4);
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 stateMachine,
CAssetId particle4, CAssetId particle5, CAssetId particle6, CAssetId particle7, CAssetId particle8,
CAssetId particle9, CAssetId texture, u32 sfxId1, CAssetId particle10, u32 sfxId2, u32 sfxId3, u32 sfxId4);
void Think(float dt, 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,
const CPlayer& player, bool gravity, float speed, float dt) {
zeus::CVector3f ret;
zeus::CVector3f playerVel = player.GetDampedClampedVelocityWR();
zeus::CVector3f gravVec(0.f, 0.f, player.GetGravity());
bool result;
const zeus::CVector3f playerVel = player.GetDampedClampedVelocityWR();
const zeus::CVector3f gravVec(0.f, 0.f, player.GetGravity());
bool result = false;
switch (player.GetOrbitState()) {
case CPlayer::EPlayerOrbitState::OrbitObject:
case CPlayer::EPlayerOrbitState::OrbitPoint:
@ -33,22 +34,28 @@ zeus::CVector3f CProjectileInfo::PredictInterceptPos(const zeus::CVector3f& gunP
break;
}
zeus::CVector3f vel;
if (playerVel.canBeNormalized())
if (playerVel.canBeNormalized()) {
vel = playerVel.normalized() * player.GetAverageSpeed();
else
} else {
vel = playerVel;
}
result = CSteeringBehaviors::ProjectOrbitalIntersection(gunPos, speed, dt, aimPos, vel,
player.GetOrbitPoint(), ret);
break;
}
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);
else
} else {
result = CSteeringBehaviors::ProjectLinearIntersection(gunPos, speed, aimPos, playerVel, ret);
}
break;
}
if (!result)
if (!result) {
ret = playerVel * 1.5f + aimPos;
}
return ret;
}

View File

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

View File

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

View File

@ -1183,7 +1183,7 @@ void CGameArea::SetAreaAttributes(const CScriptAreaAttributes* areaAttributes) {
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) {
// Calling this version of the constructor performs warmup implicitly
CGameArea area(mreaTag.id);

View File

@ -167,7 +167,7 @@ public:
public:
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 };

View File

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

View File

@ -44,8 +44,8 @@ void CScriptBeam::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CSt
x154_projectileId = mgr.AllocateUniqueId();
mgr.AddObject(new CPlasmaProjectile(xe8_weaponDescription, x10_name + "-Projectile",
x138_damageInfo.GetWeaponMode().GetType(), xf4_beamInfo, x34_transform,
EMaterialTypes::Projectile, x138_damageInfo, x8_uid, x4_areaId,
x154_projectileId, {}, false, EProjectileAttrib::PlasmaProjectile));
EMaterialTypes::Projectile, x138_damageInfo, x154_projectileId, x4_areaId,
GetUniqueId(), {}, false, EProjectileAttrib::PlasmaProjectile));
} else if (msg == EScriptObjectMessage::Deleted) {
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)
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;
if (conn2.x4_msg != EScriptObjectMessage::Increment && conn2.x4_msg != EScriptObjectMessage::Decrement)
continue;
TUniqueId id = mgr.GetIdForScript(conn2.x8_objId);
if (TCastToPtr<CPathCamera>(mgr.ObjectById(id)) || TCastToPtr<CScriptSpindleCamera>(mgr.ObjectById((id)))) {
ent->ConnectionList().erase(it);
it = ent->ConnectionList().erase(it);
if (x164_delegatedCamera != id)
x164_delegatedCamera = id;
break;

View File

@ -46,24 +46,23 @@ void CScriptDistanceFog::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId obj
else
fog->SetFogExplicit(x34_mode, x38_color, x3c_range);
} else if (msg == EScriptObjectMessage::Action) {
if (!x61_nonZero)
return;
if (x61_nonZero) {
CGameArea::CAreaFog* fog = stateMgr.GetWorld()->GetArea(x4_areaId)->GetAreaFog();
if (x34_mode == ERglFogMode::None)
fog->RollFogOut(x48_rangeDelta.x(), x44_colorDelta, x38_color);
else
fog->FadeFog(x34_mode, x38_color, x3c_range, x44_colorDelta, x48_rangeDelta);
}
CGameArea::CAreaFog* fog = stateMgr.GetWorld()->GetArea(x4_areaId)->GetAreaFog();
if (x34_mode == ERglFogMode::None)
fog->RollFogOut(x48_rangeDelta.x(), x44_colorDelta, x38_color);
else
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();
CGameArea* area = world->GetArea(x4_areaId);
CWorld* world = stateMgr.GetWorld();
CGameArea* area = world->GetArea(x4_areaId);
if (!zeus::close_enough(x54_thermalSpeed, 0.f)) {
area->SetThermalSpeedAndTarget(x54_thermalSpeed, x50_thermalTarget);
}
if (!zeus::close_enough(x5c_xraySpeed, 0.f)) {
area->SetXRaySpeedAndTarget(x5c_xraySpeed, x58_xrayTarget);
}
}
}
} // 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 camDiff = pos - camPos;
const float mag = (camDiff.magnitude());
rstl::reserved_vector<TUniqueId, 1024> near;
mgr.BuildNearList(near, camPos, camDiff * (1.f / mag), mag,
rstl::reserved_vector<TUniqueId, 1024> nearVec;
mgr.BuildNearList(nearVec, camPos, camDiff * (1.f / mag), mag,
CMaterialFilter::MakeInclude({EMaterialTypes::Occluder}), act);
TUniqueId id;
CRayCastResult result = mgr.RayWorldIntersection(
id, camPos, camDiff, mag,
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::SeeThrough}), near);
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::SeeThrough}), nearVec);
if (result.IsValid()) {
x28_ -= mag;

View File

@ -2574,16 +2574,14 @@ CEntity* ScriptLoader::LoadThardus(CStateManager& mgr, CInputStream& in, int pro
int sfxID2 = in.readUint32Big();
int sfxID3 = in.readUint32Big();
int sfxID4 = in.readUint32Big();
std::vector<CStaticRes> mData1(7);
std::vector<CStaticRes> mData2(7);
mData1.assign(std::rbegin(staticRes[0]), std::rend(staticRes[0]));
mData2.assign(std::rbegin(staticRes[1]), std::rend(staticRes[1]));
std::vector<CStaticRes> mData1(std::rbegin(staticRes[0]), std::rend(staticRes[0]));
std::vector<CStaticRes> mData2(std::rbegin(staticRes[1]), std::rend(staticRes[1]));
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),
actParms, pInfo, mData1, mData2, particle1, particle2, particle3, f1, f2, f3, f4, f5, f6,
stateMachine, particle4, particle5, particle6, particle7, particle8, particle9, texture,
sfxID1, particle10, sfxID2, sfxID3, sfxID4);
actParms, pInfo, std::move(mData1), std::move(mData2), particle1, particle2, particle3, f1,
f2, f3, f4, f5, f6, stateMachine, particle4, particle5, particle6, particle7, particle8,
particle9, texture, sfxID1, particle10, sfxID2, sfxID3, sfxID4);
}
CEntity* ScriptLoader::LoadWallCrawlerSwarm(CStateManager& mgr, CInputStream& in, int propCount,