diff --git a/Runtime/Camera/CCinematicCamera.cpp b/Runtime/Camera/CCinematicCamera.cpp index ebd7e85f3..de126b43b 100644 --- a/Runtime/Camera/CCinematicCamera.cpp +++ b/Runtime/Camera/CCinematicCamera.cpp @@ -250,9 +250,9 @@ void CCinematicCamera::CalculateMoveOutofIntoEyePosition(bool outOfEye, CStateMa if (const CModelData* mData = act->GetModelData()) { if (const CAnimData* aData = mData->GetAnimationData()) { if (const CAnimTreeNode* root = aData->GetRootAnimationTree().get()) { - CSegId lEye = aData->GetLocatorSegId("L_eye"sv); - CSegId rEye = aData->GetLocatorSegId("R_eye"sv); - if (lEye != 0xff && rEye != 0xff) { + const CSegId lEye = aData->GetLocatorSegId("L_eye"sv); + const CSegId rEye = aData->GetLocatorSegId("R_eye"sv); + if (lEye.IsValid() && rEye.IsValid()) { CCharAnimTime time = outOfEye ? CCharAnimTime(0.f) : root->VGetSteadyStateAnimInfo().GetDuration(); CCharAnimTime* pTime = outOfEye ? nullptr : &time; eyePos = ((act->GetTransform() * mData->GetScaledLocatorTransformDynamic("L_eye"sv, pTime)).origin + diff --git a/Runtime/Character/CAnimData.cpp b/Runtime/Character/CAnimData.cpp index 7dd26868e..3dddc53db 100644 --- a/Runtime/Character/CAnimData.cpp +++ b/Runtime/Character/CAnimData.cpp @@ -434,8 +434,9 @@ void CAnimData::CalcPlaybackAlignmentParms(const CAnimPlaybackParms& parms, } zeus::CTransform CAnimData::GetLocatorTransform(CSegId id, const CCharAnimTime* time) const { - if (id == 0xFF) + if (id.IsInvalid()) { return {}; + } zeus::CTransform ret; if (time || !x220_31_poseCached) { diff --git a/Runtime/Character/CParticleDatabase.cpp b/Runtime/Character/CParticleDatabase.cpp index 2ad112c4d..18b81356c 100644 --- a/Runtime/Character/CParticleDatabase.cpp +++ b/Runtime/Character/CParticleDatabase.cpp @@ -92,8 +92,8 @@ void CParticleDatabase::UpdateParticleGenDB(float dt, const CPoseAsTransforms& p CParticleGenInfo& info = *it->second; if (info.GetIsActive()) { if (info.GetType() == EParticleGenType::Normal) { - CSegId segId = charInfo.GetSegIdFromString(info.GetLocatorName()); - if (segId == 0xff) { + const CSegId segId = charInfo.GetSegIdFromString(info.GetLocatorName()); + if (segId.IsInvalid()) { ++it; continue; } diff --git a/Runtime/Character/CPoseAsTransforms.cpp b/Runtime/Character/CPoseAsTransforms.cpp index 35083b2d6..c72e1617c 100644 --- a/Runtime/Character/CPoseAsTransforms.cpp +++ b/Runtime/Character/CPoseAsTransforms.cpp @@ -7,7 +7,7 @@ CPoseAsTransforms::CPoseAsTransforms(u8 boneCount) : x1_count(boneCount), xd0_tr bool CPoseAsTransforms::ContainsDataFor(const CSegId& id) const { const std::pair& link = x8_links[id]; - return link.first != 0xff || link.second != 0xff; + return link.first.IsValid() || link.second.IsValid(); } void CPoseAsTransforms::Clear() { @@ -23,25 +23,25 @@ void CPoseAsTransforms::AccumulateScaledTransform(const CSegId& id, zeus::CMatri const zeus::CTransform& CPoseAsTransforms::GetTransform(const CSegId& id) const { const std::pair& link = x8_links[id]; - assert(link.second != 0xff); + assert(link.second.IsValid()); return xd0_transformArr[link.second].m_originToAccum; } const zeus::CTransform& CPoseAsTransforms::GetRestToAccumTransform(const CSegId& id) const { const std::pair& link = x8_links[id]; - assert(link.second != 0xff); + assert(link.second.IsValid()); return xd0_transformArr[link.second].m_restPoseToAccum; } const zeus::CVector3f& CPoseAsTransforms::GetOffset(const CSegId& id) const { const std::pair& link = x8_links[id]; - assert(link.second != 0xff); + assert(link.second.IsValid()); return xd0_transformArr[link.second].m_originToAccum.origin; } const zeus::CMatrix3f& CPoseAsTransforms::GetRotation(const CSegId& id) const { const std::pair& link = x8_links[id]; - assert(link.second != 0xff); + assert(link.second.IsValid()); return xd0_transformArr[link.second].m_originToAccum.basis; } diff --git a/Runtime/Character/CRagDoll.cpp b/Runtime/Character/CRagDoll.cpp index 333c22dcc..f0be7fd36 100644 --- a/Runtime/Character/CRagDoll.cpp +++ b/Runtime/Character/CRagDoll.cpp @@ -307,12 +307,15 @@ void CRagDoll::Prime(CStateManager& mgr, const zeus::CTransform& xf, CModelData& zeus::CVector3f scale = mData.GetScale(); CAnimData* aData = mData.GetAnimationData(); aData->BuildPose(); - for (auto& particle : x4_particles) - if (particle.x0_id != 0xff) + for (auto& particle : x4_particles) { + if (particle.x0_id.IsValid()) { particle.x4_curPos = xf * (aData->GetPose().GetOffset(particle.x0_id) * scale); + } + } SatisfyWorldConstraints(mgr, 2); - for (auto& particle : x4_particles) + for (auto& particle : x4_particles) { particle.x3c_24_impactPending = false; + } x68_26_primed = true; } diff --git a/Runtime/Character/CSegId.hpp b/Runtime/Character/CSegId.hpp index e351b7abd..7a930b3ff 100644 --- a/Runtime/Character/CSegId.hpp +++ b/Runtime/Character/CSegId.hpp @@ -3,26 +3,27 @@ #include "Runtime/IOStreams.hpp" #include "Runtime/RetroTypes.hpp" -#include - namespace urde { class CSegId { - u8 x0_segId = 0xff; + u8 x0_segId = 0xFF; public: - CSegId() = default; - CSegId(u8 id) : x0_segId(id) {} - CSegId(CInputStream& in) : x0_segId(in.readUint32Big()) {} - CSegId& operator++() { + constexpr CSegId() noexcept = default; + constexpr CSegId(u8 id) noexcept : x0_segId(id) {} + explicit CSegId(CInputStream& in) : x0_segId(in.readUint32Big()) {} + constexpr CSegId& operator++() noexcept { ++x0_segId; return *this; } - CSegId& operator--() { + constexpr CSegId& operator--() noexcept { --x0_segId; return *this; } - operator u8() const { return x0_segId; } + constexpr operator u8() const noexcept { return x0_segId; } + + constexpr bool IsValid() const noexcept { return !IsInvalid(); } + constexpr bool IsInvalid() const noexcept { return x0_segId == 0xFF; } }; } // namespace urde diff --git a/Runtime/Character/TSegIdMap.hpp b/Runtime/Character/TSegIdMap.hpp index af333b9a5..bcef067be 100644 --- a/Runtime/Character/TSegIdMap.hpp +++ b/Runtime/Character/TSegIdMap.hpp @@ -19,43 +19,55 @@ class TSegIdMap { public: TSegIdMap(const CSegId& capacity) : x1_capacity(capacity), xd0_bones(new T[capacity]) {} + T& operator[](const CSegId& id) { return SetElement(id); } const T& operator[](const CSegId& id) const { return xd0_bones[x8_indirectionMap[id].second]; } + T& SetElement(const CSegId& id, T&& obj) { size_t idx; - if (x8_indirectionMap[id].first == 0xff) { - x8_indirectionMap[id].first = xd4_curPrevBone; - x8_indirectionMap[id].second = x0_boneCount; + + if (HasElement(id)) { + idx = x8_indirectionMap[id].second; + } else { + x8_indirectionMap[id] = std::make_pair(xd4_curPrevBone, x0_boneCount); xd4_curPrevBone = id; idx = x0_boneCount; ++x0_boneCount; - } else - idx = x8_indirectionMap[id].second; + } + xd0_bones[idx] = std::move(obj); return xd0_bones[idx]; } + T& SetElement(const CSegId& id) { size_t idx; - if (x8_indirectionMap[id].first == 0xff) { - x8_indirectionMap[id].first = xd4_curPrevBone; - x8_indirectionMap[id].second = x0_boneCount; + + if (HasElement(id)) { + idx = x8_indirectionMap[id].second; + } else { + x8_indirectionMap[id] = std::make_pair(xd4_curPrevBone, x0_boneCount); xd4_curPrevBone = id; idx = x0_boneCount; ++x0_boneCount; - } else - idx = x8_indirectionMap[id].second; + } + return xd0_bones[idx]; } + void DelElement(const CSegId& id) { - if (x8_indirectionMap[id].first != 0xff) { - if (id == xd4_curPrevBone) - xd4_curPrevBone = x8_indirectionMap[id].first; - x8_indirectionMap[id].first = 0xff; - x8_indirectionMap[id].second = 0xff; - --x0_boneCount; + if (!HasElement(id)) { + return; } + + if (id == xd4_curPrevBone) { + xd4_curPrevBone = x8_indirectionMap[id].first; + } + + x8_indirectionMap[id] = {}; + --x0_boneCount; } - bool HasElement(const CSegId& id) const { return x8_indirectionMap[id].first != 0xff; } + + bool HasElement(const CSegId& id) const { return x8_indirectionMap[id].first.IsValid(); } u32 GetCapacity() const { return x1_capacity; } }; diff --git a/Runtime/Collision/CCollisionActorManager.cpp b/Runtime/Collision/CCollisionActorManager.cpp index add950c4a..e9e3baacf 100644 --- a/Runtime/Collision/CCollisionActorManager.cpp +++ b/Runtime/Collision/CCollisionActorManager.cpp @@ -20,7 +20,7 @@ CCollisionActorManager::CCollisionActorManager(CStateManager& mgr, TUniqueId own CJointCollisionDescription modDesc = desc; modDesc.ScaleAllBounds(scale); zeus::CTransform locXf = GetWRLocatorTransform(*animData, modDesc.GetPivotId(), xf, scaleXf); - if (modDesc.GetNextId() != 0xff) { + if (modDesc.GetNextId().IsValid()) { zeus::CTransform locXf2 = GetWRLocatorTransform(*animData, modDesc.GetNextId(), xf, scaleXf); float dist = (locXf2.origin - locXf.origin).magnitude(); if (modDesc.GetType() == CJointCollisionDescription::ECollisionType::OBBAutoSize) { diff --git a/Runtime/MP1/World/CFlaahgra.cpp b/Runtime/MP1/World/CFlaahgra.cpp index 0fbb41fdd..cd1bb864d 100644 --- a/Runtime/MP1/World/CFlaahgra.cpp +++ b/Runtime/MP1/World/CFlaahgra.cpp @@ -443,26 +443,34 @@ void CFlaahgra::GetMirrorWaypoints(CStateManager& mgr) { void CFlaahgra::AddCollisionList(const SJointInfo* joints, int count, std::vector& outJoints) { const CAnimData* animData = GetModelData()->GetAnimationData(); - for (u32 i = 0; i < count; ++i) { - CSegId from = animData->GetLocatorSegId(joints[i].from); - CSegId to = animData->GetLocatorSegId(joints[i].to); - if (to != 0xFF && from != 0xFF) { - outJoints.push_back(CJointCollisionDescription::SphereSubdivideCollision( - to, from, joints[i].radius, joints[i].separation, CJointCollisionDescription::EOrientationType::One, - joints[i].from, 10.f)); + for (s32 i = 0; i < count; ++i) { + const auto& joint = joints[i]; + const CSegId from = animData->GetLocatorSegId(joint.from); + const CSegId to = animData->GetLocatorSegId(joint.to); + + if (to.IsInvalid() || from.IsInvalid()) { + continue; } + + outJoints.push_back(CJointCollisionDescription::SphereSubdivideCollision( + to, from, joint.radius, joint.separation, CJointCollisionDescription::EOrientationType::One, joint.from, 10.f)); } } void CFlaahgra::AddSphereCollisionList(const SSphereJointInfo* joints, int count, std::vector& outJoints) { const CAnimData* animData = GetModelData()->GetAnimationData(); - for (u32 i = 0; i < count; ++i) { - CSegId seg = animData->GetLocatorSegId(joints[i].name); - if (seg != 0xFF) { - outJoints.push_back(CJointCollisionDescription::SphereCollision(seg, joints[i].radius, joints[i].name, 10.f)); + + for (s32 i = 0; i < count; ++i) { + const auto& joint = joints[i]; + const CSegId seg = animData->GetLocatorSegId(joint.name); + + if (seg.IsInvalid()) { + continue; } + + outJoints.push_back(CJointCollisionDescription::SphereCollision(seg, joint.radius, joint.name, 10.f)); } } diff --git a/Runtime/MP1/World/CFlaahgraTentacle.cpp b/Runtime/MP1/World/CFlaahgraTentacle.cpp index c799eed6d..b0361ff0b 100644 --- a/Runtime/MP1/World/CFlaahgraTentacle.cpp +++ b/Runtime/MP1/World/CFlaahgraTentacle.cpp @@ -90,7 +90,7 @@ void CFlaahgraTentacle::AddSphereCollisionList(const SSphereJointInfo* sphereJoi const SSphereJointInfo& sphereJoint = sphereJoints[i]; const CSegId segId = animData->GetLocatorSegId(sphereJoint.name); - if (segId == 0xFF) { + if (segId.IsInvalid()) { continue; } diff --git a/Runtime/MP1/World/CMetroidBeta.cpp b/Runtime/MP1/World/CMetroidBeta.cpp index c52a8e70f..db1acae89 100644 --- a/Runtime/MP1/World/CMetroidBeta.cpp +++ b/Runtime/MP1/World/CMetroidBeta.cpp @@ -260,13 +260,15 @@ void CMetroidBeta::CreateCollisionActorManager(CStateManager& mgr) { void CMetroidBeta::AddSphereJoints(SSphereJointInfo* sphereJoints, s32 count, std::vector& joints) { - for (u32 i = 0; i < count; ++i) { - CSegId id = GetModelData()->GetAnimationData()->GetLocatorSegId(sphereJoints[i].name); - if (id == 0xFF) - continue; + for (s32 i = 0; i < count; ++i) { + const auto& sphereJoint = sphereJoints[i]; + const CSegId id = GetModelData()->GetAnimationData()->GetLocatorSegId(sphereJoint.name); - joints.push_back( - CJointCollisionDescription::SphereCollision(id, sphereJoints[i].radius, sphereJoints[i].name, 1000.0f)); + if (id.IsInvalid()) { + continue; + } + + joints.push_back(CJointCollisionDescription::SphereCollision(id, sphereJoint.radius, sphereJoint.name, 1000.0f)); } } void CMetroidBeta::SetCollisionActorHealthAndVulnerability(CStateManager& mgr) { diff --git a/Runtime/MP1/World/CSpacePirate.cpp b/Runtime/MP1/World/CSpacePirate.cpp index 66ba9efa5..ad638eb8d 100644 --- a/Runtime/MP1/World/CSpacePirate.cpp +++ b/Runtime/MP1/World/CSpacePirate.cpp @@ -1498,15 +1498,17 @@ void CSpacePirate::Deactivate(CStateManager& mgr, EStateMsg msg, float dt) { } void CSpacePirate::CheckBlade(CStateManager& mgr) { - if (!x638_25_appliedBladeDamage && x7b9_swooshSeg != 0xff) { - if (TCastToPtr act = mgr.ObjectById(x7c0_targetId)) { - zeus::CVector3f extent = x64_modelData->GetScale() * 0.5f; - zeus::CVector3f swooshPos = GetLctrTransform(x7b9_swooshSeg).origin; - if (zeus::CAABox(swooshPos - extent, swooshPos + extent).intersects(act->GetBoundingBox())) { - mgr.ApplyDamage(GetUniqueId(), act->GetUniqueId(), GetUniqueId(), x568_pirateData.x4c_BladeDamage, - CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), zeus::skZero3f); - x638_25_appliedBladeDamage = true; - } + if (x638_25_appliedBladeDamage || x7b9_swooshSeg.IsInvalid()) { + return; + } + + if (TCastToPtr act = mgr.ObjectById(x7c0_targetId)) { + zeus::CVector3f extent = x64_modelData->GetScale() * 0.5f; + zeus::CVector3f swooshPos = GetLctrTransform(x7b9_swooshSeg).origin; + if (zeus::CAABox(swooshPos - extent, swooshPos + extent).intersects(act->GetBoundingBox())) { + mgr.ApplyDamage(GetUniqueId(), act->GetUniqueId(), GetUniqueId(), x568_pirateData.x4c_BladeDamage, + CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), zeus::skZero3f); + x638_25_appliedBladeDamage = true; } } } diff --git a/Runtime/MP1/World/CSpankWeed.cpp b/Runtime/MP1/World/CSpankWeed.cpp index b1b59653e..ac00306f1 100644 --- a/Runtime/MP1/World/CSpankWeed.cpp +++ b/Runtime/MP1/World/CSpankWeed.cpp @@ -36,10 +36,10 @@ CSpankWeed::CSpankWeed(TUniqueId uid, std::string_view name, const CEntityInfo& list.Add(EMaterialTypes::Player); SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(GetMaterialFilter().GetIncludeList(), list)); - CSegId segId = GetModelData()->GetAnimationData()->GetLocatorSegId("lockon_target_LCTR"sv); - if (segId != 0xFF) { - zeus::CTransform locatorXf = GetTransform() * zeus::CTransform::Scale(GetModelData()->GetScale()) * - GetModelData()->GetAnimationData()->GetLocatorTransform(segId, nullptr); + const CSegId segId = GetModelData()->GetAnimationData()->GetLocatorSegId("lockon_target_LCTR"sv); + if (segId.IsValid()) { + const zeus::CTransform locatorXf = GetTransform() * zeus::CTransform::Scale(GetModelData()->GetScale()) * + GetModelData()->GetAnimationData()->GetLocatorTransform(segId, nullptr); x5a8_lockonTarget = locatorXf.origin; x59c_lockonOffset = locatorXf.origin - GetTranslation(); } @@ -71,9 +71,10 @@ void CSpankWeed::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CState joints.reserve(12); for (const SSphereJointInfo& joint : kArmCollision) { - CSegId id = GetModelData()->GetAnimationData()->GetLocatorSegId(joint.name); - if (id != 0xFF) + const CSegId id = GetModelData()->GetAnimationData()->GetLocatorSegId(joint.name); + if (id.IsValid()) { joints.push_back(CJointCollisionDescription::SphereCollision(id, joint.radius, joint.name, 0.001f)); + } } x594_collisionMgr = @@ -140,9 +141,9 @@ zeus::CVector3f CSpankWeed::GetOrbitPosition(const CStateManager& mgr) const { zeus::CVector3f CSpankWeed::GetAimPosition(const CStateManager&, float dt) const { zeus::CVector3f pos = (dt > 0.f ? PredictMotion(dt).x0_translation : zeus::skZero3f); - CSegId id = GetModelData()->GetAnimationData()->GetLocatorSegId("lockon_target_LCTR"sv); - if (id != 0xFF) { - zeus::CVector3f lockonOff = GetModelData()->GetAnimationData()->GetLocatorTransform(id, nullptr).origin; + const CSegId id = GetModelData()->GetAnimationData()->GetLocatorSegId("lockon_target_LCTR"sv); + if (id.IsValid()) { + const zeus::CVector3f lockonOff = GetModelData()->GetAnimationData()->GetLocatorTransform(id, nullptr).origin; return pos + (GetTransform() * (GetModelData()->GetScale() * lockonOff)); } diff --git a/Runtime/World/CPatterned.cpp b/Runtime/World/CPatterned.cpp index 47cc563ba..ec5bf5775 100644 --- a/Runtime/World/CPatterned.cpp +++ b/Runtime/World/CPatterned.cpp @@ -393,19 +393,21 @@ bool CPatterned::CanRenderUnsorted(const urde::CStateManager& mgr) const { zeus::CVector3f CPatterned::GetAimPosition(const urde::CStateManager& mgr, float dt) const { zeus::CVector3f offset; - if (dt > 0.f) + if (dt > 0.f) { offset = PredictMotion(dt).x0_translation; + } - CSegId segId = GetModelData()->GetAnimationData()->GetLocatorSegId("lockon_target_LCTR"sv); - if (segId != 0xFF) { - zeus::CTransform xf = GetModelData()->GetAnimationData()->GetLocatorTransform(segId, nullptr); - zeus::CVector3f scaledOrigin = GetModelData()->GetScale() * xf.origin; - if (auto tb = GetTouchBounds()) + const CSegId segId = GetModelData()->GetAnimationData()->GetLocatorSegId("lockon_target_LCTR"sv); + if (segId.IsValid()) { + const zeus::CTransform xf = GetModelData()->GetAnimationData()->GetLocatorTransform(segId, nullptr); + const zeus::CVector3f scaledOrigin = GetModelData()->GetScale() * xf.origin; + + if (const auto tb = GetTouchBounds()) { return offset + tb->clampToBox(x34_transform * scaledOrigin); + } - zeus::CAABox aabox = GetBaseBoundingBox(); - - zeus::CAABox primBox(aabox.min + GetPrimitiveOffset(), aabox.max + GetPrimitiveOffset()); + const zeus::CAABox aabox = GetBaseBoundingBox(); + const zeus::CAABox primBox(aabox.min + GetPrimitiveOffset(), aabox.max + GetPrimitiveOffset()); return offset + (x34_transform * primBox.clampToBox(scaledOrigin)); }