CSegId: Add member functions for querying validity

Allows querying validity of segment IDs without hardcoding the magic
value that signifies an invalid ID.
This commit is contained in:
Lioncash 2019-10-26 21:53:11 -04:00
parent 30af6f0bfb
commit 660d092cad
14 changed files with 112 additions and 78 deletions

View File

@ -250,9 +250,9 @@ void CCinematicCamera::CalculateMoveOutofIntoEyePosition(bool outOfEye, CStateMa
if (const CModelData* mData = act->GetModelData()) { if (const CModelData* mData = act->GetModelData()) {
if (const CAnimData* aData = mData->GetAnimationData()) { if (const CAnimData* aData = mData->GetAnimationData()) {
if (const CAnimTreeNode* root = aData->GetRootAnimationTree().get()) { if (const CAnimTreeNode* root = aData->GetRootAnimationTree().get()) {
CSegId lEye = aData->GetLocatorSegId("L_eye"sv); const CSegId lEye = aData->GetLocatorSegId("L_eye"sv);
CSegId rEye = aData->GetLocatorSegId("R_eye"sv); const CSegId rEye = aData->GetLocatorSegId("R_eye"sv);
if (lEye != 0xff && rEye != 0xff) { if (lEye.IsValid() && rEye.IsValid()) {
CCharAnimTime time = outOfEye ? CCharAnimTime(0.f) : root->VGetSteadyStateAnimInfo().GetDuration(); CCharAnimTime time = outOfEye ? CCharAnimTime(0.f) : root->VGetSteadyStateAnimInfo().GetDuration();
CCharAnimTime* pTime = outOfEye ? nullptr : &time; CCharAnimTime* pTime = outOfEye ? nullptr : &time;
eyePos = ((act->GetTransform() * mData->GetScaledLocatorTransformDynamic("L_eye"sv, pTime)).origin + eyePos = ((act->GetTransform() * mData->GetScaledLocatorTransformDynamic("L_eye"sv, pTime)).origin +

View File

@ -434,8 +434,9 @@ void CAnimData::CalcPlaybackAlignmentParms(const CAnimPlaybackParms& parms,
} }
zeus::CTransform CAnimData::GetLocatorTransform(CSegId id, const CCharAnimTime* time) const { zeus::CTransform CAnimData::GetLocatorTransform(CSegId id, const CCharAnimTime* time) const {
if (id == 0xFF) if (id.IsInvalid()) {
return {}; return {};
}
zeus::CTransform ret; zeus::CTransform ret;
if (time || !x220_31_poseCached) { if (time || !x220_31_poseCached) {

View File

@ -92,8 +92,8 @@ void CParticleDatabase::UpdateParticleGenDB(float dt, const CPoseAsTransforms& p
CParticleGenInfo& info = *it->second; CParticleGenInfo& info = *it->second;
if (info.GetIsActive()) { if (info.GetIsActive()) {
if (info.GetType() == EParticleGenType::Normal) { if (info.GetType() == EParticleGenType::Normal) {
CSegId segId = charInfo.GetSegIdFromString(info.GetLocatorName()); const CSegId segId = charInfo.GetSegIdFromString(info.GetLocatorName());
if (segId == 0xff) { if (segId.IsInvalid()) {
++it; ++it;
continue; continue;
} }

View File

@ -7,7 +7,7 @@ CPoseAsTransforms::CPoseAsTransforms(u8 boneCount) : x1_count(boneCount), xd0_tr
bool CPoseAsTransforms::ContainsDataFor(const CSegId& id) const { bool CPoseAsTransforms::ContainsDataFor(const CSegId& id) const {
const std::pair<CSegId, CSegId>& link = x8_links[id]; const std::pair<CSegId, CSegId>& link = x8_links[id];
return link.first != 0xff || link.second != 0xff; return link.first.IsValid() || link.second.IsValid();
} }
void CPoseAsTransforms::Clear() { 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 zeus::CTransform& CPoseAsTransforms::GetTransform(const CSegId& id) const {
const std::pair<CSegId, CSegId>& link = x8_links[id]; const std::pair<CSegId, CSegId>& link = x8_links[id];
assert(link.second != 0xff); assert(link.second.IsValid());
return xd0_transformArr[link.second].m_originToAccum; return xd0_transformArr[link.second].m_originToAccum;
} }
const zeus::CTransform& CPoseAsTransforms::GetRestToAccumTransform(const CSegId& id) const { const zeus::CTransform& CPoseAsTransforms::GetRestToAccumTransform(const CSegId& id) const {
const std::pair<CSegId, CSegId>& link = x8_links[id]; const std::pair<CSegId, CSegId>& link = x8_links[id];
assert(link.second != 0xff); assert(link.second.IsValid());
return xd0_transformArr[link.second].m_restPoseToAccum; return xd0_transformArr[link.second].m_restPoseToAccum;
} }
const zeus::CVector3f& CPoseAsTransforms::GetOffset(const CSegId& id) const { const zeus::CVector3f& CPoseAsTransforms::GetOffset(const CSegId& id) const {
const std::pair<CSegId, CSegId>& link = x8_links[id]; const std::pair<CSegId, CSegId>& link = x8_links[id];
assert(link.second != 0xff); assert(link.second.IsValid());
return xd0_transformArr[link.second].m_originToAccum.origin; return xd0_transformArr[link.second].m_originToAccum.origin;
} }
const zeus::CMatrix3f& CPoseAsTransforms::GetRotation(const CSegId& id) const { const zeus::CMatrix3f& CPoseAsTransforms::GetRotation(const CSegId& id) const {
const std::pair<CSegId, CSegId>& link = x8_links[id]; const std::pair<CSegId, CSegId>& link = x8_links[id];
assert(link.second != 0xff); assert(link.second.IsValid());
return xd0_transformArr[link.second].m_originToAccum.basis; return xd0_transformArr[link.second].m_originToAccum.basis;
} }

View File

@ -307,12 +307,15 @@ void CRagDoll::Prime(CStateManager& mgr, const zeus::CTransform& xf, CModelData&
zeus::CVector3f scale = mData.GetScale(); zeus::CVector3f scale = mData.GetScale();
CAnimData* aData = mData.GetAnimationData(); CAnimData* aData = mData.GetAnimationData();
aData->BuildPose(); aData->BuildPose();
for (auto& particle : x4_particles) for (auto& particle : x4_particles) {
if (particle.x0_id != 0xff) if (particle.x0_id.IsValid()) {
particle.x4_curPos = xf * (aData->GetPose().GetOffset(particle.x0_id) * scale); particle.x4_curPos = xf * (aData->GetPose().GetOffset(particle.x0_id) * scale);
}
}
SatisfyWorldConstraints(mgr, 2); SatisfyWorldConstraints(mgr, 2);
for (auto& particle : x4_particles) for (auto& particle : x4_particles) {
particle.x3c_24_impactPending = false; particle.x3c_24_impactPending = false;
}
x68_26_primed = true; x68_26_primed = true;
} }

View File

@ -6,7 +6,7 @@
namespace urde { namespace urde {
class CSegId { class CSegId {
u8 x0_segId = 0xff; u8 x0_segId = 0xFF;
public: public:
constexpr CSegId() noexcept = default; constexpr CSegId() noexcept = default;
@ -21,6 +21,9 @@ public:
return *this; return *this;
} }
constexpr operator u8() const noexcept { 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 } // namespace urde

View File

@ -19,43 +19,55 @@ class TSegIdMap {
public: public:
TSegIdMap(const CSegId& capacity) : x1_capacity(capacity), xd0_bones(new T[capacity]) {} TSegIdMap(const CSegId& capacity) : x1_capacity(capacity), xd0_bones(new T[capacity]) {}
T& operator[](const CSegId& id) { return SetElement(id); } T& operator[](const CSegId& id) { return SetElement(id); }
const T& operator[](const CSegId& id) const { return xd0_bones[x8_indirectionMap[id].second]; } const T& operator[](const CSegId& id) const { return xd0_bones[x8_indirectionMap[id].second]; }
T& SetElement(const CSegId& id, T&& obj) { T& SetElement(const CSegId& id, T&& obj) {
size_t idx; size_t idx;
if (x8_indirectionMap[id].first == 0xff) {
x8_indirectionMap[id].first = xd4_curPrevBone; if (HasElement(id)) {
x8_indirectionMap[id].second = x0_boneCount; idx = x8_indirectionMap[id].second;
} else {
x8_indirectionMap[id] = std::make_pair(xd4_curPrevBone, x0_boneCount);
xd4_curPrevBone = id; xd4_curPrevBone = id;
idx = x0_boneCount; idx = x0_boneCount;
++x0_boneCount; ++x0_boneCount;
} else }
idx = x8_indirectionMap[id].second;
xd0_bones[idx] = std::move(obj); xd0_bones[idx] = std::move(obj);
return xd0_bones[idx]; return xd0_bones[idx];
} }
T& SetElement(const CSegId& id) { T& SetElement(const CSegId& id) {
size_t idx; size_t idx;
if (x8_indirectionMap[id].first == 0xff) {
x8_indirectionMap[id].first = xd4_curPrevBone; if (HasElement(id)) {
x8_indirectionMap[id].second = x0_boneCount; idx = x8_indirectionMap[id].second;
} else {
x8_indirectionMap[id] = std::make_pair(xd4_curPrevBone, x0_boneCount);
xd4_curPrevBone = id; xd4_curPrevBone = id;
idx = x0_boneCount; idx = x0_boneCount;
++x0_boneCount; ++x0_boneCount;
} else }
idx = x8_indirectionMap[id].second;
return xd0_bones[idx]; return xd0_bones[idx];
} }
void DelElement(const CSegId& id) { void DelElement(const CSegId& id) {
if (x8_indirectionMap[id].first != 0xff) { if (!HasElement(id)) {
if (id == xd4_curPrevBone) return;
}
if (id == xd4_curPrevBone) {
xd4_curPrevBone = x8_indirectionMap[id].first; xd4_curPrevBone = x8_indirectionMap[id].first;
x8_indirectionMap[id].first = 0xff; }
x8_indirectionMap[id].second = 0xff;
x8_indirectionMap[id] = {};
--x0_boneCount; --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; } u32 GetCapacity() const { return x1_capacity; }
}; };

View File

@ -20,7 +20,7 @@ CCollisionActorManager::CCollisionActorManager(CStateManager& mgr, TUniqueId own
CJointCollisionDescription modDesc = desc; CJointCollisionDescription modDesc = desc;
modDesc.ScaleAllBounds(scale); modDesc.ScaleAllBounds(scale);
zeus::CTransform locXf = GetWRLocatorTransform(*animData, modDesc.GetPivotId(), xf, scaleXf); 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); zeus::CTransform locXf2 = GetWRLocatorTransform(*animData, modDesc.GetNextId(), xf, scaleXf);
float dist = (locXf2.origin - locXf.origin).magnitude(); float dist = (locXf2.origin - locXf.origin).magnitude();
if (modDesc.GetType() == CJointCollisionDescription::ECollisionType::OBBAutoSize) { if (modDesc.GetType() == CJointCollisionDescription::ECollisionType::OBBAutoSize) {

View File

@ -443,26 +443,34 @@ void CFlaahgra::GetMirrorWaypoints(CStateManager& mgr) {
void CFlaahgra::AddCollisionList(const SJointInfo* joints, int count, void CFlaahgra::AddCollisionList(const SJointInfo* joints, int count,
std::vector<CJointCollisionDescription>& outJoints) { std::vector<CJointCollisionDescription>& outJoints) {
const CAnimData* animData = GetModelData()->GetAnimationData(); 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) { for (s32 i = 0; i < count; ++i) {
outJoints.push_back(CJointCollisionDescription::SphereSubdivideCollision( const auto& joint = joints[i];
to, from, joints[i].radius, joints[i].separation, CJointCollisionDescription::EOrientationType::One, const CSegId from = animData->GetLocatorSegId(joint.from);
joints[i].from, 10.f)); 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, void CFlaahgra::AddSphereCollisionList(const SSphereJointInfo* joints, int count,
std::vector<CJointCollisionDescription>& outJoints) { std::vector<CJointCollisionDescription>& outJoints) {
const CAnimData* animData = GetModelData()->GetAnimationData(); const CAnimData* animData = GetModelData()->GetAnimationData();
for (u32 i = 0; i < count; ++i) {
CSegId seg = animData->GetLocatorSegId(joints[i].name); for (s32 i = 0; i < count; ++i) {
if (seg != 0xFF) { const auto& joint = joints[i];
outJoints.push_back(CJointCollisionDescription::SphereCollision(seg, joints[i].radius, joints[i].name, 10.f)); const CSegId seg = animData->GetLocatorSegId(joint.name);
if (seg.IsInvalid()) {
continue;
} }
outJoints.push_back(CJointCollisionDescription::SphereCollision(seg, joint.radius, joint.name, 10.f));
} }
} }

View File

@ -90,7 +90,7 @@ void CFlaahgraTentacle::AddSphereCollisionList(const SSphereJointInfo* sphereJoi
const SSphereJointInfo& sphereJoint = sphereJoints[i]; const SSphereJointInfo& sphereJoint = sphereJoints[i];
const CSegId segId = animData->GetLocatorSegId(sphereJoint.name); const CSegId segId = animData->GetLocatorSegId(sphereJoint.name);
if (segId == 0xFF) { if (segId.IsInvalid()) {
continue; continue;
} }

View File

@ -260,13 +260,15 @@ void CMetroidBeta::CreateCollisionActorManager(CStateManager& mgr) {
void CMetroidBeta::AddSphereJoints(SSphereJointInfo* sphereJoints, s32 count, void CMetroidBeta::AddSphereJoints(SSphereJointInfo* sphereJoints, s32 count,
std::vector<CJointCollisionDescription>& joints) { std::vector<CJointCollisionDescription>& joints) {
for (u32 i = 0; i < count; ++i) { for (s32 i = 0; i < count; ++i) {
CSegId id = GetModelData()->GetAnimationData()->GetLocatorSegId(sphereJoints[i].name); const auto& sphereJoint = sphereJoints[i];
if (id == 0xFF) const CSegId id = GetModelData()->GetAnimationData()->GetLocatorSegId(sphereJoint.name);
continue;
joints.push_back( if (id.IsInvalid()) {
CJointCollisionDescription::SphereCollision(id, sphereJoints[i].radius, sphereJoints[i].name, 1000.0f)); continue;
}
joints.push_back(CJointCollisionDescription::SphereCollision(id, sphereJoint.radius, sphereJoint.name, 1000.0f));
} }
} }
void CMetroidBeta::SetCollisionActorHealthAndVulnerability(CStateManager& mgr) { void CMetroidBeta::SetCollisionActorHealthAndVulnerability(CStateManager& mgr) {

View File

@ -1498,7 +1498,10 @@ void CSpacePirate::Deactivate(CStateManager& mgr, EStateMsg msg, float dt) {
} }
void CSpacePirate::CheckBlade(CStateManager& mgr) { void CSpacePirate::CheckBlade(CStateManager& mgr) {
if (!x638_25_appliedBladeDamage && x7b9_swooshSeg != 0xff) { if (x638_25_appliedBladeDamage || x7b9_swooshSeg.IsInvalid()) {
return;
}
if (TCastToPtr<CPhysicsActor> act = mgr.ObjectById(x7c0_targetId)) { if (TCastToPtr<CPhysicsActor> act = mgr.ObjectById(x7c0_targetId)) {
zeus::CVector3f extent = x64_modelData->GetScale() * 0.5f; zeus::CVector3f extent = x64_modelData->GetScale() * 0.5f;
zeus::CVector3f swooshPos = GetLctrTransform(x7b9_swooshSeg).origin; zeus::CVector3f swooshPos = GetLctrTransform(x7b9_swooshSeg).origin;
@ -1509,7 +1512,6 @@ void CSpacePirate::CheckBlade(CStateManager& mgr) {
} }
} }
} }
}
void CSpacePirate::Attack(CStateManager& mgr, EStateMsg msg, float dt) { void CSpacePirate::Attack(CStateManager& mgr, EStateMsg msg, float dt) {
switch (msg) { switch (msg) {

View File

@ -36,9 +36,9 @@ CSpankWeed::CSpankWeed(TUniqueId uid, std::string_view name, const CEntityInfo&
list.Add(EMaterialTypes::Player); list.Add(EMaterialTypes::Player);
SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(GetMaterialFilter().GetIncludeList(), list)); SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(GetMaterialFilter().GetIncludeList(), list));
CSegId segId = GetModelData()->GetAnimationData()->GetLocatorSegId("lockon_target_LCTR"sv); const CSegId segId = GetModelData()->GetAnimationData()->GetLocatorSegId("lockon_target_LCTR"sv);
if (segId != 0xFF) { if (segId.IsValid()) {
zeus::CTransform locatorXf = GetTransform() * zeus::CTransform::Scale(GetModelData()->GetScale()) * const zeus::CTransform locatorXf = GetTransform() * zeus::CTransform::Scale(GetModelData()->GetScale()) *
GetModelData()->GetAnimationData()->GetLocatorTransform(segId, nullptr); GetModelData()->GetAnimationData()->GetLocatorTransform(segId, nullptr);
x5a8_lockonTarget = locatorXf.origin; x5a8_lockonTarget = locatorXf.origin;
x59c_lockonOffset = locatorXf.origin - GetTranslation(); x59c_lockonOffset = locatorXf.origin - GetTranslation();
@ -71,10 +71,11 @@ void CSpankWeed::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CState
joints.reserve(12); joints.reserve(12);
for (const SSphereJointInfo& joint : kArmCollision) { for (const SSphereJointInfo& joint : kArmCollision) {
CSegId id = GetModelData()->GetAnimationData()->GetLocatorSegId(joint.name); const CSegId id = GetModelData()->GetAnimationData()->GetLocatorSegId(joint.name);
if (id != 0xFF) if (id.IsValid()) {
joints.push_back(CJointCollisionDescription::SphereCollision(id, joint.radius, joint.name, 0.001f)); joints.push_back(CJointCollisionDescription::SphereCollision(id, joint.radius, joint.name, 0.001f));
} }
}
x594_collisionMgr = x594_collisionMgr =
std::make_unique<CCollisionActorManager>(mgr, GetUniqueId(), GetAreaIdAlways(), joints, GetActive()); std::make_unique<CCollisionActorManager>(mgr, GetUniqueId(), GetAreaIdAlways(), joints, GetActive());
@ -140,9 +141,9 @@ zeus::CVector3f CSpankWeed::GetOrbitPosition(const CStateManager& mgr) const {
zeus::CVector3f CSpankWeed::GetAimPosition(const CStateManager&, float dt) const { zeus::CVector3f CSpankWeed::GetAimPosition(const CStateManager&, float dt) const {
zeus::CVector3f pos = (dt > 0.f ? PredictMotion(dt).x0_translation : zeus::skZero3f); zeus::CVector3f pos = (dt > 0.f ? PredictMotion(dt).x0_translation : zeus::skZero3f);
CSegId id = GetModelData()->GetAnimationData()->GetLocatorSegId("lockon_target_LCTR"sv); const CSegId id = GetModelData()->GetAnimationData()->GetLocatorSegId("lockon_target_LCTR"sv);
if (id != 0xFF) { if (id.IsValid()) {
zeus::CVector3f lockonOff = GetModelData()->GetAnimationData()->GetLocatorTransform(id, nullptr).origin; const zeus::CVector3f lockonOff = GetModelData()->GetAnimationData()->GetLocatorTransform(id, nullptr).origin;
return pos + (GetTransform() * (GetModelData()->GetScale() * lockonOff)); return pos + (GetTransform() * (GetModelData()->GetScale() * lockonOff));
} }

View File

@ -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 CPatterned::GetAimPosition(const urde::CStateManager& mgr, float dt) const {
zeus::CVector3f offset; zeus::CVector3f offset;
if (dt > 0.f) if (dt > 0.f) {
offset = PredictMotion(dt).x0_translation; offset = PredictMotion(dt).x0_translation;
}
CSegId segId = GetModelData()->GetAnimationData()->GetLocatorSegId("lockon_target_LCTR"sv); const CSegId segId = GetModelData()->GetAnimationData()->GetLocatorSegId("lockon_target_LCTR"sv);
if (segId != 0xFF) { if (segId.IsValid()) {
zeus::CTransform xf = GetModelData()->GetAnimationData()->GetLocatorTransform(segId, nullptr); const zeus::CTransform xf = GetModelData()->GetAnimationData()->GetLocatorTransform(segId, nullptr);
zeus::CVector3f scaledOrigin = GetModelData()->GetScale() * xf.origin; const zeus::CVector3f scaledOrigin = GetModelData()->GetScale() * xf.origin;
if (auto tb = GetTouchBounds())
if (const auto tb = GetTouchBounds()) {
return offset + tb->clampToBox(x34_transform * scaledOrigin); return offset + tb->clampToBox(x34_transform * scaledOrigin);
}
zeus::CAABox aabox = GetBaseBoundingBox(); const zeus::CAABox aabox = GetBaseBoundingBox();
const zeus::CAABox primBox(aabox.min + GetPrimitiveOffset(), aabox.max + GetPrimitiveOffset());
zeus::CAABox primBox(aabox.min + GetPrimitiveOffset(), aabox.max + GetPrimitiveOffset());
return offset + (x34_transform * primBox.clampToBox(scaledOrigin)); return offset + (x34_transform * primBox.clampToBox(scaledOrigin));
} }