mirror of https://github.com/AxioDL/metaforce.git
Space pirate bug fixes
This commit is contained in:
parent
ccf87925b9
commit
dac8fc3eb5
|
@ -212,7 +212,7 @@ struct HealthInfo : BigDNA {
|
|||
AT_DECL_DNA_YAML
|
||||
Value<atUint32> propertyCount;
|
||||
Value<float> health SPECTER_PROPERTY("Health", "Base health for object");
|
||||
Value<float> knockbackResistence SPECTER_PROPERTY("Knockback Resistence", "");
|
||||
Value<float> knockbackResistance SPECTER_PROPERTY("Knockback Resistance", "");
|
||||
} SPECTER_PROPERTY("Health Info", "");
|
||||
|
||||
struct LightParameters : BigDNA {
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "hecl/CVarManager.hpp"
|
||||
#include "World/CPatterned.hpp"
|
||||
#include "World/CDestroyableRock.hpp"
|
||||
#include "World/CPathFindSearch.hpp"
|
||||
#include <cmath>
|
||||
|
||||
namespace urde {
|
||||
|
@ -515,7 +516,15 @@ void CStateManager::BuildDynamicLightListForWorld() {
|
|||
}
|
||||
}
|
||||
|
||||
void CStateManager::DrawDebugStuff() const {}
|
||||
void CStateManager::DrawDebugStuff() const {
|
||||
for (CEntity* ent : GetActorObjectList()) {
|
||||
if (TCastToPtr<CPatterned> ai = ent) {
|
||||
if (CPathFindSearch* path = ai->GetSearchPath()) {
|
||||
path->DebugDraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CStateManager::RenderCamerasAndAreaLights() const {
|
||||
x870_cameraManager->RenderCameras(*this);
|
||||
|
@ -1558,8 +1567,8 @@ bool CStateManager::ApplyLocalDamage(const zeus::CVector3f& pos, const zeus::CVe
|
|||
}
|
||||
|
||||
float newHp = hInfo->GetHP() - mulDam;
|
||||
hInfo->SetHP(newHp);
|
||||
bool significant = std::fabs(newHp - hInfo->GetHP()) >= 0.00001;
|
||||
hInfo->SetHP(newHp);
|
||||
|
||||
if (player && GetPlayerState()->CanTakeDamage()) {
|
||||
player->TakeDamage(significant, pos, mulDam, weapMode.GetType(), *this);
|
||||
|
|
|
@ -108,7 +108,7 @@ CAssetId CAnimData::GetEventResourceIdForAnimResourceId(CAssetId id) const {
|
|||
}
|
||||
|
||||
void CAnimData::AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet) {
|
||||
for (std::pair<u32, CAdditiveAnimPlayback>& additive : x434_additiveAnims)
|
||||
for (auto& additive : x434_additiveAnims)
|
||||
if (additive.second.GetTargetWeight() > 0.00001f)
|
||||
additive.second.AddToSegStatementSet(list, *xcc_layoutData.GetObj(), stSet);
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ SAdvancementDeltas CAnimData::AdvanceAdditiveAnims(float dt) {
|
|||
|
||||
SAdvancementDeltas deltas = {};
|
||||
|
||||
for (std::pair<u32, CAdditiveAnimPlayback>& additive : x434_additiveAnims) {
|
||||
for (auto& additive : x434_additiveAnims) {
|
||||
std::shared_ptr<CAnimTreeNode>& anim = additive.second.GetAnim();
|
||||
if (additive.second.IsActive()) {
|
||||
while (time.GreaterThanZero() && std::fabs(time.GetSeconds()) >= 0.00001f) {
|
||||
|
@ -181,72 +181,73 @@ SAdvancementDeltas CAnimData::UpdateAdditiveAnims(float dt) {
|
|||
return AdvanceAdditiveAnims(dt);
|
||||
}
|
||||
|
||||
bool CAnimData::IsAdditiveAnimation(u32 idx) const {
|
||||
u32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
bool CAnimData::IsAdditiveAnimation(s32 idx) const {
|
||||
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
return x0_charFactory->HasAdditiveInfo(animIdx);
|
||||
}
|
||||
|
||||
bool CAnimData::IsAdditiveAnimationAdded(u32 idx) const {
|
||||
bool CAnimData::IsAdditiveAnimationAdded(s32 idx) const {
|
||||
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
auto search =
|
||||
std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||
[&](const std::pair<u32, CAdditiveAnimPlayback>& pair) -> bool { return pair.first == idx; });
|
||||
if (search == x434_additiveAnims.cend())
|
||||
return false;
|
||||
return true;
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
return search != x434_additiveAnims.cend();
|
||||
}
|
||||
|
||||
const std::shared_ptr<CAnimTreeNode>& CAnimData::GetAdditiveAnimationTree(u32 idx) const {
|
||||
const std::shared_ptr<CAnimTreeNode>& CAnimData::GetAdditiveAnimationTree(s32 idx) const {
|
||||
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
auto search =
|
||||
std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||
[&](const std::pair<u32, CAdditiveAnimPlayback>& pair) -> bool { return pair.first == idx; });
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
return search->second.GetAnim();
|
||||
}
|
||||
|
||||
bool CAnimData::IsAdditiveAnimationActive(u32 idx) const {
|
||||
bool CAnimData::IsAdditiveAnimationActive(s32 idx) const {
|
||||
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
auto search =
|
||||
std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||
[&](const std::pair<u32, CAdditiveAnimPlayback>& pair) -> bool { return pair.first == idx; });
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
if (search == x434_additiveAnims.cend())
|
||||
return false;
|
||||
return search->second.IsActive();
|
||||
}
|
||||
|
||||
void CAnimData::DelAdditiveAnimation(s32 idx) {
|
||||
u32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
for (std::pair<u32, CAdditiveAnimPlayback>& anim : x434_additiveAnims) {
|
||||
if (anim.first == animIdx && anim.second.GetPhase() != EAdditivePlaybackPhase::FadingOut &&
|
||||
anim.second.GetPhase() != EAdditivePlaybackPhase::FadedOut) {
|
||||
anim.second.FadeOut();
|
||||
return;
|
||||
}
|
||||
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
auto search =
|
||||
std::find_if(x434_additiveAnims.begin(), x434_additiveAnims.end(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
if (search != x434_additiveAnims.cend() &&
|
||||
search->second.GetPhase() != EAdditivePlaybackPhase::FadingOut &&
|
||||
search->second.GetPhase() != EAdditivePlaybackPhase::FadedOut) {
|
||||
search->second.FadeOut();
|
||||
}
|
||||
}
|
||||
|
||||
void CAnimData::AddAdditiveAnimation(s32 idx, float weight, bool active, bool fadeOut) {
|
||||
u32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
for (std::pair<u32, CAdditiveAnimPlayback>& anim : x434_additiveAnims) {
|
||||
if (anim.first == animIdx && anim.second.GetPhase() != EAdditivePlaybackPhase::FadingOut &&
|
||||
anim.second.GetPhase() != EAdditivePlaybackPhase::FadedOut) {
|
||||
anim.second.SetActive(active);
|
||||
anim.second.SetWeight(weight);
|
||||
anim.second.SetNeedsFadeOut(!anim.second.IsActive() && fadeOut);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
auto search =
|
||||
std::find_if(x434_additiveAnims.begin(), x434_additiveAnims.end(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
if (search != x434_additiveAnims.cend()) {
|
||||
search->second.SetActive(active);
|
||||
search->second.SetWeight(weight);
|
||||
search->second.SetNeedsFadeOut(!search->second.IsActive() && fadeOut);
|
||||
} else {
|
||||
std::shared_ptr<CAnimTreeNode> node =
|
||||
GetAnimationManager()->GetAnimationTree(animIdx, CMetaAnimTreeBuildOrders::NoSpecialOrders());
|
||||
|
||||
const CAdditiveAnimationInfo& info = x0_charFactory->FindAdditiveInfo(animIdx);
|
||||
x434_additiveAnims.emplace_back(std::make_pair(idx, CAdditiveAnimPlayback(node, weight, active, info, fadeOut)));
|
||||
x434_additiveAnims.emplace_back(std::make_pair(animIdx, CAdditiveAnimPlayback(node, weight, active, info, fadeOut)));
|
||||
}
|
||||
}
|
||||
|
||||
float CAnimData::GetAdditiveAnimationWeight(u32 idx) const {
|
||||
u32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
for (const std::pair<u32, CAdditiveAnimPlayback>& anim : x434_additiveAnims) {
|
||||
if (anim.first == animIdx)
|
||||
return anim.second.GetTargetWeight();
|
||||
}
|
||||
float CAnimData::GetAdditiveAnimationWeight(s32 idx) const {
|
||||
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
|
||||
auto search =
|
||||
std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
|
||||
[animIdx](const auto& pair) { return pair.first == animIdx; });
|
||||
if (search != x434_additiveAnims.cend())
|
||||
return search->second.GetTargetWeight();
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
|
@ -618,13 +619,13 @@ void CAnimData::SetAnimation(const CAnimPlaybackParms& parms, bool noTrans) {
|
|||
x200_speedScale = 1.f;
|
||||
x208_defaultAnim = parms.GetAnimationId();
|
||||
|
||||
u32 animIdxA = xc_charInfo.GetAnimationIndex(parms.GetAnimationId());
|
||||
s32 animIdxA = xc_charInfo.GetAnimationIndex(parms.GetAnimationId());
|
||||
|
||||
ResetPOILists();
|
||||
|
||||
std::shared_ptr<CAnimTreeNode> blendNode;
|
||||
if (parms.GetSecondAnimationId() != -1) {
|
||||
u32 animIdxB = xc_charInfo.GetAnimationIndex(parms.GetSecondAnimationId());
|
||||
s32 animIdxB = xc_charInfo.GetAnimationIndex(parms.GetSecondAnimationId());
|
||||
|
||||
std::shared_ptr<CAnimTreeNode> treeA =
|
||||
x100_animMgr->GetAnimationTree(animIdxA, CMetaAnimTreeBuildOrders::NoSpecialOrders());
|
||||
|
|
|
@ -108,7 +108,7 @@ private:
|
|||
|
||||
float x200_speedScale = 1.f;
|
||||
s32 x204_charIdx;
|
||||
u16 x208_defaultAnim;
|
||||
s32 x208_defaultAnim;
|
||||
u32 x20c_passedBoolCount = 0;
|
||||
u32 x210_passedIntCount = 0;
|
||||
u32 x214_passedParticleCount = 0;
|
||||
|
@ -133,7 +133,7 @@ private:
|
|||
CHierarchyPoseBuilder x2fc_poseBuilder;
|
||||
|
||||
CAnimPlaybackParms x40c_playbackParms;
|
||||
rstl::reserved_vector<std::pair<u32, CAdditiveAnimPlayback>, 8> x434_additiveAnims;
|
||||
rstl::reserved_vector<std::pair<s32, CAdditiveAnimPlayback>, 8> x434_additiveAnims;
|
||||
|
||||
static rstl::reserved_vector<CBoolPOINode, 8> g_BoolPOINodes;
|
||||
static rstl::reserved_vector<CInt32POINode, 16> g_Int32POINodes;
|
||||
|
@ -158,14 +158,14 @@ public:
|
|||
static SAdvancementResults AdvanceAdditiveAnim(std::shared_ptr<CAnimTreeNode>& anim, const CCharAnimTime& time);
|
||||
SAdvancementDeltas AdvanceAdditiveAnims(float);
|
||||
SAdvancementDeltas UpdateAdditiveAnims(float);
|
||||
bool IsAdditiveAnimation(u32) const;
|
||||
bool IsAdditiveAnimationAdded(u32) const;
|
||||
bool IsAdditiveAnimation(s32) const;
|
||||
bool IsAdditiveAnimationAdded(s32) const;
|
||||
const std::shared_ptr<CAnimTreeNode>& GetRootAnimationTree() const { return x1f8_animRoot; }
|
||||
const std::shared_ptr<CAnimTreeNode>& GetAdditiveAnimationTree(u32) const;
|
||||
bool IsAdditiveAnimationActive(u32) const;
|
||||
const std::shared_ptr<CAnimTreeNode>& GetAdditiveAnimationTree(s32) const;
|
||||
bool IsAdditiveAnimationActive(s32) const;
|
||||
void DelAdditiveAnimation(s32);
|
||||
void AddAdditiveAnimation(s32, float, bool, bool);
|
||||
float GetAdditiveAnimationWeight(u32 idx) const;
|
||||
float GetAdditiveAnimationWeight(s32 idx) const;
|
||||
std::shared_ptr<CAnimationManager> GetAnimationManager();
|
||||
const CCharacterInfo& GetCharacterInfo() const { return xc_charInfo; }
|
||||
const CCharLayoutInfo& GetCharLayoutInfo() const { return *xcc_layoutData.GetObj(); }
|
||||
|
@ -229,6 +229,7 @@ public:
|
|||
static void FreeCache();
|
||||
static void InitializeCache();
|
||||
CHierarchyPoseBuilder& PoseBuilder() { return x2fc_poseBuilder; }
|
||||
const CHierarchyPoseBuilder& GetPoseBuilder() const { return x2fc_poseBuilder; }
|
||||
const CParticleDatabase& GetParticleDB() const { return x120_particleDB; }
|
||||
CParticleDatabase& GetParticleDB() { return x120_particleDB; }
|
||||
void SetParticleCEXTValue(std::string_view name, int idx, float value);
|
||||
|
|
|
@ -11,9 +11,9 @@ class CPrimitive;
|
|||
|
||||
class CAnimationDatabase {
|
||||
public:
|
||||
virtual const std::shared_ptr<IMetaAnim>& GetMetaAnim(u32) const = 0;
|
||||
virtual const std::shared_ptr<IMetaAnim>& GetMetaAnim(s32) const = 0;
|
||||
virtual u32 GetNumMetaAnims() const = 0;
|
||||
virtual const char* GetMetaAnimName(u32) const = 0;
|
||||
virtual const char* GetMetaAnimName(s32) const = 0;
|
||||
virtual void GetAllUniquePrimitives(std::vector<CPrimitive>&) const = 0;
|
||||
virtual void GetUniquePrimitivesFromMetaAnim(std::set<CPrimitive>&, std::string_view) const = 0;
|
||||
};
|
||||
|
|
|
@ -11,11 +11,11 @@ CAnimationDatabaseGame::CAnimationDatabaseGame(const std::vector<CAnimation>& an
|
|||
x10_anims.emplace_back(anim.GetMetaAnim());
|
||||
}
|
||||
|
||||
const std::shared_ptr<IMetaAnim>& CAnimationDatabaseGame::GetMetaAnim(u32 idx) const { return x10_anims[idx]; }
|
||||
const std::shared_ptr<IMetaAnim>& CAnimationDatabaseGame::GetMetaAnim(s32 idx) const { return x10_anims[idx]; }
|
||||
|
||||
u32 CAnimationDatabaseGame::GetNumMetaAnims() const { return x10_anims.size(); }
|
||||
|
||||
const char* CAnimationDatabaseGame::GetMetaAnimName(u32 idx) const {
|
||||
const char* CAnimationDatabaseGame::GetMetaAnimName(s32 idx) const {
|
||||
return "Meta-animation name unavailable in Release mode.";
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,9 @@ class CAnimationDatabaseGame final : public CAnimationDatabase {
|
|||
|
||||
public:
|
||||
CAnimationDatabaseGame(const std::vector<CAnimation>& anims);
|
||||
const std::shared_ptr<IMetaAnim>& GetMetaAnim(u32 idx) const;
|
||||
const std::shared_ptr<IMetaAnim>& GetMetaAnim(s32 idx) const;
|
||||
u32 GetNumMetaAnims() const;
|
||||
const char* GetMetaAnimName(u32 idx) const;
|
||||
const char* GetMetaAnimName(s32 idx) const;
|
||||
void GetAllUniquePrimitives(std::vector<CPrimitive>& primsOut) const;
|
||||
void GetUniquePrimitivesFromMetaAnim(std::set<CPrimitive>& primsOut, std::string_view name) const;
|
||||
};
|
||||
|
|
|
@ -7,13 +7,13 @@ namespace urde {
|
|||
|
||||
const CAnimationDatabaseGame* CAnimationManager::GetAnimationDatabase() const { return x0_animDB.GetObj(); }
|
||||
|
||||
std::shared_ptr<CAnimTreeNode> CAnimationManager::GetAnimationTree(u32 animIdx,
|
||||
std::shared_ptr<CAnimTreeNode> CAnimationManager::GetAnimationTree(s32 animIdx,
|
||||
const CMetaAnimTreeBuildOrders& orders) const {
|
||||
const std::shared_ptr<IMetaAnim>& anim = x0_animDB->GetMetaAnim(animIdx);
|
||||
return anim->GetAnimationTree(x8_sysCtx, orders);
|
||||
}
|
||||
|
||||
const std::shared_ptr<IMetaAnim>& CAnimationManager::GetMetaAnimation(u32 idx) const {
|
||||
const std::shared_ptr<IMetaAnim>& CAnimationManager::GetMetaAnimation(s32 idx) const {
|
||||
return x0_animDB->GetMetaAnim(idx);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ public:
|
|||
: x0_animDB(animDB), x8_sysCtx(sysCtx) {}
|
||||
|
||||
const CAnimationDatabaseGame* GetAnimationDatabase() const;
|
||||
std::shared_ptr<CAnimTreeNode> GetAnimationTree(u32, const CMetaAnimTreeBuildOrders& orders) const;
|
||||
const std::shared_ptr<IMetaAnim>& GetMetaAnimation(u32) const;
|
||||
std::shared_ptr<CAnimTreeNode> GetAnimationTree(s32, const CMetaAnimTreeBuildOrders& orders) const;
|
||||
const std::shared_ptr<IMetaAnim>& GetMetaAnimation(s32) const;
|
||||
};
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -34,7 +34,7 @@ void CBoneTracking::PreRender(const CStateManager& mgr, CAnimData& animData, con
|
|||
if (x14_segId == 0)
|
||||
return;
|
||||
CHierarchyPoseBuilder& pb = animData.PoseBuilder();
|
||||
TCastToConstPtr<CPatterned> targetAct = mgr.GetObjectById(x34_target);
|
||||
TCastToConstPtr<CActor> targetAct = mgr.GetObjectById(x34_target);
|
||||
if (x36_24_active && tracking && (targetAct || x24_targetPosition)) {
|
||||
x36_25_hasTrackedRotation = true;
|
||||
auto layoutInfo = pb.CharLayoutInfo();
|
||||
|
|
|
@ -100,7 +100,7 @@ CAssetId CCharacterFactory::GetEventResourceIdForAnimResourceId(CAssetId id) con
|
|||
return search->second;
|
||||
}
|
||||
|
||||
const CAdditiveAnimationInfo& CCharacterFactory::FindAdditiveInfo(u32 idx) const {
|
||||
const CAdditiveAnimationInfo& CCharacterFactory::FindAdditiveInfo(s32 idx) const {
|
||||
auto search = rstl::binary_find(x40_additiveInfo.cbegin(), x40_additiveInfo.cend(), idx,
|
||||
[](const auto& anim) { return anim.first; });
|
||||
|
||||
|
@ -109,7 +109,7 @@ const CAdditiveAnimationInfo& CCharacterFactory::FindAdditiveInfo(u32 idx) const
|
|||
return search->second;
|
||||
}
|
||||
|
||||
bool CCharacterFactory::HasAdditiveInfo(u32 idx) const {
|
||||
bool CCharacterFactory::HasAdditiveInfo(s32 idx) const {
|
||||
auto search = rstl::binary_find(x40_additiveInfo.cbegin(), x40_additiveInfo.cend(), idx,
|
||||
[](const auto& anim) { return anim.first; });
|
||||
return search != x40_additiveInfo.cend();
|
||||
|
|
|
@ -65,8 +65,8 @@ public:
|
|||
CAssetId GetEventResourceIdForAnimResourceId(CAssetId animId) const;
|
||||
|
||||
const CCharacterInfo& GetCharInfo(int charIdx) const { return x4_charInfoDB[charIdx]; }
|
||||
const CAdditiveAnimationInfo& FindAdditiveInfo(u32 idx) const;
|
||||
bool HasAdditiveInfo(u32 idx) const;
|
||||
const CAdditiveAnimationInfo& FindAdditiveInfo(s32 idx) const;
|
||||
bool HasAdditiveInfo(s32 idx) const;
|
||||
};
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -47,7 +47,7 @@ void CGroundMovement::MoveGroundCollider(CStateManager& mgr, CPhysicsActor& acto
|
|||
mgr.BuildColliderList(useColliderList, actor, motionVol);
|
||||
CAreaCollisionCache cache(motionVol);
|
||||
float collideDt = dt;
|
||||
if (actor.GetCollisionPrimitive()->GetPrimType() == FOURCC('OBTG')) {
|
||||
if (actor.GetCollisionPrimitive()->GetPrimType() != FOURCC('OBTG')) {
|
||||
CGameCollision::BuildAreaCollisionCache(mgr, cache);
|
||||
if (deltaMag > 0.5f * CGameCollision::GetMinExtentForCollisionPrimitive(*actor.GetCollisionPrimitive())) {
|
||||
zeus::CVector3f point = actor.GetCollisionPrimitive()->CalculateAABox(actor.GetPrimitiveTransform()).center();
|
||||
|
@ -59,6 +59,8 @@ void CGroundMovement::MoveGroundCollider(CStateManager& mgr, CPhysicsActor& acto
|
|||
collideDt = dt * (result.GetT() / deltaMag);
|
||||
newState = actor.PredictMotion_Internal(collideDt);
|
||||
}
|
||||
}
|
||||
}
|
||||
actor.MoveCollisionPrimitive(newState.x0_translation);
|
||||
if (CGameCollision::DetectCollision_Cached(mgr, cache, *actor.GetCollisionPrimitive(),
|
||||
actor.GetPrimitiveTransform(), actor.GetMaterialFilter(),
|
||||
|
@ -107,8 +109,6 @@ void CGroundMovement::MoveGroundCollider(CStateManager& mgr, CPhysicsActor& acto
|
|||
if (actor.GetMaterialList().HasMaterial(EMaterialTypes::Player)) {
|
||||
CGameCollision::CollisionFailsafe(mgr, cache, actor, *actor.GetCollisionPrimitive(), useColliderList, 0.f, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CGroundMovement::ResolveUpDown(CAreaCollisionCache& cache, CStateManager& mgr, CPhysicsActor& actor,
|
||||
|
|
|
@ -19,10 +19,6 @@ class CHierarchyPoseBuilder {
|
|||
CSegId x1_sibling = 0;
|
||||
zeus::CQuaternion x4_rotation;
|
||||
zeus::CVector3f x14_offset;
|
||||
CTreeNode() = default;
|
||||
CTreeNode(const zeus::CVector3f& offset) : x14_offset(offset) {}
|
||||
CTreeNode(const zeus::CQuaternion& quat) : x4_rotation(quat) {}
|
||||
CTreeNode(const zeus::CQuaternion& quat, const zeus::CVector3f& offset) : x4_rotation(quat), x14_offset(offset) {}
|
||||
};
|
||||
TSegIdMap<CTreeNode> x38_treeMap;
|
||||
|
||||
|
|
|
@ -13,30 +13,67 @@ void CIkChain::Update(float dt) {
|
|||
void CIkChain::Deactivate() { x44_24_activated = false; }
|
||||
|
||||
void CIkChain::Activate(const CAnimData& animData, const CSegId& segId, const zeus::CTransform& xf) {
|
||||
// const CHierarchyPoseBuilder& posBuilder = animData.GetPoseBuilder();
|
||||
x0_ = segId;
|
||||
|
||||
// const TLockedToken<CCharLayoutInfo>& info = posBuilder.CharLayoutInfo();
|
||||
x0_bone = segId;
|
||||
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;
|
||||
x4_p2p1Dir = info->GetFromParentUnrotated(x1_p1);
|
||||
x1c_p2p1Length = x4_p2p1Dir.magnitude();
|
||||
x4_p2p1Dir = x4_p2p1Dir / x1c_p2p1Length;
|
||||
x10_p1BoneDir = info->GetFromParentUnrotated(x0_bone);
|
||||
x20_p1BoneLength = x10_p1BoneDir.magnitude();
|
||||
x10_p1BoneDir = x10_p1BoneDir / x20_p1BoneLength;
|
||||
x34_holdPos = xf.origin;
|
||||
x24_holdRot = zeus::CQuaternion(xf.basis);
|
||||
x44_24_activated = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CIkChain::PreRender(CAnimData& animData, const zeus::CTransform& xf, const zeus::CVector3f& scale) {}
|
||||
void CIkChain::PreRender(CAnimData& animData, const zeus::CTransform& xf, const zeus::CVector3f& scale) {
|
||||
if (x40_time > 0.f) {
|
||||
zeus::CTransform p2Xf = animData.GetLocatorTransform(x2_p2, nullptr);
|
||||
zeus::CVector3f localDelta = xf.transposeRotate(x34_holdPos - xf.origin);
|
||||
localDelta /= scale;
|
||||
localDelta = p2Xf.transposeRotate(localDelta - p2Xf.origin);
|
||||
zeus::CQuaternion p2Rot = animData.PoseBuilder().GetTreeMap()[x2_p2].x4_rotation;
|
||||
zeus::CQuaternion p1Rot = animData.PoseBuilder().GetTreeMap()[x1_p1].x4_rotation;
|
||||
zeus::CQuaternion boneRot = animData.PoseBuilder().GetTreeMap()[x0_bone].x4_rotation;
|
||||
zeus::CQuaternion newP2Rot = p2Rot;
|
||||
zeus::CQuaternion newP1Rot = p1Rot;
|
||||
Solve(newP2Rot, newP1Rot, localDelta);
|
||||
zeus::CQuaternion newBoneRot =
|
||||
(zeus::CQuaternion((xf * p2Xf).basis) * p2Rot.inverse() * newP2Rot * newP1Rot).inverse() * x24_holdRot;
|
||||
if (x40_time < 1.f) {
|
||||
newP2Rot = zeus::CQuaternion::slerpShort(p2Rot, newP2Rot, x40_time);
|
||||
newP1Rot = zeus::CQuaternion::slerpShort(p1Rot, newP1Rot, x40_time);
|
||||
newBoneRot = zeus::CQuaternion::slerpShort(boneRot, newBoneRot, x40_time);
|
||||
}
|
||||
animData.PoseBuilder().GetTreeMap()[x2_p2].x4_rotation = newP2Rot;
|
||||
animData.PoseBuilder().GetTreeMap()[x1_p1].x4_rotation = newP1Rot;
|
||||
animData.PoseBuilder().GetTreeMap()[x0_bone].x4_rotation = newBoneRot;
|
||||
animData.MarkPoseDirty();
|
||||
}
|
||||
}
|
||||
|
||||
void CIkChain::Solve(zeus::CQuaternion& q1, zeus::CQuaternion& q2, const zeus::CVector3f& vec) {
|
||||
const float mag = vec.magnitude();
|
||||
const float magSq = mag * mag;
|
||||
const float twoMag = (2.0f * mag);
|
||||
float f29 = std::acos(zeus::clamp(-1.f, (((x20_ * magSq) + x20_) - (x1c_ * x1c_)) / (twoMag * x20_), 1.f));
|
||||
float f30 = std::acos(zeus::clamp(-1.f, ((x1c_ * (magSq - (x20_ * x20_))) + x1c_) / (twoMag * x1c_), 1.f));
|
||||
float f29 = std::acos(zeus::clamp(-1.f, (((x20_p1BoneLength * magSq) + x20_p1BoneLength) -
|
||||
(x1c_p2p1Length * x1c_p2p1Length)) / (twoMag * x20_p1BoneLength), 1.f));
|
||||
float f30 = std::acos(zeus::clamp(-1.f, ((x1c_p2p1Length * (magSq - (x20_p1BoneLength * x20_p1BoneLength))) +
|
||||
x1c_p2p1Length) / (twoMag * x1c_p2p1Length), 1.f));
|
||||
|
||||
zeus::CVector3f vecA = q2.transform(x10_);
|
||||
zeus::CVector3f crossVecA = x4_.cross(vecA);
|
||||
zeus::CVector3f vecA = q2.transform(x10_p1BoneDir);
|
||||
zeus::CVector3f crossVecA = x4_p2p1Dir.cross(vecA);
|
||||
float crossAMag = crossVecA.magnitude();
|
||||
crossVecA *= zeus::CVector3f(1.f / crossVecA.magnitude());
|
||||
float angle = std::asin(zeus::min(crossAMag, 1.f));
|
||||
if (x4_.dot(vecA) < 0.f)
|
||||
if (x4_p2p1Dir.dot(vecA) < 0.f)
|
||||
angle = M_PIF - angle;
|
||||
q2 = zeus::CQuaternion::fromAxisAngle(crossVecA, (f30 + f29) - angle) * q2;
|
||||
zeus::CVector3f v1 = q1.transform((x1c_ * x4_) + (x20_ * q2.transform(x10_)));
|
||||
zeus::CVector3f v1 = q1.transform((x1c_p2p1Length * x4_p2p1Dir) + (x20_p1BoneLength * q2.transform(x10_p1BoneDir)));
|
||||
zeus::CVector3f v2 = q1.transform(vec);
|
||||
zeus::CVector3f crossVecB = v1.normalized().cross((1.f / mag) * v2);
|
||||
angle = std::asin(zeus::min(crossVecB.magnitude(), 1.f));
|
||||
|
|
|
@ -10,15 +10,15 @@ namespace urde {
|
|||
class CAnimData;
|
||||
class CSegId;
|
||||
class CIkChain {
|
||||
CSegId x0_;
|
||||
CSegId x1_;
|
||||
CSegId x2_;
|
||||
zeus::CVector3f x4_ = zeus::CVector3f::skForward;
|
||||
zeus::CVector3f x10_ = zeus::CVector3f::skForward;
|
||||
float x1c_ = 1.f;
|
||||
float x20_ = 1.f;
|
||||
zeus::CQuaternion x24_;
|
||||
zeus::CVector3f x34_;
|
||||
CSegId x0_bone;
|
||||
CSegId x1_p1;
|
||||
CSegId x2_p2;
|
||||
zeus::CVector3f x4_p2p1Dir = zeus::CVector3f::skForward;
|
||||
zeus::CVector3f x10_p1BoneDir = zeus::CVector3f::skForward;
|
||||
float x1c_p2p1Length = 1.f;
|
||||
float x20_p1BoneLength = 1.f;
|
||||
zeus::CQuaternion x24_holdRot;
|
||||
zeus::CVector3f x34_holdPos;
|
||||
float x40_time = 0.f;
|
||||
|
||||
union {
|
||||
|
|
|
@ -7,9 +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];
|
||||
if (link.first != 0xff || link.second != 0xff)
|
||||
return true;
|
||||
return false;
|
||||
return link.first != 0xff || link.second != 0xff;
|
||||
}
|
||||
|
||||
void CPoseAsTransforms::Clear() {
|
||||
|
@ -25,21 +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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
return xd0_transformArr[link.second].m_originToAccum.basis;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace urde {
|
|||
class CCharLayoutInfo;
|
||||
|
||||
class CPoseAsTransforms {
|
||||
friend class CAnimData;
|
||||
public:
|
||||
struct Transform {
|
||||
zeus::CTransform m_originToAccum;
|
||||
|
|
|
@ -308,7 +308,7 @@ void FilterByClosestNormal(const zeus::CVector3f& norm, const CCollisionInfoList
|
|||
}
|
||||
|
||||
if (idx != -1)
|
||||
out.Add(in.GetItem(i), false);
|
||||
out.Add(in.GetItem(idx), false);
|
||||
}
|
||||
|
||||
static const zeus::CVector3f AABBNormalTable[] = {{-1.f, 0.f, 0.f}, {1.f, 0.f, 0.f}, {0.f, -1.f, 0.f},
|
||||
|
|
|
@ -20,7 +20,7 @@ class CPoseAsTransforms;
|
|||
class CModel;
|
||||
|
||||
struct CModelFlags {
|
||||
u8 x0_blendMode = 0; /* >6: additive, >4: blend, else opaque */
|
||||
u8 x0_blendMode = 0; /* 2: add color, >6: additive, >4: blend, else opaque */
|
||||
u8 x1_matSetIdx = 0;
|
||||
EExtendedShader m_extendedShader = EExtendedShader::Lighting;
|
||||
bool m_noCull = false;
|
||||
|
|
|
@ -957,6 +957,7 @@ boo::ObjToken<boo::IGraphicsBufferD> CBooModel::UpdateUniformData(const CModelFl
|
|||
lightingOut.colorRegs[1] = CGraphics::g_ColorRegs[1];
|
||||
lightingOut.colorRegs[2] = CGraphics::g_ColorRegs[2];
|
||||
lightingOut.mulColor = flags.x4_color;
|
||||
lightingOut.ambient += flags.addColor;
|
||||
lightingOut.fog = CGraphics::g_Fog;
|
||||
}
|
||||
|
||||
|
|
|
@ -943,8 +943,8 @@ void CSamusHud::UpdateHudDamage(float dt, const CStateManager& mgr, DataSpec::IT
|
|||
x44c_hudLagShakeRot.rotateZ(rand() / float(RAND_MAX) * rotAng);
|
||||
zeus::CVector3f vecs[] = {zeus::CVector3f::skRight, zeus::CVector3f::skForward, zeus::CVector3f::skUp};
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
int sel = int(rand() / float(RAND_MAX) * 9.f);
|
||||
vecs[sel & 0x3][(sel / 3) & 0x3] += (rand() / float(RAND_MAX) - dt) * rotMul;
|
||||
int sel = rand() % 9;
|
||||
vecs[sel % 3][sel / 3] += (rand() / float(RAND_MAX) - dt) * rotMul;
|
||||
}
|
||||
x428_decoShakeRotate = zeus::CMatrix3f(vecs[0], vecs[1], vecs[2]).transposed();
|
||||
transformUpdate = true;
|
||||
|
|
|
@ -155,7 +155,7 @@ void CPirateRagDoll::PreRender(const zeus::CVector3f& v, CModelData& mData) {
|
|||
aData->PoseBuilder().GetTreeMap()[rootId].x4_rotation = _a4;
|
||||
if (x6c_spacePirate->x7b4_attachedActor == kInvalidUniqueId) {
|
||||
zeus::CVector3f _b0 = aData->GetCharLayoutInfo().GetFromParentUnrotated(x4_particles[1].GetBone());
|
||||
aData->PoseBuilder().GetTreeMap()[x4_particles[1].GetBone()] = zeus::CQuaternion::shortestRotationArc(
|
||||
aData->PoseBuilder().GetTreeMap()[x4_particles[1].GetBone()].x4_rotation = zeus::CQuaternion::shortestRotationArc(
|
||||
_b0, _a4.inverse().transform(x4_particles[1].GetPosition() - x4_particles[0].GetPosition()));
|
||||
}
|
||||
BoneAlign(aData->PoseBuilder(), aData->GetCharLayoutInfo(), 3, 4,
|
||||
|
@ -552,7 +552,7 @@ bool CSpacePirate::FireProjectile(float dt, CStateManager& mgr) {
|
|||
void CSpacePirate::UpdateAttacks(float dt, CStateManager& mgr) {
|
||||
bool reset = true;
|
||||
if ((!x400_25_alive ||
|
||||
(x450_bodyController->GetBodyStateInfo().GetCurrentState()->CanShoot() && x637_29_inWallHang && !x634_27_melee &&
|
||||
(x450_bodyController->GetBodyStateInfo().GetCurrentState()->CanShoot() && x637_25_enableAim && !x634_27_melee &&
|
||||
!x634_25_ceilingAmbush && !x639_26_started && !x450_bodyController->IsElectrocuting())) &&
|
||||
x7c4_burstFire.GetBurstType() != -1) {
|
||||
if (x400_25_alive) {
|
||||
|
@ -1008,7 +1008,7 @@ void CSpacePirate::Touch(CActor& other, CStateManager& mgr) {
|
|||
}
|
||||
|
||||
zeus::CAABox CSpacePirate::GetSortingBounds(const CStateManager& mgr) const {
|
||||
zeus::CAABox aabb = x64_modelData->GetBounds();
|
||||
zeus::CAABox aabb = x64_modelData->GetBounds(x34_transform);
|
||||
zeus::CVector3f radius = aabb.extents() * 0.5f;
|
||||
zeus::CVector3f center = aabb.center();
|
||||
return zeus::CAABox(center - radius, center + radius);
|
||||
|
@ -1280,6 +1280,7 @@ void CSpacePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) {
|
|||
x328_24_inPosition = false;
|
||||
x2dc_destObj = cp->GetUniqueId();
|
||||
x2e0_destPos = cp->GetTranslation();
|
||||
}
|
||||
if (GetSearchPath()->Search(GetTranslation(), x2e0_destPos) == CPathFindSearch::EResult::Success) {
|
||||
x2ec_reflectedDestPos = GetTranslation();
|
||||
x2e0_destPos =
|
||||
|
@ -1352,7 +1353,6 @@ void CSpacePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) {
|
|||
x644_steeringSpeed = 1.f;
|
||||
x639_27_inRange = false;
|
||||
x63a_24_normalDodge = true;
|
||||
}
|
||||
break;
|
||||
case EStateMsg::Update:
|
||||
CPatterned::PathFind(mgr, msg, dt);
|
||||
|
|
|
@ -67,6 +67,8 @@ CAiFuncMap::CAiFuncMap() {
|
|||
x10_triggerFuncs["OffLine"] = &CAi::OffLine;
|
||||
x10_triggerFuncs["Attacked"] = &CAi::Attacked;
|
||||
x10_triggerFuncs["PathShagged"] = &CAi::PathShagged;
|
||||
x10_triggerFuncs["PathOver"] = &CAi::PathOver;
|
||||
x10_triggerFuncs["PathFound"] = &CAi::PathFound;
|
||||
x10_triggerFuncs["TooClose"] = &CAi::TooClose;
|
||||
x10_triggerFuncs["InRange"] = &CAi::InRange;
|
||||
x10_triggerFuncs["InMaxRange"] = &CAi::InMaxRange;
|
||||
|
|
|
@ -989,6 +989,7 @@ void CGameArea::PostConstructArea() {
|
|||
CAssetId pathId = r.readUint32Big();
|
||||
x12c_postConstructed->x10ac_pathToken = g_SimplePool->GetObj(SObjectTag{FOURCC('PATH'), pathId});
|
||||
x12c_postConstructed->x10bc_pathArea = x12c_postConstructed->x10ac_pathToken.GetObj();
|
||||
x12c_postConstructed->x10bc_pathArea->SetTransform(xc_transform);
|
||||
++secIt;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,11 @@ bool CPFAreaOctree::IsPointInsidePaddedAABox(const zeus::CVector3f& point, float
|
|||
point.z() >= x4_aabb.min.z() - padding && point.z() <= x4_aabb.max.z() + padding;
|
||||
}
|
||||
|
||||
CPFOpenList::CPFOpenList() {
|
||||
x40_region.SetData(&x90_regionData);
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CPFOpenList::Clear() {
|
||||
x40_region.Data()->SetOpenMore(&x40_region);
|
||||
x40_region.Data()->SetOpenLess(&x40_region);
|
||||
|
|
|
@ -48,6 +48,7 @@ class CPFOpenList {
|
|||
CPFRegionData x90_regionData;
|
||||
|
||||
public:
|
||||
CPFOpenList();
|
||||
void Clear();
|
||||
void Push(CPFRegion* reg);
|
||||
CPFRegion* Pop();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "CPathFindSearch.hpp"
|
||||
#include "Graphics/CGraphics.hpp"
|
||||
|
||||
namespace urde {
|
||||
|
||||
|
@ -348,4 +349,17 @@ bool CPathFindSearch::Search(rstl::reserved_vector<CPFRegion*, 4>& regs1, const
|
|||
return reg != nullptr;
|
||||
}
|
||||
|
||||
void CPathFindVisualizer::Draw(const CPathFindSearch& path) {
|
||||
m_spline.Reset();
|
||||
for (const auto& wp : path.GetWaypoints())
|
||||
m_spline.AddVertex(wp, zeus::CColor::skBlue, 2.f);
|
||||
m_spline.Render();
|
||||
}
|
||||
|
||||
void CPathFindSearch::DebugDraw() const {
|
||||
if (!m_viz)
|
||||
m_viz.emplace();
|
||||
m_viz->Draw(*this);
|
||||
}
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -2,8 +2,16 @@
|
|||
|
||||
#include "RetroTypes.hpp"
|
||||
#include "CPathFindArea.hpp"
|
||||
#include "Graphics/CLineRenderer.hpp"
|
||||
|
||||
namespace urde {
|
||||
class CPathFindSearch;
|
||||
|
||||
class CPathFindVisualizer {
|
||||
CLineRenderer m_spline = {CLineRenderer::EPrimitiveMode::LineStrip, 16, {}, true};
|
||||
public:
|
||||
void Draw(const CPathFindSearch& path);
|
||||
};
|
||||
|
||||
class CPathFindSearch {
|
||||
public:
|
||||
|
@ -19,6 +27,7 @@ private:
|
|||
float xd8_padding = 10.f;
|
||||
u32 xdc_flags; // 0x2: flyer, 0x4: path-always-exists (swimmers)
|
||||
u32 xe0_indexMask;
|
||||
mutable std::experimental::optional<CPathFindVisualizer> m_viz;
|
||||
bool Search(rstl::reserved_vector<CPFRegion*, 4>& regs1, const zeus::CVector3f& p1,
|
||||
rstl::reserved_vector<CPFRegion*, 4>& regs2, const zeus::CVector3f& p2);
|
||||
void GetSplinePoint(zeus::CVector3f& pOut, const zeus::CVector3f& p1, u32 wpIdx) const;
|
||||
|
@ -43,6 +52,7 @@ public:
|
|||
float GetCharacterHeight() const { return xd0_chHeight; }
|
||||
void SetCharacterHeight(float h) { xd0_chHeight = h; }
|
||||
float RemainingPathDistance(const zeus::CVector3f& pos) const;
|
||||
void DebugDraw() const;
|
||||
};
|
||||
|
||||
} // namespace urde
|
||||
|
|
|
@ -1501,7 +1501,9 @@ void CPatterned::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) {
|
|||
/* Being damaged */
|
||||
zeus::CColor col2 = col;
|
||||
col2.a() = alpha / 255.f;
|
||||
xb4_drawFlags = CModelFlags(2, 0, 3, col2);
|
||||
xb4_drawFlags = CModelFlags(2, 0, 3, zeus::CColor::skWhite);
|
||||
/* Make color additive */
|
||||
xb4_drawFlags.addColor = col2;
|
||||
} else {
|
||||
xb4_drawFlags = CModelFlags(0, 0, 3, zeus::CColor::skWhite);
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@ void CStateMachineState::Update(CStateManager& mgr, CAi& ai, float delta) {
|
|||
if (andPassed && state) {
|
||||
x4_state->CallFunc(mgr, ai, EStateMsg::Deactivate, 0.f);
|
||||
x4_state = state;
|
||||
printf("%s %d\n", state->xc_name, int(state - x0_machine->GetStateVector().data()));
|
||||
x8_time = 0.f;
|
||||
x18_24_codeTrigger = false;
|
||||
xc_random = mgr.GetActiveRandom()->Float();
|
||||
|
|
2
specter
2
specter
|
@ -1 +1 @@
|
|||
Subproject commit f81efb25b53e90cf9e77c06a09095a433929ddb4
|
||||
Subproject commit e86cce5a6f6ad0182d9d2e01fb31bac47f4df882
|
Loading…
Reference in New Issue