From c869814da3e2e66a4c1123ef7b7fd766f7586fc8 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Wed, 31 Aug 2016 21:10:08 -0700 Subject: [PATCH] CPhysicsActor imps --- Runtime/World/CActor.cpp | 8 ++ Runtime/World/CActor.hpp | 1 + Runtime/World/CPhysicsActor.cpp | 150 +++++++++++++++++++++++++-- Runtime/World/CPhysicsActor.hpp | 46 ++++++-- Runtime/World/CScriptDistanceFog.cpp | 16 +-- specter | 2 +- 6 files changed, 187 insertions(+), 36 deletions(-) diff --git a/Runtime/World/CActor.cpp b/Runtime/World/CActor.cpp index 3f71cb13d..4c8c893bb 100644 --- a/Runtime/World/CActor.cpp +++ b/Runtime/World/CActor.cpp @@ -293,4 +293,12 @@ void CActor::SetSfxPitchBend(s32 val) CSfxManager::PitchBend(*x8c_sfxHandle.get(), val); } +void CActor::SetTranslation(const zeus::CVector3f &tr) +{ + x34_transform.origin = tr; + xe4_27_ = true; + xe4_28_ = true; + xe4_29_ = true; +} + } diff --git a/Runtime/World/CActor.hpp b/Runtime/World/CActor.hpp index 22dc43711..2411e6249 100644 --- a/Runtime/World/CActor.hpp +++ b/Runtime/World/CActor.hpp @@ -138,6 +138,7 @@ public: bool HasModelData() const; const CSfxHandle* GetSfxHandle() const; void SetSfxPitchBend(s32); + void SetTranslation(const zeus::CVector3f& tr); }; } diff --git a/Runtime/World/CPhysicsActor.cpp b/Runtime/World/CPhysicsActor.cpp index d8070387b..e1177c55a 100644 --- a/Runtime/World/CPhysicsActor.cpp +++ b/Runtime/World/CPhysicsActor.cpp @@ -38,22 +38,22 @@ const CCollisionPrimitive& CPhysicsActor::GetCollisionPrimitive() const return x1c0_collisionPrimitive; } -zeus::CTransform CPhysicsActor::GetPrimitiveTransform() +zeus::CTransform CPhysicsActor::GetPrimitiveTransform() const { - return zeus::CTransform(); + return zeus::CTransform::Translate(x34_transform.origin + x1e8_primitiveOffset); } -float CPhysicsActor::GetStepUpHeight() +float CPhysicsActor::GetStepUpHeight() const { return x23c_stepUpHeight; } -float CPhysicsActor::GetStepDownHeight() +float CPhysicsActor::GetStepDownHeight() const { return x240_stepDownHeight; } -float CPhysicsActor::GetWeight() +float CPhysicsActor::GetWeight() const { return 24.525002f * xe8_mass; } @@ -79,27 +79,69 @@ void CPhysicsActor::SetBoundingBox(const zeus::CAABox &box) MoveCollisionPrimitive(zeus::CVector3f::skZero); } -zeus::CAABox CPhysicsActor::GetMotionVolume() +zeus::CAABox CPhysicsActor::GetMotionVolume(float dt) const { - return {}; + zeus::CAABox aabox = GetCollisionPrimitive().CalculateAABox(GetPrimitiveTransform()); + zeus::CVector3f velocity = CalculateNewVelocityWR_UsingImpulses(); + + const zeus::CVector3f dv = (dt * velocity); + aabox.accumulateBounds(aabox.max + dv); + aabox.accumulateBounds(aabox.min + dv); + + float up = GetStepUpHeight(); + up = zeus::max(up, 0.f); + aabox.accumulateBounds(aabox.max + up); + + float down = GetStepDownHeight(); + down = zeus::max(down, 0.f); + aabox.accumulateBounds(aabox.min + down); + return aabox; +} + +zeus::CVector3f CPhysicsActor::CalculateNewVelocityWR_UsingImpulses() const +{ + return x138_velocity + (xec_massRecip * (x168_ + x18c_)); } zeus::CAABox CPhysicsActor::GetBoundingBox() { - return {}; + return { x1a4_baseBoundingBox.min + x1e8_primitiveOffset + x34_transform.origin, + x1a4_baseBoundingBox.max + x1e8_primitiveOffset + x34_transform.origin }; } -const zeus::CAABox &CPhysicsActor::GetBaseBoundingBox() const +const zeus::CAABox& CPhysicsActor::GetBaseBoundingBox() const { return x1a4_baseBoundingBox; } +void CPhysicsActor::AddMotionState(const CMotionState& mst) +{ + zeus::CNUQuaternion q{x34_transform.buildMatrix3f()}; + // TODO: Jack please verify this assignment: 8011B514 + x34_transform = zeus::CTransform::Translate(x34_transform.origin) * zeus::CMatrix3f(q); + + xe4_27_ = true; + xe4_28_ = true; + xe4_29_ = true; + + SetTranslation(x34_transform.origin + mst.x0_origin); + + x108_ += mst.x1c_; + + ComputeDerivedQuantities(); +} + +CMotionState CPhysicsActor::GetMotionState() const +{ + return {x34_transform.origin, {x34_transform.buildMatrix3f()}, xfc_, x108_}; +} + void CPhysicsActor::SetInertiaTensorScalar(float tensor) { if (tensor <= 0.0f) tensor = 1.0f; - xf0_inertialTensor = tensor; - xf4_inertialTensorRecip = 1.0f / tensor; + xf0_inertiaTensor = tensor; + xf4_inertiaTensorRecip = 1.0f / tensor; } void CPhysicsActor::SetMass(float mass) @@ -113,4 +155,90 @@ void CPhysicsActor::SetMass(float mass) SetInertiaTensorScalar(mass * tensor); } +void CPhysicsActor::SetAngularVelocityOR(const zeus::CAxisAngle& angVel) +{ + x144_angularVelocity = x34_transform.rotate(angVel); + x108_ = xf0_inertiaTensor * x144_angularVelocity; +} + +zeus::CAxisAngle CPhysicsActor::GetAngularVelocityOR() const +{ + return x34_transform.transposeRotate(x144_angularVelocity); +} + +void CPhysicsActor::SetAngularVelocityWR(const zeus::CAxisAngle& angVel) +{ + x144_angularVelocity = angVel; + x108_ = xf0_inertiaTensor * x144_angularVelocity; +} + +void CPhysicsActor::SetVelocityWR(const zeus::CVector3f &vel) +{ + x138_velocity = vel; + xfc_ = xe8_mass * x138_velocity; +} + +void CPhysicsActor::SetVelocityOR(const zeus::CVector3f& vel) +{ + SetVelocityWR(x34_transform.rotate(vel)); +} + +zeus::CVector3f CPhysicsActor::GetTotalForcesWR() const +{ + return x15c_ + x150_; +} + +void CPhysicsActor::RotateInOneFrameOR(const zeus::CQuaternion &q, float d) +{ + x198_ += GetRotateToORAngularMomentumWR(q, d); +} + +zeus::CVector3f CPhysicsActor::GetRotateToORAngularMomentumWR(const zeus::CQuaternion& q, float d) const +{ + if (q.w > 0.99999976) + return zeus::CVector3f::skZero; + return (xf0_inertiaTensor * (((2.f * std::acos(q.w)) * (1.f / d)) * + x34_transform.rotate({q.x, q.y, q.z}).normalized())); +} + +void CPhysicsActor::ClearImpulses() +{ + x18c_ = x168_ = zeus::CVector3f::skZero; + x198_ = x180_ = zeus::CAxisAngle::skZero; +} + +void CPhysicsActor::ClearForcesAndTorques() +{ + x18c_ = x168_ = x15c_ = zeus::CVector3f::skZero; + x198_ = x180_ = x174_ = zeus::CAxisAngle::skZero; +} + +void CPhysicsActor::Stop() +{ + ClearForcesAndTorques(); + xfc_ = zeus::CVector3f::skZero; + x108_ = zeus::CAxisAngle::skZero; + ComputeDerivedQuantities(); +} + +void CPhysicsActor::ComputeDerivedQuantities() +{ + x138_velocity = xec_massRecip * xfc_; + x114_ = x34_transform.buildMatrix3f(); + x144_angularVelocity = xf0_inertiaTensor * x108_; +} + +bool CPhysicsActor::WillMove(const CStateManager&) +{ + if (!zeus::close_enough(zeus::CVector3f::skZero, x138_velocity) || + !zeus::close_enough(zeus::CVector3f::skZero, x168_) || + !zeus::close_enough(zeus::CVector3f::skZero, x18c_) || + !zeus::close_enough(zeus::CVector3f::skZero, x144_angularVelocity) || + !zeus::close_enough(zeus::CVector3f::skZero, x180_) || + !zeus::close_enough(zeus::CVector3f::skZero, GetTotalForcesWR())) + return true; + + return false; +} + } diff --git a/Runtime/World/CPhysicsActor.hpp b/Runtime/World/CPhysicsActor.hpp index 4de6794aa..b98ad83bd 100644 --- a/Runtime/World/CPhysicsActor.hpp +++ b/Runtime/World/CPhysicsActor.hpp @@ -22,7 +22,17 @@ struct SMoverData struct CMotionState { - CMotionState(const zeus::CVector3f&, const zeus::CNUQuaternion&, const zeus::CVector3f&, const zeus::CAxisAngle&); + zeus::CVector3f x0_origin; + zeus::CQuaternion xc_rotation; + zeus::CVector3f x1c_; + zeus::CAxisAngle x28_; + CMotionState(const zeus::CVector3f& origin, const zeus::CNUQuaternion& rotation, + const zeus::CVector3f& v2, const zeus::CAxisAngle& angle) + : x0_origin(origin) + , xc_rotation(rotation) + , x1c_(v2) + , x28_(angle) + {} }; class CPhysicsActor : public CActor @@ -30,15 +40,15 @@ class CPhysicsActor : public CActor protected: float xe8_mass; float xec_massRecip; - float xf0_inertialTensor; - float xf4_inertialTensorRecip; + float xf0_inertiaTensor; + float xf4_inertiaTensorRecip; bool xf8_; bool xf9_; zeus::CVector3f xfc_; zeus::CAxisAngle x108_; zeus::CMatrix3f x114_; - zeus::CVector3f x138_; - zeus::CAxisAngle x144_; + zeus::CVector3f x138_velocity; + zeus::CAxisAngle x144_angularVelocity; zeus::CVector3f x150_; zeus::CVector3f x15c_; zeus::CVector3f x168_; @@ -70,21 +80,37 @@ public: zeus::CVector3f GetOrbitPosition(const CStateManager&); zeus::CVector3f GetAimPosition(const CStateManager&, float val); virtual const CCollisionPrimitive& GetCollisionPrimitive() const; - virtual zeus::CTransform GetPrimitiveTransform(); + virtual zeus::CTransform GetPrimitiveTransform() const; virtual void CollidedWith(const TUniqueId&, const CCollisionInfoList&, CStateManager&); - virtual float GetStepUpHeight(); - virtual float GetStepDownHeight(); - virtual float GetWeight(); + virtual float GetStepUpHeight() const; + virtual float GetStepDownHeight() const; + virtual float GetWeight() const; void SetPrimitiveOffset(const zeus::CVector2f& offset); zeus::CVector3f GetPrimitiveOffset(); void MoveCollisionPrimitive(const zeus::CVector3f& offset); void SetBoundingBox(const zeus::CAABox& box); - zeus::CAABox GetMotionVolume(); + zeus::CAABox GetMotionVolume(float f31) const; + zeus::CVector3f CalculateNewVelocityWR_UsingImpulses() const; zeus::CAABox GetBoundingBox(); const zeus::CAABox& GetBaseBoundingBox() const; + void AddMotionState(const CMotionState& mst); + CMotionState GetMotionState() const; void SetInertiaTensorScalar(float tensor); void SetMass(float mass); + void SetAngularVelocityOR(const zeus::CAxisAngle& angVel); + zeus::CAxisAngle GetAngularVelocityOR() const; + void SetAngularVelocityWR(const zeus::CAxisAngle& angVel); + void SetVelocityWR(const zeus::CVector3f& vel); + void SetVelocityOR(const zeus::CVector3f& vel); + zeus::CVector3f GetTotalForcesWR() const; + void RotateInOneFrameOR(const zeus::CQuaternion& q, float d); + zeus::CVector3f GetRotateToORAngularMomentumWR(const zeus::CQuaternion& q, float d) const; + void ClearImpulses(); + void ClearForcesAndTorques(); + void Stop(); + void ComputeDerivedQuantities(); + bool WillMove(const CStateManager&); }; } diff --git a/Runtime/World/CScriptDistanceFog.cpp b/Runtime/World/CScriptDistanceFog.cpp index d29706ac0..ac094f1ab 100644 --- a/Runtime/World/CScriptDistanceFog.cpp +++ b/Runtime/World/CScriptDistanceFog.cpp @@ -4,18 +4,6 @@ namespace urde { -bool close_enough(const zeus::CVector2f& a, const zeus::CVector2f& b, float epsilon = 0.000099999997f) -{ - if (std::fabs(a.x - b.x) < epsilon && std::fabs(a.y - b.y) < epsilon) - return true; - return false; -} - -bool close_enough(float a, float b, double epsilon = 0.000009999999747378752) -{ - return std::fabs(a - b) < epsilon; -} - CScriptDistanceFog::CScriptDistanceFog(TUniqueId uid, const std::string& name, const CEntityInfo& info, const ERglFogMode& mode, const zeus::CColor& color, const zeus::CVector2f& range, float colorDelta, @@ -34,7 +22,7 @@ CScriptDistanceFog::CScriptDistanceFog(TUniqueId uid, const std::string& name, c x60_explicit(expl) { - if (close_enough(rangeDelta, zeus::CVector2f::skZero) && close_enough(colorDelta, 0.f)) + if (zeus::close_enough(rangeDelta, zeus::CVector2f::skZero) && zeus::close_enough(colorDelta, 0.f)) x61_nonZero = false; else x61_nonZero = true; @@ -68,7 +56,7 @@ void CScriptDistanceFog::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId obj else fog->FadeFog(x34_mode, x38_color, x3c_range, x44_colorDelta, x48_rangeDelta); - if (close_enough(x54_thermalSpeed, 0.f) && !close_enough(x5c_xraySpeed, 0.f)) + if (zeus::close_enough(x54_thermalSpeed, 0.f) && !zeus::close_enough(x5c_xraySpeed, 0.f)) { CWorld* world = stateMgr.GetWorld(); CGameArea* area = world->GetArea(GetAreaId()); diff --git a/specter b/specter index 8395c1d5b..50749d771 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit 8395c1d5be86448f5072534f0b6d8699c2d32443 +Subproject commit 50749d771218db49aac420fe3e7aa11d9ffc3612