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 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 +

View File

@ -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) {

View File

@ -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;
}

View File

@ -7,7 +7,7 @@ CPoseAsTransforms::CPoseAsTransforms(u8 boneCount) : x1_count(boneCount), xd0_tr
bool CPoseAsTransforms::ContainsDataFor(const CSegId& id) const {
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() {
@ -23,25 +23,25 @@ void CPoseAsTransforms::AccumulateScaledTransform(const CSegId& id, zeus::CMatri
const zeus::CTransform& CPoseAsTransforms::GetTransform(const CSegId& id) const {
const std::pair<CSegId, CSegId>& 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<CSegId, CSegId>& 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<CSegId, CSegId>& 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<CSegId, CSegId>& link = x8_links[id];
assert(link.second != 0xff);
assert(link.second.IsValid());
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();
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;
}

View File

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

View File

@ -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; }
};

View File

@ -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) {

View File

@ -443,26 +443,34 @@ void CFlaahgra::GetMirrorWaypoints(CStateManager& mgr) {
void CFlaahgra::AddCollisionList(const SJointInfo* joints, int count,
std::vector<CJointCollisionDescription>& 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<CJointCollisionDescription>& 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));
}
}

View File

@ -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;
}

View File

@ -260,13 +260,15 @@ void CMetroidBeta::CreateCollisionActorManager(CStateManager& mgr) {
void CMetroidBeta::AddSphereJoints(SSphereJointInfo* sphereJoints, s32 count,
std::vector<CJointCollisionDescription>& 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) {

View File

@ -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<CPhysicsActor> 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<CPhysicsActor> 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;
}
}
}

View File

@ -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));
}

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 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));
}