mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-05-13 15:11:22 +00:00
245 lines
6.4 KiB
C++
245 lines
6.4 KiB
C++
#include "CPhysicsActor.hpp"
|
|
|
|
namespace urde
|
|
{
|
|
|
|
CPhysicsActor::CPhysicsActor(TUniqueId uid, bool active, const std::string& name, const CEntityInfo& info,
|
|
const zeus::CTransform& xf, CModelData&& mData, const CMaterialList& matList,
|
|
const zeus::CAABox& box, const SMoverData& moverData, const CActorParameters& actorParms,
|
|
float, float)
|
|
: CActor(uid, active, name, info, xf, std::move(mData), matList, actorParms, kInvalidUniqueId)
|
|
{
|
|
}
|
|
|
|
void CPhysicsActor::Render(const CStateManager &mgr)
|
|
{
|
|
CActor::Render(mgr);
|
|
}
|
|
|
|
zeus::CVector3f CPhysicsActor::GetOrbitPosition(const CStateManager &)
|
|
{
|
|
return GetBoundingBox().center();
|
|
}
|
|
|
|
zeus::CVector3f CPhysicsActor::GetAimPosition(const CStateManager &, float val)
|
|
{
|
|
if (val <= 0.0)
|
|
return GetBoundingBox().center();
|
|
//zeus::CVector3f delta = PredictMotion(val);
|
|
return zeus::CVector3f();
|
|
}
|
|
|
|
void CPhysicsActor::CollidedWith(const TUniqueId &, const CCollisionInfoList &, CStateManager &)
|
|
{
|
|
}
|
|
|
|
const CCollisionPrimitive& CPhysicsActor::GetCollisionPrimitive() const
|
|
{
|
|
return x1c0_collisionPrimitive;
|
|
}
|
|
|
|
zeus::CTransform CPhysicsActor::GetPrimitiveTransform() const
|
|
{
|
|
return zeus::CTransform::Translate(x34_transform.origin + x1e8_primitiveOffset);
|
|
}
|
|
|
|
float CPhysicsActor::GetStepUpHeight() const
|
|
{
|
|
return x23c_stepUpHeight;
|
|
}
|
|
|
|
float CPhysicsActor::GetStepDownHeight() const
|
|
{
|
|
return x240_stepDownHeight;
|
|
}
|
|
|
|
float CPhysicsActor::GetWeight() const
|
|
{
|
|
return 24.525002f * xe8_mass;
|
|
}
|
|
|
|
void CPhysicsActor::SetPrimitiveOffset(const zeus::CVector2f &offset)
|
|
{
|
|
x1e8_primitiveOffset = offset;
|
|
}
|
|
|
|
zeus::CVector3f CPhysicsActor::GetPrimitiveOffset()
|
|
{
|
|
return x1e8_primitiveOffset;
|
|
}
|
|
|
|
void CPhysicsActor::MoveCollisionPrimitive(const zeus::CVector3f &offset)
|
|
{
|
|
x1e8_primitiveOffset = offset;
|
|
}
|
|
|
|
void CPhysicsActor::SetBoundingBox(const zeus::CAABox &box)
|
|
{
|
|
x1a4_baseBoundingBox = box;
|
|
MoveCollisionPrimitive(zeus::CVector3f::skZero);
|
|
}
|
|
|
|
zeus::CAABox CPhysicsActor::GetMotionVolume(float dt) const
|
|
{
|
|
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 { x1a4_baseBoundingBox.min + x1e8_primitiveOffset + x34_transform.origin,
|
|
x1a4_baseBoundingBox.max + x1e8_primitiveOffset + x34_transform.origin };
|
|
}
|
|
|
|
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_inertiaTensor = tensor;
|
|
xf4_inertiaTensorRecip = 1.0f / tensor;
|
|
}
|
|
|
|
void CPhysicsActor::SetMass(float mass)
|
|
{
|
|
xe8_mass = mass;
|
|
float tensor = 1.0f;
|
|
if (mass > 0.0f)
|
|
tensor = 1.0f / mass;
|
|
|
|
xec_massRecip = tensor;
|
|
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;
|
|
}
|
|
|
|
}
|