Space pirate bug fixes

This commit is contained in:
Jack Andersen 2018-12-14 20:29:41 -10:00
parent ccf87925b9
commit dac8fc3eb5
32 changed files with 294 additions and 210 deletions

View File

@ -212,7 +212,7 @@ struct HealthInfo : BigDNA {
AT_DECL_DNA_YAML AT_DECL_DNA_YAML
Value<atUint32> propertyCount; Value<atUint32> propertyCount;
Value<float> health SPECTER_PROPERTY("Health", "Base health for object"); 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", ""); } SPECTER_PROPERTY("Health Info", "");
struct LightParameters : BigDNA { struct LightParameters : BigDNA {

View File

@ -56,6 +56,7 @@
#include "hecl/CVarManager.hpp" #include "hecl/CVarManager.hpp"
#include "World/CPatterned.hpp" #include "World/CPatterned.hpp"
#include "World/CDestroyableRock.hpp" #include "World/CDestroyableRock.hpp"
#include "World/CPathFindSearch.hpp"
#include <cmath> #include <cmath>
namespace urde { 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 { void CStateManager::RenderCamerasAndAreaLights() const {
x870_cameraManager->RenderCameras(*this); x870_cameraManager->RenderCameras(*this);
@ -1558,8 +1567,8 @@ bool CStateManager::ApplyLocalDamage(const zeus::CVector3f& pos, const zeus::CVe
} }
float newHp = hInfo->GetHP() - mulDam; float newHp = hInfo->GetHP() - mulDam;
hInfo->SetHP(newHp);
bool significant = std::fabs(newHp - hInfo->GetHP()) >= 0.00001; bool significant = std::fabs(newHp - hInfo->GetHP()) >= 0.00001;
hInfo->SetHP(newHp);
if (player && GetPlayerState()->CanTakeDamage()) { if (player && GetPlayerState()->CanTakeDamage()) {
player->TakeDamage(significant, pos, mulDam, weapMode.GetType(), *this); player->TakeDamage(significant, pos, mulDam, weapMode.GetType(), *this);

View File

@ -108,7 +108,7 @@ CAssetId CAnimData::GetEventResourceIdForAnimResourceId(CAssetId id) const {
} }
void CAnimData::AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet) { 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) if (additive.second.GetTargetWeight() > 0.00001f)
additive.second.AddToSegStatementSet(list, *xcc_layoutData.GetObj(), stSet); additive.second.AddToSegStatementSet(list, *xcc_layoutData.GetObj(), stSet);
} }
@ -126,7 +126,7 @@ SAdvancementDeltas CAnimData::AdvanceAdditiveAnims(float dt) {
SAdvancementDeltas deltas = {}; SAdvancementDeltas deltas = {};
for (std::pair<u32, CAdditiveAnimPlayback>& additive : x434_additiveAnims) { for (auto& additive : x434_additiveAnims) {
std::shared_ptr<CAnimTreeNode>& anim = additive.second.GetAnim(); std::shared_ptr<CAnimTreeNode>& anim = additive.second.GetAnim();
if (additive.second.IsActive()) { if (additive.second.IsActive()) {
while (time.GreaterThanZero() && std::fabs(time.GetSeconds()) >= 0.00001f) { while (time.GreaterThanZero() && std::fabs(time.GetSeconds()) >= 0.00001f) {
@ -181,72 +181,73 @@ SAdvancementDeltas CAnimData::UpdateAdditiveAnims(float dt) {
return AdvanceAdditiveAnims(dt); return AdvanceAdditiveAnims(dt);
} }
bool CAnimData::IsAdditiveAnimation(u32 idx) const { bool CAnimData::IsAdditiveAnimation(s32 idx) const {
u32 animIdx = xc_charInfo.GetAnimationIndex(idx); s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
return x0_charFactory->HasAdditiveInfo(animIdx); 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 = auto search =
std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(), 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 search != x434_additiveAnims.cend();
return false;
return true;
} }
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 = auto search =
std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(), 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(); return search->second.GetAnim();
} }
bool CAnimData::IsAdditiveAnimationActive(u32 idx) const { bool CAnimData::IsAdditiveAnimationActive(s32 idx) const {
s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
auto search = auto search =
std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(), 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()) if (search == x434_additiveAnims.cend())
return false; return false;
return search->second.IsActive(); return search->second.IsActive();
} }
void CAnimData::DelAdditiveAnimation(s32 idx) { void CAnimData::DelAdditiveAnimation(s32 idx) {
u32 animIdx = xc_charInfo.GetAnimationIndex(idx); s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
for (std::pair<u32, CAdditiveAnimPlayback>& anim : x434_additiveAnims) { auto search =
if (anim.first == animIdx && anim.second.GetPhase() != EAdditivePlaybackPhase::FadingOut && std::find_if(x434_additiveAnims.begin(), x434_additiveAnims.end(),
anim.second.GetPhase() != EAdditivePlaybackPhase::FadedOut) { [animIdx](const auto& pair) { return pair.first == animIdx; });
anim.second.FadeOut(); if (search != x434_additiveAnims.cend() &&
return; search->second.GetPhase() != EAdditivePlaybackPhase::FadingOut &&
} search->second.GetPhase() != EAdditivePlaybackPhase::FadedOut) {
search->second.FadeOut();
} }
} }
void CAnimData::AddAdditiveAnimation(s32 idx, float weight, bool active, bool fadeOut) { void CAnimData::AddAdditiveAnimation(s32 idx, float weight, bool active, bool fadeOut) {
u32 animIdx = xc_charInfo.GetAnimationIndex(idx); s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
for (std::pair<u32, CAdditiveAnimPlayback>& anim : x434_additiveAnims) { auto search =
if (anim.first == animIdx && anim.second.GetPhase() != EAdditivePlaybackPhase::FadingOut && std::find_if(x434_additiveAnims.begin(), x434_additiveAnims.end(),
anim.second.GetPhase() != EAdditivePlaybackPhase::FadedOut) { [animIdx](const auto& pair) { return pair.first == animIdx; });
anim.second.SetActive(active); if (search != x434_additiveAnims.cend()) {
anim.second.SetWeight(weight); search->second.SetActive(active);
anim.second.SetNeedsFadeOut(!anim.second.IsActive() && fadeOut); search->second.SetWeight(weight);
return; search->second.SetNeedsFadeOut(!search->second.IsActive() && fadeOut);
} } else {
} std::shared_ptr<CAnimTreeNode> node =
std::shared_ptr<CAnimTreeNode> node =
GetAnimationManager()->GetAnimationTree(animIdx, CMetaAnimTreeBuildOrders::NoSpecialOrders()); GetAnimationManager()->GetAnimationTree(animIdx, CMetaAnimTreeBuildOrders::NoSpecialOrders());
const CAdditiveAnimationInfo& info = x0_charFactory->FindAdditiveInfo(animIdx);
const CAdditiveAnimationInfo& info = x0_charFactory->FindAdditiveInfo(animIdx); x434_additiveAnims.emplace_back(std::make_pair(animIdx, CAdditiveAnimPlayback(node, weight, active, info, fadeOut)));
x434_additiveAnims.emplace_back(std::make_pair(idx, CAdditiveAnimPlayback(node, weight, active, info, fadeOut))); }
} }
float CAnimData::GetAdditiveAnimationWeight(u32 idx) const { float CAnimData::GetAdditiveAnimationWeight(s32 idx) const {
u32 animIdx = xc_charInfo.GetAnimationIndex(idx); s32 animIdx = xc_charInfo.GetAnimationIndex(idx);
for (const std::pair<u32, CAdditiveAnimPlayback>& anim : x434_additiveAnims) { auto search =
if (anim.first == animIdx) std::find_if(x434_additiveAnims.cbegin(), x434_additiveAnims.cend(),
return anim.second.GetTargetWeight(); [animIdx](const auto& pair) { return pair.first == animIdx; });
} if (search != x434_additiveAnims.cend())
return search->second.GetTargetWeight();
return 0.f; return 0.f;
} }
@ -618,13 +619,13 @@ void CAnimData::SetAnimation(const CAnimPlaybackParms& parms, bool noTrans) {
x200_speedScale = 1.f; x200_speedScale = 1.f;
x208_defaultAnim = parms.GetAnimationId(); x208_defaultAnim = parms.GetAnimationId();
u32 animIdxA = xc_charInfo.GetAnimationIndex(parms.GetAnimationId()); s32 animIdxA = xc_charInfo.GetAnimationIndex(parms.GetAnimationId());
ResetPOILists(); ResetPOILists();
std::shared_ptr<CAnimTreeNode> blendNode; std::shared_ptr<CAnimTreeNode> blendNode;
if (parms.GetSecondAnimationId() != -1) { if (parms.GetSecondAnimationId() != -1) {
u32 animIdxB = xc_charInfo.GetAnimationIndex(parms.GetSecondAnimationId()); s32 animIdxB = xc_charInfo.GetAnimationIndex(parms.GetSecondAnimationId());
std::shared_ptr<CAnimTreeNode> treeA = std::shared_ptr<CAnimTreeNode> treeA =
x100_animMgr->GetAnimationTree(animIdxA, CMetaAnimTreeBuildOrders::NoSpecialOrders()); x100_animMgr->GetAnimationTree(animIdxA, CMetaAnimTreeBuildOrders::NoSpecialOrders());

View File

@ -108,7 +108,7 @@ private:
float x200_speedScale = 1.f; float x200_speedScale = 1.f;
s32 x204_charIdx; s32 x204_charIdx;
u16 x208_defaultAnim; s32 x208_defaultAnim;
u32 x20c_passedBoolCount = 0; u32 x20c_passedBoolCount = 0;
u32 x210_passedIntCount = 0; u32 x210_passedIntCount = 0;
u32 x214_passedParticleCount = 0; u32 x214_passedParticleCount = 0;
@ -133,7 +133,7 @@ private:
CHierarchyPoseBuilder x2fc_poseBuilder; CHierarchyPoseBuilder x2fc_poseBuilder;
CAnimPlaybackParms x40c_playbackParms; 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<CBoolPOINode, 8> g_BoolPOINodes;
static rstl::reserved_vector<CInt32POINode, 16> g_Int32POINodes; static rstl::reserved_vector<CInt32POINode, 16> g_Int32POINodes;
@ -158,14 +158,14 @@ public:
static SAdvancementResults AdvanceAdditiveAnim(std::shared_ptr<CAnimTreeNode>& anim, const CCharAnimTime& time); static SAdvancementResults AdvanceAdditiveAnim(std::shared_ptr<CAnimTreeNode>& anim, const CCharAnimTime& time);
SAdvancementDeltas AdvanceAdditiveAnims(float); SAdvancementDeltas AdvanceAdditiveAnims(float);
SAdvancementDeltas UpdateAdditiveAnims(float); SAdvancementDeltas UpdateAdditiveAnims(float);
bool IsAdditiveAnimation(u32) const; bool IsAdditiveAnimation(s32) const;
bool IsAdditiveAnimationAdded(u32) const; bool IsAdditiveAnimationAdded(s32) const;
const std::shared_ptr<CAnimTreeNode>& GetRootAnimationTree() const { return x1f8_animRoot; } const std::shared_ptr<CAnimTreeNode>& GetRootAnimationTree() const { return x1f8_animRoot; }
const std::shared_ptr<CAnimTreeNode>& GetAdditiveAnimationTree(u32) const; const std::shared_ptr<CAnimTreeNode>& GetAdditiveAnimationTree(s32) const;
bool IsAdditiveAnimationActive(u32) const; bool IsAdditiveAnimationActive(s32) const;
void DelAdditiveAnimation(s32); void DelAdditiveAnimation(s32);
void AddAdditiveAnimation(s32, float, bool, bool); void AddAdditiveAnimation(s32, float, bool, bool);
float GetAdditiveAnimationWeight(u32 idx) const; float GetAdditiveAnimationWeight(s32 idx) const;
std::shared_ptr<CAnimationManager> GetAnimationManager(); std::shared_ptr<CAnimationManager> GetAnimationManager();
const CCharacterInfo& GetCharacterInfo() const { return xc_charInfo; } const CCharacterInfo& GetCharacterInfo() const { return xc_charInfo; }
const CCharLayoutInfo& GetCharLayoutInfo() const { return *xcc_layoutData.GetObj(); } const CCharLayoutInfo& GetCharLayoutInfo() const { return *xcc_layoutData.GetObj(); }
@ -229,6 +229,7 @@ public:
static void FreeCache(); static void FreeCache();
static void InitializeCache(); static void InitializeCache();
CHierarchyPoseBuilder& PoseBuilder() { return x2fc_poseBuilder; } CHierarchyPoseBuilder& PoseBuilder() { return x2fc_poseBuilder; }
const CHierarchyPoseBuilder& GetPoseBuilder() const { return x2fc_poseBuilder; }
const CParticleDatabase& GetParticleDB() const { return x120_particleDB; } const CParticleDatabase& GetParticleDB() const { return x120_particleDB; }
CParticleDatabase& GetParticleDB() { return x120_particleDB; } CParticleDatabase& GetParticleDB() { return x120_particleDB; }
void SetParticleCEXTValue(std::string_view name, int idx, float value); void SetParticleCEXTValue(std::string_view name, int idx, float value);

View File

@ -11,9 +11,9 @@ class CPrimitive;
class CAnimationDatabase { class CAnimationDatabase {
public: 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 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 GetAllUniquePrimitives(std::vector<CPrimitive>&) const = 0;
virtual void GetUniquePrimitivesFromMetaAnim(std::set<CPrimitive>&, std::string_view) const = 0; virtual void GetUniquePrimitivesFromMetaAnim(std::set<CPrimitive>&, std::string_view) const = 0;
}; };

View File

@ -11,11 +11,11 @@ CAnimationDatabaseGame::CAnimationDatabaseGame(const std::vector<CAnimation>& an
x10_anims.emplace_back(anim.GetMetaAnim()); 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(); } 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."; return "Meta-animation name unavailable in Release mode.";
} }

View File

@ -10,9 +10,9 @@ class CAnimationDatabaseGame final : public CAnimationDatabase {
public: public:
CAnimationDatabaseGame(const std::vector<CAnimation>& anims); 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; u32 GetNumMetaAnims() const;
const char* GetMetaAnimName(u32 idx) const; const char* GetMetaAnimName(s32 idx) const;
void GetAllUniquePrimitives(std::vector<CPrimitive>& primsOut) const; void GetAllUniquePrimitives(std::vector<CPrimitive>& primsOut) const;
void GetUniquePrimitivesFromMetaAnim(std::set<CPrimitive>& primsOut, std::string_view name) const; void GetUniquePrimitivesFromMetaAnim(std::set<CPrimitive>& primsOut, std::string_view name) const;
}; };

View File

@ -7,13 +7,13 @@ namespace urde {
const CAnimationDatabaseGame* CAnimationManager::GetAnimationDatabase() const { return x0_animDB.GetObj(); } 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 CMetaAnimTreeBuildOrders& orders) const {
const std::shared_ptr<IMetaAnim>& anim = x0_animDB->GetMetaAnim(animIdx); const std::shared_ptr<IMetaAnim>& anim = x0_animDB->GetMetaAnim(animIdx);
return anim->GetAnimationTree(x8_sysCtx, orders); 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); return x0_animDB->GetMetaAnim(idx);
} }

View File

@ -20,8 +20,8 @@ public:
: x0_animDB(animDB), x8_sysCtx(sysCtx) {} : x0_animDB(animDB), x8_sysCtx(sysCtx) {}
const CAnimationDatabaseGame* GetAnimationDatabase() const; const CAnimationDatabaseGame* GetAnimationDatabase() const;
std::shared_ptr<CAnimTreeNode> GetAnimationTree(u32, const CMetaAnimTreeBuildOrders& orders) const; std::shared_ptr<CAnimTreeNode> GetAnimationTree(s32, const CMetaAnimTreeBuildOrders& orders) const;
const std::shared_ptr<IMetaAnim>& GetMetaAnimation(u32) const; const std::shared_ptr<IMetaAnim>& GetMetaAnimation(s32) const;
}; };
} // namespace urde } // namespace urde

View File

@ -34,7 +34,7 @@ void CBoneTracking::PreRender(const CStateManager& mgr, CAnimData& animData, con
if (x14_segId == 0) if (x14_segId == 0)
return; return;
CHierarchyPoseBuilder& pb = animData.PoseBuilder(); 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)) { if (x36_24_active && tracking && (targetAct || x24_targetPosition)) {
x36_25_hasTrackedRotation = true; x36_25_hasTrackedRotation = true;
auto layoutInfo = pb.CharLayoutInfo(); auto layoutInfo = pb.CharLayoutInfo();

View File

@ -100,7 +100,7 @@ CAssetId CCharacterFactory::GetEventResourceIdForAnimResourceId(CAssetId id) con
return search->second; 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, auto search = rstl::binary_find(x40_additiveInfo.cbegin(), x40_additiveInfo.cend(), idx,
[](const auto& anim) { return anim.first; }); [](const auto& anim) { return anim.first; });
@ -109,7 +109,7 @@ const CAdditiveAnimationInfo& CCharacterFactory::FindAdditiveInfo(u32 idx) const
return search->second; 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, auto search = rstl::binary_find(x40_additiveInfo.cbegin(), x40_additiveInfo.cend(), idx,
[](const auto& anim) { return anim.first; }); [](const auto& anim) { return anim.first; });
return search != x40_additiveInfo.cend(); return search != x40_additiveInfo.cend();

View File

@ -65,8 +65,8 @@ public:
CAssetId GetEventResourceIdForAnimResourceId(CAssetId animId) const; CAssetId GetEventResourceIdForAnimResourceId(CAssetId animId) const;
const CCharacterInfo& GetCharInfo(int charIdx) const { return x4_charInfoDB[charIdx]; } const CCharacterInfo& GetCharInfo(int charIdx) const { return x4_charInfoDB[charIdx]; }
const CAdditiveAnimationInfo& FindAdditiveInfo(u32 idx) const; const CAdditiveAnimationInfo& FindAdditiveInfo(s32 idx) const;
bool HasAdditiveInfo(u32 idx) const; bool HasAdditiveInfo(s32 idx) const;
}; };
} // namespace urde } // namespace urde

View File

@ -47,7 +47,7 @@ void CGroundMovement::MoveGroundCollider(CStateManager& mgr, CPhysicsActor& acto
mgr.BuildColliderList(useColliderList, actor, motionVol); mgr.BuildColliderList(useColliderList, actor, motionVol);
CAreaCollisionCache cache(motionVol); CAreaCollisionCache cache(motionVol);
float collideDt = dt; float collideDt = dt;
if (actor.GetCollisionPrimitive()->GetPrimType() == FOURCC('OBTG')) { if (actor.GetCollisionPrimitive()->GetPrimType() != FOURCC('OBTG')) {
CGameCollision::BuildAreaCollisionCache(mgr, cache); CGameCollision::BuildAreaCollisionCache(mgr, cache);
if (deltaMag > 0.5f * CGameCollision::GetMinExtentForCollisionPrimitive(*actor.GetCollisionPrimitive())) { if (deltaMag > 0.5f * CGameCollision::GetMinExtentForCollisionPrimitive(*actor.GetCollisionPrimitive())) {
zeus::CVector3f point = actor.GetCollisionPrimitive()->CalculateAABox(actor.GetPrimitiveTransform()).center(); zeus::CVector3f point = actor.GetCollisionPrimitive()->CalculateAABox(actor.GetPrimitiveTransform()).center();
@ -59,55 +59,55 @@ void CGroundMovement::MoveGroundCollider(CStateManager& mgr, CPhysicsActor& acto
collideDt = dt * (result.GetT() / deltaMag); collideDt = dt * (result.GetT() / deltaMag);
newState = actor.PredictMotion_Internal(collideDt); newState = actor.PredictMotion_Internal(collideDt);
} }
actor.MoveCollisionPrimitive(newState.x0_translation); }
if (CGameCollision::DetectCollision_Cached(mgr, cache, *actor.GetCollisionPrimitive(), }
actor.GetPrimitiveTransform(), actor.GetMaterialFilter(), actor.MoveCollisionPrimitive(newState.x0_translation);
useColliderList, idDetect, collisionList)) { if (CGameCollision::DetectCollision_Cached(mgr, cache, *actor.GetCollisionPrimitive(),
actor.AddMotionState(newState); actor.GetPrimitiveTransform(), actor.GetMaterialFilter(),
float resolved = 0.f; useColliderList, idDetect, collisionList)) {
if (ResolveUpDown(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList, actor.GetStepUpHeight(), 0.f, actor.AddMotionState(newState);
resolved, collisionList)) { float resolved = 0.f;
actor.SetMotionState(oldState); if (ResolveUpDown(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList, actor.GetStepUpHeight(), 0.f,
MoveGroundColliderXY(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList, collideDt); resolved, collisionList)) {
} actor.SetMotionState(oldState);
MoveGroundColliderXY(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList, collideDt);
}
} else { } else {
actor.AddMotionState(newState); actor.AddMotionState(newState);
} }
float stepDown = actor.GetStepDownHeight(); float stepDown = actor.GetStepDownHeight();
float resolved = 0.f; float resolved = 0.f;
collisionList.Clear(); collisionList.Clear();
TUniqueId stepZId = kInvalidUniqueId; TUniqueId stepZId = kInvalidUniqueId;
if (stepDown >= 0.f) { if (stepDown >= 0.f) {
if (MoveGroundColliderZ(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList, -stepDown, resolved, if (MoveGroundColliderZ(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList, -stepDown, resolved,
collisionList, stepZId)) { collisionList, stepZId)) {
if (collisionList.GetCount() > 0) { if (collisionList.GetCount() > 0) {
CCollisionInfoList filteredList; CCollisionInfoList filteredList;
CollisionUtil::FilterByClosestNormal(zeus::CVector3f{0.f, 0.f, 1.f}, collisionList, filteredList); CollisionUtil::FilterByClosestNormal(zeus::CVector3f{0.f, 0.f, 1.f}, collisionList, filteredList);
if (filteredList.GetCount() > 0) { if (filteredList.GetCount() > 0) {
if (CGameCollision::IsFloor(filteredList.Front().GetMaterialLeft(), if (CGameCollision::IsFloor(filteredList.Front().GetMaterialLeft(),
filteredList.Front().GetNormalLeft())) { filteredList.Front().GetNormalLeft())) {
if (TCastToPtr<CScriptPlatform> plat = mgr.ObjectById(stepZId)) if (TCastToPtr<CScriptPlatform> plat = mgr.ObjectById(stepZId))
mgr.SendScriptMsg(plat.GetPtr(), actor.GetUniqueId(), EScriptObjectMessage::AddPlatformRider); mgr.SendScriptMsg(plat.GetPtr(), actor.GetUniqueId(), EScriptObjectMessage::AddPlatformRider);
CGameCollision::SendMaterialMessage(mgr, filteredList.Front().GetMaterialLeft(), actor); CGameCollision::SendMaterialMessage(mgr, filteredList.Front().GetMaterialLeft(), actor);
mgr.SendScriptMsg(&actor, kInvalidUniqueId, EScriptObjectMessage::OnFloor); mgr.SendScriptMsg(&actor, kInvalidUniqueId, EScriptObjectMessage::OnFloor);
} else { } else {
CheckFalling(actor, mgr, dt); CheckFalling(actor, mgr, dt);
}
}
} }
} }
} else {
CheckFalling(actor, mgr, dt);
}
actor.ClearForcesAndTorques();
actor.MoveCollisionPrimitive(zeus::CVector3f::skZero);
if (actor.GetMaterialList().HasMaterial(EMaterialTypes::Player)) {
CGameCollision::CollisionFailsafe(mgr, cache, actor, *actor.GetCollisionPrimitive(), useColliderList, 0.f, 1);
} }
} }
} else {
CheckFalling(actor, mgr, dt);
}
actor.ClearForcesAndTorques();
actor.MoveCollisionPrimitive(zeus::CVector3f::skZero);
if (actor.GetMaterialList().HasMaterial(EMaterialTypes::Player)) {
CGameCollision::CollisionFailsafe(mgr, cache, actor, *actor.GetCollisionPrimitive(), useColliderList, 0.f, 1);
} }
} }

View File

@ -19,10 +19,6 @@ class CHierarchyPoseBuilder {
CSegId x1_sibling = 0; CSegId x1_sibling = 0;
zeus::CQuaternion x4_rotation; zeus::CQuaternion x4_rotation;
zeus::CVector3f x14_offset; 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; TSegIdMap<CTreeNode> x38_treeMap;

View File

@ -13,30 +13,67 @@ void CIkChain::Update(float dt) {
void CIkChain::Deactivate() { x44_24_activated = false; } void CIkChain::Deactivate() { x44_24_activated = false; }
void CIkChain::Activate(const CAnimData& animData, const CSegId& segId, const zeus::CTransform& xf) { void CIkChain::Activate(const CAnimData& animData, const CSegId& segId, const zeus::CTransform& xf) {
// const CHierarchyPoseBuilder& posBuilder = animData.GetPoseBuilder(); x0_bone = segId;
x0_ = segId; auto info = animData.GetPoseBuilder().CharLayoutInfo();
x1_p1 = info->GetRootNode()->GetBoneMap()[x0_bone].x0_parentId;
// const TLockedToken<CCharLayoutInfo>& info = posBuilder.CharLayoutInfo(); 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) { void CIkChain::Solve(zeus::CQuaternion& q1, zeus::CQuaternion& q2, const zeus::CVector3f& vec) {
const float mag = vec.magnitude(); const float mag = vec.magnitude();
const float magSq = mag * mag; const float magSq = mag * mag;
const float twoMag = (2.0f * 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 f29 = std::acos(zeus::clamp(-1.f, (((x20_p1BoneLength * magSq) + x20_p1BoneLength) -
float f30 = std::acos(zeus::clamp(-1.f, ((x1c_ * (magSq - (x20_ * x20_))) + x1c_) / (twoMag * x1c_), 1.f)); (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 vecA = q2.transform(x10_p1BoneDir);
zeus::CVector3f crossVecA = x4_.cross(vecA); zeus::CVector3f crossVecA = x4_p2p1Dir.cross(vecA);
float crossAMag = crossVecA.magnitude(); float crossAMag = crossVecA.magnitude();
crossVecA *= zeus::CVector3f(1.f / crossVecA.magnitude()); crossVecA *= zeus::CVector3f(1.f / crossVecA.magnitude());
float angle = std::asin(zeus::min(crossAMag, 1.f)); 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; angle = M_PIF - angle;
q2 = zeus::CQuaternion::fromAxisAngle(crossVecA, (f30 + f29) - angle) * q2; 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 v2 = q1.transform(vec);
zeus::CVector3f crossVecB = v1.normalized().cross((1.f / mag) * v2); zeus::CVector3f crossVecB = v1.normalized().cross((1.f / mag) * v2);
angle = std::asin(zeus::min(crossVecB.magnitude(), 1.f)); angle = std::asin(zeus::min(crossVecB.magnitude(), 1.f));

View File

@ -10,15 +10,15 @@ namespace urde {
class CAnimData; class CAnimData;
class CSegId; class CSegId;
class CIkChain { class CIkChain {
CSegId x0_; CSegId x0_bone;
CSegId x1_; CSegId x1_p1;
CSegId x2_; CSegId x2_p2;
zeus::CVector3f x4_ = zeus::CVector3f::skForward; zeus::CVector3f x4_p2p1Dir = zeus::CVector3f::skForward;
zeus::CVector3f x10_ = zeus::CVector3f::skForward; zeus::CVector3f x10_p1BoneDir = zeus::CVector3f::skForward;
float x1c_ = 1.f; float x1c_p2p1Length = 1.f;
float x20_ = 1.f; float x20_p1BoneLength = 1.f;
zeus::CQuaternion x24_; zeus::CQuaternion x24_holdRot;
zeus::CVector3f x34_; zeus::CVector3f x34_holdPos;
float x40_time = 0.f; float x40_time = 0.f;
union { union {

View File

@ -7,9 +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];
if (link.first != 0xff || link.second != 0xff) return link.first != 0xff || link.second != 0xff;
return true;
return false;
} }
void CPoseAsTransforms::Clear() { 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 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);
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);
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);
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);
return xd0_transformArr[link.second].m_originToAccum.basis; return xd0_transformArr[link.second].m_originToAccum.basis;
} }

View File

@ -8,6 +8,7 @@ namespace urde {
class CCharLayoutInfo; class CCharLayoutInfo;
class CPoseAsTransforms { class CPoseAsTransforms {
friend class CAnimData;
public: public:
struct Transform { struct Transform {
zeus::CTransform m_originToAccum; zeus::CTransform m_originToAccum;

View File

@ -308,7 +308,7 @@ void FilterByClosestNormal(const zeus::CVector3f& norm, const CCollisionInfoList
} }
if (idx != -1) 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}, static const zeus::CVector3f AABBNormalTable[] = {{-1.f, 0.f, 0.f}, {1.f, 0.f, 0.f}, {0.f, -1.f, 0.f},

View File

@ -20,7 +20,7 @@ class CPoseAsTransforms;
class CModel; class CModel;
struct CModelFlags { 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; u8 x1_matSetIdx = 0;
EExtendedShader m_extendedShader = EExtendedShader::Lighting; EExtendedShader m_extendedShader = EExtendedShader::Lighting;
bool m_noCull = false; bool m_noCull = false;

View File

@ -957,6 +957,7 @@ boo::ObjToken<boo::IGraphicsBufferD> CBooModel::UpdateUniformData(const CModelFl
lightingOut.colorRegs[1] = CGraphics::g_ColorRegs[1]; lightingOut.colorRegs[1] = CGraphics::g_ColorRegs[1];
lightingOut.colorRegs[2] = CGraphics::g_ColorRegs[2]; lightingOut.colorRegs[2] = CGraphics::g_ColorRegs[2];
lightingOut.mulColor = flags.x4_color; lightingOut.mulColor = flags.x4_color;
lightingOut.ambient += flags.addColor;
lightingOut.fog = CGraphics::g_Fog; lightingOut.fog = CGraphics::g_Fog;
} }

View File

@ -943,8 +943,8 @@ void CSamusHud::UpdateHudDamage(float dt, const CStateManager& mgr, DataSpec::IT
x44c_hudLagShakeRot.rotateZ(rand() / float(RAND_MAX) * rotAng); x44c_hudLagShakeRot.rotateZ(rand() / float(RAND_MAX) * rotAng);
zeus::CVector3f vecs[] = {zeus::CVector3f::skRight, zeus::CVector3f::skForward, zeus::CVector3f::skUp}; zeus::CVector3f vecs[] = {zeus::CVector3f::skRight, zeus::CVector3f::skForward, zeus::CVector3f::skUp};
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
int sel = int(rand() / float(RAND_MAX) * 9.f); int sel = rand() % 9;
vecs[sel & 0x3][(sel / 3) & 0x3] += (rand() / float(RAND_MAX) - dt) * rotMul; vecs[sel % 3][sel / 3] += (rand() / float(RAND_MAX) - dt) * rotMul;
} }
x428_decoShakeRotate = zeus::CMatrix3f(vecs[0], vecs[1], vecs[2]).transposed(); x428_decoShakeRotate = zeus::CMatrix3f(vecs[0], vecs[1], vecs[2]).transposed();
transformUpdate = true; transformUpdate = true;

View File

@ -155,7 +155,7 @@ void CPirateRagDoll::PreRender(const zeus::CVector3f& v, CModelData& mData) {
aData->PoseBuilder().GetTreeMap()[rootId].x4_rotation = _a4; aData->PoseBuilder().GetTreeMap()[rootId].x4_rotation = _a4;
if (x6c_spacePirate->x7b4_attachedActor == kInvalidUniqueId) { if (x6c_spacePirate->x7b4_attachedActor == kInvalidUniqueId) {
zeus::CVector3f _b0 = aData->GetCharLayoutInfo().GetFromParentUnrotated(x4_particles[1].GetBone()); 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())); _b0, _a4.inverse().transform(x4_particles[1].GetPosition() - x4_particles[0].GetPosition()));
} }
BoneAlign(aData->PoseBuilder(), aData->GetCharLayoutInfo(), 3, 4, 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) { void CSpacePirate::UpdateAttacks(float dt, CStateManager& mgr) {
bool reset = true; bool reset = true;
if ((!x400_25_alive || 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())) && !x634_25_ceilingAmbush && !x639_26_started && !x450_bodyController->IsElectrocuting())) &&
x7c4_burstFire.GetBurstType() != -1) { x7c4_burstFire.GetBurstType() != -1) {
if (x400_25_alive) { 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 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 radius = aabb.extents() * 0.5f;
zeus::CVector3f center = aabb.center(); zeus::CVector3f center = aabb.center();
return zeus::CAABox(center - radius, center + radius); return zeus::CAABox(center - radius, center + radius);
@ -1280,46 +1280,46 @@ void CSpacePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) {
x328_24_inPosition = false; x328_24_inPosition = false;
x2dc_destObj = cp->GetUniqueId(); x2dc_destObj = cp->GetUniqueId();
x2e0_destPos = cp->GetTranslation(); x2e0_destPos = cp->GetTranslation();
if (GetSearchPath()->Search(GetTranslation(), x2e0_destPos) == CPathFindSearch::EResult::Success) { }
x2ec_reflectedDestPos = GetTranslation(); if (GetSearchPath()->Search(GetTranslation(), x2e0_destPos) == CPathFindSearch::EResult::Success) {
x2e0_destPos = x2ec_reflectedDestPos = GetTranslation();
(GetSearchPath()->GetCurrentWaypoint() + 1 < GetSearchPath()->GetWaypoints().size()) ? x2e0_destPos =
GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint() + 1] : (GetSearchPath()->GetCurrentWaypoint() + 1 < GetSearchPath()->GetWaypoints().size()) ?
GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint()]; GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint() + 1] :
x328_24_inPosition = false; GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint()];
x450_bodyController->GetCommandMgr().DeliverCmd( x328_24_inPosition = false;
CBCLocomotionCmd(x2e0_destPos - GetTranslation(), zeus::CVector3f::skZero, 1.f)); x450_bodyController->GetCommandMgr().DeliverCmd(
} else { CBCLocomotionCmd(x2e0_destPos - GetTranslation(), zeus::CVector3f::skZero, 1.f));
CScriptAiJumpPoint* bestJp = nullptr; } else {
float minDist = FLT_MAX; CScriptAiJumpPoint* bestJp = nullptr;
for (CEntity* ent : mgr.GetAiWaypointObjectList()) { float minDist = FLT_MAX;
if (TCastToPtr<CScriptAiJumpPoint> jp = ent) { for (CEntity* ent : mgr.GetAiWaypointObjectList()) {
if (jp->GetActive() && !jp->GetInUse(GetUniqueId()) && jp->GetJumpTarget() == kInvalidUniqueId && if (TCastToPtr<CScriptAiJumpPoint> jp = ent) {
GetAreaIdAlways() == jp->GetAreaIdAlways()) { if (jp->GetActive() && !jp->GetInUse(GetUniqueId()) && jp->GetJumpTarget() == kInvalidUniqueId &&
zeus::CVector3f toJp = jp->GetTranslation() - GetTranslation(); GetAreaIdAlways() == jp->GetAreaIdAlways()) {
float f30 = toJp.magSquared(); zeus::CVector3f toJp = jp->GetTranslation() - GetTranslation();
if (f30 > 25.f && jp->GetTransform().basis[1].dot(toJp) > 0.f) { float f30 = toJp.magSquared();
if (TCastToConstPtr<CScriptWaypoint> wp = mgr.GetObjectById(jp->GetJumpPoint())) { if (f30 > 25.f && jp->GetTransform().basis[1].dot(toJp) > 0.f) {
if ((wp->GetTranslation().z() - jp->GetTranslation().z()) * if (TCastToConstPtr<CScriptWaypoint> wp = mgr.GetObjectById(jp->GetJumpPoint())) {
(x2e0_destPos.z() - GetTranslation().z()) > 0.f) { if ((wp->GetTranslation().z() - jp->GetTranslation().z()) *
zeus::CVector3f delta = x2e0_destPos - wp->GetTranslation(); (x2e0_destPos.z() - GetTranslation().z()) > 0.f) {
f30 += 4.f * toJp.z() * toJp.z(); zeus::CVector3f delta = x2e0_destPos - wp->GetTranslation();
f30 += delta.magSquared() + delta.z() * delta.z() * 9.f; f30 += 4.f * toJp.z() * toJp.z();
if (f30 < minDist && f30 += delta.magSquared() + delta.z() * delta.z() * 9.f;
GetSearchPath()->PathExists(GetTranslation(), jp->GetTranslation()) == if (f30 < minDist &&
CPathFindSearch::EResult::Success) { GetSearchPath()->PathExists(GetTranslation(), jp->GetTranslation()) ==
bool r24 = false; CPathFindSearch::EResult::Success) {
auto res = GetSearchPath()->PathExists(wp->GetTranslation(), x2e0_destPos); bool r24 = false;
if (res != CPathFindSearch::EResult::Success) auto res = GetSearchPath()->PathExists(wp->GetTranslation(), x2e0_destPos);
f30 += 1000.f; if (res != CPathFindSearch::EResult::Success)
if (res == CPathFindSearch::EResult::Success) f30 += 1000.f;
r24 = true; if (res == CPathFindSearch::EResult::Success)
if (f30 < minDist) { r24 = true;
minDist = f30; if (f30 < minDist) {
bestJp = jp.GetPtr(); minDist = f30;
if (r24) bestJp = jp.GetPtr();
break; if (r24)
} break;
} }
} }
} }
@ -1327,32 +1327,32 @@ void CSpacePirate::PathFind(CStateManager& mgr, EStateMsg msg, float dt) {
} }
} }
} }
if (bestJp) { }
x2e0_destPos = bestJp->GetTranslation(); if (bestJp) {
if (GetSearchPath()->Search(GetTranslation(), x2e0_destPos) == CPathFindSearch::EResult::Success) { x2e0_destPos = bestJp->GetTranslation();
x2ec_reflectedDestPos = GetTranslation(); if (GetSearchPath()->Search(GetTranslation(), x2e0_destPos) == CPathFindSearch::EResult::Success) {
x2e0_destPos = x2ec_reflectedDestPos = GetTranslation();
(GetSearchPath()->GetCurrentWaypoint() + 1 < GetSearchPath()->GetWaypoints().size()) ? x2e0_destPos =
GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint() + 1] : (GetSearchPath()->GetCurrentWaypoint() + 1 < GetSearchPath()->GetWaypoints().size()) ?
GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint()]; GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint() + 1] :
x328_24_inPosition = false; GetSearchPath()->GetWaypoints()[GetSearchPath()->GetCurrentWaypoint()];
x840_jumpPoint = bestJp->GetUniqueId(); x328_24_inPosition = false;
x824_jumpHeight = bestJp->GetJumpApex(); x840_jumpPoint = bestJp->GetUniqueId();
if (TCastToConstPtr<CScriptWaypoint> wp = mgr.GetObjectById(bestJp->GetJumpPoint())) { x824_jumpHeight = bestJp->GetJumpApex();
x828_patrolDestPos = wp->GetTranslation(); if (TCastToConstPtr<CScriptWaypoint> wp = mgr.GetObjectById(bestJp->GetJumpPoint())) {
x450_bodyController->GetCommandMgr().DeliverCmd( x828_patrolDestPos = wp->GetTranslation();
CBCLocomotionCmd(x2e0_destPos, zeus::CVector3f::skZero, 1.f)); x450_bodyController->GetCommandMgr().DeliverCmd(
x30c_behaviourOrient = EBehaviourOrient::MoveDir; CBCLocomotionCmd(x2e0_destPos, zeus::CVector3f::skZero, 1.f));
} x30c_behaviourOrient = EBehaviourOrient::MoveDir;
} }
} }
} }
x450_bodyController->GetCommandMgr().SetSteeringBlendMode(ESteeringBlendMode::FullSpeed);
if (x637_25_enableAim)
x644_steeringSpeed = 1.f;
x639_27_inRange = false;
x63a_24_normalDodge = true;
} }
x450_bodyController->GetCommandMgr().SetSteeringBlendMode(ESteeringBlendMode::FullSpeed);
if (x637_25_enableAim)
x644_steeringSpeed = 1.f;
x639_27_inRange = false;
x63a_24_normalDodge = true;
break; break;
case EStateMsg::Update: case EStateMsg::Update:
CPatterned::PathFind(mgr, msg, dt); CPatterned::PathFind(mgr, msg, dt);

View File

@ -67,6 +67,8 @@ CAiFuncMap::CAiFuncMap() {
x10_triggerFuncs["OffLine"] = &CAi::OffLine; x10_triggerFuncs["OffLine"] = &CAi::OffLine;
x10_triggerFuncs["Attacked"] = &CAi::Attacked; x10_triggerFuncs["Attacked"] = &CAi::Attacked;
x10_triggerFuncs["PathShagged"] = &CAi::PathShagged; x10_triggerFuncs["PathShagged"] = &CAi::PathShagged;
x10_triggerFuncs["PathOver"] = &CAi::PathOver;
x10_triggerFuncs["PathFound"] = &CAi::PathFound;
x10_triggerFuncs["TooClose"] = &CAi::TooClose; x10_triggerFuncs["TooClose"] = &CAi::TooClose;
x10_triggerFuncs["InRange"] = &CAi::InRange; x10_triggerFuncs["InRange"] = &CAi::InRange;
x10_triggerFuncs["InMaxRange"] = &CAi::InMaxRange; x10_triggerFuncs["InMaxRange"] = &CAi::InMaxRange;

View File

@ -989,6 +989,7 @@ void CGameArea::PostConstructArea() {
CAssetId pathId = r.readUint32Big(); CAssetId pathId = r.readUint32Big();
x12c_postConstructed->x10ac_pathToken = g_SimplePool->GetObj(SObjectTag{FOURCC('PATH'), pathId}); x12c_postConstructed->x10ac_pathToken = g_SimplePool->GetObj(SObjectTag{FOURCC('PATH'), pathId});
x12c_postConstructed->x10bc_pathArea = x12c_postConstructed->x10ac_pathToken.GetObj(); x12c_postConstructed->x10bc_pathArea = x12c_postConstructed->x10ac_pathToken.GetObj();
x12c_postConstructed->x10bc_pathArea->SetTransform(xc_transform);
++secIt; ++secIt;
} }

View File

@ -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; 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() { void CPFOpenList::Clear() {
x40_region.Data()->SetOpenMore(&x40_region); x40_region.Data()->SetOpenMore(&x40_region);
x40_region.Data()->SetOpenLess(&x40_region); x40_region.Data()->SetOpenLess(&x40_region);

View File

@ -48,6 +48,7 @@ class CPFOpenList {
CPFRegionData x90_regionData; CPFRegionData x90_regionData;
public: public:
CPFOpenList();
void Clear(); void Clear();
void Push(CPFRegion* reg); void Push(CPFRegion* reg);
CPFRegion* Pop(); CPFRegion* Pop();

View File

@ -1,4 +1,5 @@
#include "CPathFindSearch.hpp" #include "CPathFindSearch.hpp"
#include "Graphics/CGraphics.hpp"
namespace urde { namespace urde {
@ -348,4 +349,17 @@ bool CPathFindSearch::Search(rstl::reserved_vector<CPFRegion*, 4>& regs1, const
return reg != nullptr; 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 } // namespace urde

View File

@ -2,8 +2,16 @@
#include "RetroTypes.hpp" #include "RetroTypes.hpp"
#include "CPathFindArea.hpp" #include "CPathFindArea.hpp"
#include "Graphics/CLineRenderer.hpp"
namespace urde { namespace urde {
class CPathFindSearch;
class CPathFindVisualizer {
CLineRenderer m_spline = {CLineRenderer::EPrimitiveMode::LineStrip, 16, {}, true};
public:
void Draw(const CPathFindSearch& path);
};
class CPathFindSearch { class CPathFindSearch {
public: public:
@ -19,6 +27,7 @@ private:
float xd8_padding = 10.f; float xd8_padding = 10.f;
u32 xdc_flags; // 0x2: flyer, 0x4: path-always-exists (swimmers) u32 xdc_flags; // 0x2: flyer, 0x4: path-always-exists (swimmers)
u32 xe0_indexMask; u32 xe0_indexMask;
mutable std::experimental::optional<CPathFindVisualizer> m_viz;
bool Search(rstl::reserved_vector<CPFRegion*, 4>& regs1, const zeus::CVector3f& p1, bool Search(rstl::reserved_vector<CPFRegion*, 4>& regs1, const zeus::CVector3f& p1,
rstl::reserved_vector<CPFRegion*, 4>& regs2, const zeus::CVector3f& p2); rstl::reserved_vector<CPFRegion*, 4>& regs2, const zeus::CVector3f& p2);
void GetSplinePoint(zeus::CVector3f& pOut, const zeus::CVector3f& p1, u32 wpIdx) const; void GetSplinePoint(zeus::CVector3f& pOut, const zeus::CVector3f& p1, u32 wpIdx) const;
@ -43,6 +52,7 @@ public:
float GetCharacterHeight() const { return xd0_chHeight; } float GetCharacterHeight() const { return xd0_chHeight; }
void SetCharacterHeight(float h) { xd0_chHeight = h; } void SetCharacterHeight(float h) { xd0_chHeight = h; }
float RemainingPathDistance(const zeus::CVector3f& pos) const; float RemainingPathDistance(const zeus::CVector3f& pos) const;
void DebugDraw() const;
}; };
} // namespace urde } // namespace urde

View File

@ -1501,7 +1501,9 @@ void CPatterned::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) {
/* Being damaged */ /* Being damaged */
zeus::CColor col2 = col; zeus::CColor col2 = col;
col2.a() = alpha / 255.f; 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 { } else {
xb4_drawFlags = CModelFlags(0, 0, 3, zeus::CColor::skWhite); xb4_drawFlags = CModelFlags(0, 0, 3, zeus::CColor::skWhite);
} }

View File

@ -78,6 +78,7 @@ void CStateMachineState::Update(CStateManager& mgr, CAi& ai, float delta) {
if (andPassed && state) { if (andPassed && state) {
x4_state->CallFunc(mgr, ai, EStateMsg::Deactivate, 0.f); x4_state->CallFunc(mgr, ai, EStateMsg::Deactivate, 0.f);
x4_state = state; x4_state = state;
printf("%s %d\n", state->xc_name, int(state - x0_machine->GetStateVector().data()));
x8_time = 0.f; x8_time = 0.f;
x18_24_codeTrigger = false; x18_24_codeTrigger = false;
xc_random = mgr.GetActiveRandom()->Float(); xc_random = mgr.GetActiveRandom()->Float();

@ -1 +1 @@
Subproject commit f81efb25b53e90cf9e77c06a09095a433929ddb4 Subproject commit e86cce5a6f6ad0182d9d2e01fb31bac47f4df882