mirror of https://github.com/AxioDL/metaforce.git
Initial work on CGroundMovement
This commit is contained in:
parent
c854a45dfe
commit
d4a97861dc
|
@ -1499,27 +1499,27 @@ bool CStateManager::TestRayDamage(const zeus::CVector3f& pos, const CActor& dama
|
||||||
return CGameCollision::RayDynamicIntersectionBool(*this, pos, dir, filter, nearList, &damagee, depth * origMag);
|
return CGameCollision::RayDynamicIntersectionBool(*this, pos, dir, filter, nearList, &damagee, depth * origMag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CStateManager::RayCollideWorld(const zeus::CVector3f& pos, const zeus::CVector3f& damageeCenter,
|
bool CStateManager::RayCollideWorld(const zeus::CVector3f& start, const zeus::CVector3f& end,
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
const CMaterialFilter& filter, const CActor& damagee)
|
const CMaterialFilter& filter, const CActor& damagee)
|
||||||
{
|
{
|
||||||
return RayCollideWorldInternal(pos, damageeCenter, filter, nearList, &damagee);
|
return RayCollideWorldInternal(start, end, filter, nearList, &damagee);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CStateManager::RayCollideWorldInternal(const zeus::CVector3f& pos, const zeus::CVector3f& damageeCenter,
|
bool CStateManager::RayCollideWorldInternal(const zeus::CVector3f& start, const zeus::CVector3f& end,
|
||||||
const CMaterialFilter& filter,
|
const CMaterialFilter& filter,
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
const CActor* damagee)
|
const CActor* damagee)
|
||||||
{
|
{
|
||||||
zeus::CVector3f vecToDamagee = damageeCenter - pos;
|
zeus::CVector3f delta = end - start;
|
||||||
if (!vecToDamagee.canBeNormalized())
|
if (!delta.canBeNormalized())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
float mag = vecToDamagee.magnitude();
|
float mag = delta.magnitude();
|
||||||
zeus::CVector3f dir = vecToDamagee * (1.f / mag);
|
zeus::CVector3f dir = delta * (1.f / mag);
|
||||||
if (!CGameCollision::RayStaticIntersectionBool(*this, pos, dir, mag, filter))
|
if (!CGameCollision::RayStaticIntersectionBool(*this, start, dir, mag, filter))
|
||||||
return false;
|
return false;
|
||||||
return CGameCollision::RayDynamicIntersectionBool(*this, pos, dir, filter, nearList, damagee, mag);
|
return CGameCollision::RayDynamicIntersectionBool(*this, start, dir, filter, nearList, damagee, mag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CStateManager::MultiRayCollideWorld(const zeus::CMRay& ray, const CMaterialFilter& filter)
|
bool CStateManager::MultiRayCollideWorld(const zeus::CMRay& ray, const CMaterialFilter& filter)
|
||||||
|
|
|
@ -332,10 +332,10 @@ public:
|
||||||
const CDamageInfo& info);
|
const CDamageInfo& info);
|
||||||
bool TestRayDamage(const zeus::CVector3f& pos, const CActor& damagee,
|
bool TestRayDamage(const zeus::CVector3f& pos, const CActor& damagee,
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList);
|
const rstl::reserved_vector<TUniqueId, 1024>& nearList);
|
||||||
bool RayCollideWorld(const zeus::CVector3f& pos, const zeus::CVector3f& damageeCenter,
|
bool RayCollideWorld(const zeus::CVector3f& start, const zeus::CVector3f& end,
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
const CMaterialFilter& filter, const CActor& damagee);
|
const CMaterialFilter& filter, const CActor& damagee);
|
||||||
bool RayCollideWorldInternal(const zeus::CVector3f& pos, const zeus::CVector3f& damageeCenter,
|
bool RayCollideWorldInternal(const zeus::CVector3f& start, const zeus::CVector3f& end,
|
||||||
const CMaterialFilter& filter,
|
const CMaterialFilter& filter,
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
const CActor* damagee);
|
const CActor* damagee);
|
||||||
|
|
|
@ -0,0 +1,619 @@
|
||||||
|
#include "CGroundMovement.hpp"
|
||||||
|
#include "World/CPhysicsActor.hpp"
|
||||||
|
#include "Collision/CGameCollision.hpp"
|
||||||
|
#include "Collision/CCollisionInfoList.hpp"
|
||||||
|
#include "Collision/CollisionUtil.hpp"
|
||||||
|
#include "Collision/CAABoxFilter.hpp"
|
||||||
|
#include "CStateManager.hpp"
|
||||||
|
#include "TCastTo.hpp"
|
||||||
|
#include "World/CScriptPlatform.hpp"
|
||||||
|
#include "World/CWorld.hpp"
|
||||||
|
#include "World/CPlayer.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
void CGroundMovement::CheckFalling(CPhysicsActor& actor, CStateManager& mgr, float)
|
||||||
|
{
|
||||||
|
bool oob = true;
|
||||||
|
for (const CGameArea& area : *mgr.GetWorld())
|
||||||
|
{
|
||||||
|
if (area.GetAABB().intersects(*actor.GetTouchBounds()))
|
||||||
|
{
|
||||||
|
oob = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!oob)
|
||||||
|
{
|
||||||
|
mgr.SendScriptMsg(&actor, kInvalidUniqueId, EScriptObjectMessage::Falling);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mgr.SendScriptMsg(&actor, kInvalidUniqueId, EScriptObjectMessage::OnFloor);
|
||||||
|
actor.SetAngularVelocityWR(actor.GetAngularVelocityWR() * 0.98f);
|
||||||
|
zeus::CVector3f vel = actor.GetTransform().transposeRotate(actor.GetVelocity());
|
||||||
|
vel.z = 0.f;
|
||||||
|
actor.SetVelocityOR(vel);
|
||||||
|
actor.SetMomentumWR(zeus::CVector3f::skZero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroundMovement::MoveGroundCollider(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
||||||
|
const rstl::reserved_vector<TUniqueId, 1024>* nearList)
|
||||||
|
{
|
||||||
|
CMotionState oldState = actor.GetMotionState();
|
||||||
|
CMotionState newState = actor.PredictMotion_Internal(dt);
|
||||||
|
float deltaMag = newState.x0_translation.magnitude();
|
||||||
|
TUniqueId idDetect = kInvalidUniqueId;
|
||||||
|
CCollisionInfoList collisionList;
|
||||||
|
zeus::CAABox motionVol = actor.GetMotionVolume(dt);
|
||||||
|
rstl::reserved_vector<TUniqueId, 1024> useColliderList;
|
||||||
|
if (nearList)
|
||||||
|
useColliderList = *nearList;
|
||||||
|
mgr.BuildColliderList(useColliderList, actor, motionVol);
|
||||||
|
CAreaCollisionCache cache(motionVol);
|
||||||
|
float collideDt = dt;
|
||||||
|
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();
|
||||||
|
TUniqueId intersectId = kInvalidUniqueId;
|
||||||
|
CMaterialFilter filter = CMaterialFilter::MakeInclude({EMaterialTypes::Solid});
|
||||||
|
CRayCastResult result =
|
||||||
|
mgr.RayWorldIntersection(intersectId, point, newState.x0_translation.normalized(), deltaMag,
|
||||||
|
filter, useColliderList);
|
||||||
|
if (result.IsValid())
|
||||||
|
{
|
||||||
|
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(),
|
||||||
|
useColliderList, idDetect, collisionList))
|
||||||
|
{
|
||||||
|
actor.AddMotionState(newState);
|
||||||
|
float resolved = 0.f;
|
||||||
|
if (ResolveUpDown(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList,
|
||||||
|
actor.GetStepUpHeight(), 0.f, resolved, collisionList))
|
||||||
|
{
|
||||||
|
actor.SetMotionState(oldState);
|
||||||
|
MoveGroundColliderXY(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList, collideDt);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
actor.AddMotionState(newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
float stepDown = actor.GetStepDownHeight();
|
||||||
|
float resolved = 0.f;
|
||||||
|
collisionList.Clear();
|
||||||
|
TUniqueId stepZId = kInvalidUniqueId;
|
||||||
|
if (stepDown >= 0.f)
|
||||||
|
{
|
||||||
|
if (MoveGroundColliderZ(cache, mgr, actor, actor.GetMaterialFilter(), useColliderList,
|
||||||
|
-stepDown, resolved, collisionList, stepZId))
|
||||||
|
{
|
||||||
|
if (collisionList.GetCount() > 0)
|
||||||
|
{
|
||||||
|
CCollisionInfoList filteredList;
|
||||||
|
CollisionUtil::FilterByClosestNormal(zeus::CVector3f{0.f, 0.f, 1.f}, collisionList, filteredList);
|
||||||
|
if (filteredList.GetCount() > 0)
|
||||||
|
{
|
||||||
|
if (CGameCollision::IsFloor(filteredList.Front().GetMaterialLeft(),
|
||||||
|
filteredList.Front().GetNormalLeft()))
|
||||||
|
{
|
||||||
|
if (TCastToPtr<CScriptPlatform> plat = mgr.ObjectById(stepZId))
|
||||||
|
mgr.SendScriptMsg(plat.GetPtr(), actor.GetUniqueId(),
|
||||||
|
EScriptObjectMessage::AddPlatformRider);
|
||||||
|
CGameCollision::SendMaterialMessage(mgr, filteredList.Front().GetMaterialLeft(), actor);
|
||||||
|
mgr.SendScriptMsg(&actor, kInvalidUniqueId, EScriptObjectMessage::OnFloor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CGroundMovement::ResolveUpDown(CAreaCollisionCache& cache, CStateManager& mgr, CPhysicsActor& actor,
|
||||||
|
const CMaterialFilter& filter, rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
|
float stepUp, float stepDown, float& fOut, CCollisionInfoList& list)
|
||||||
|
{
|
||||||
|
float zextent = stepDown;
|
||||||
|
if (list.GetCount() <= 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
zeus::CAABox aabb = zeus::CAABox::skInvertedBox;
|
||||||
|
zeus::CVector3f normAccum = zeus::CVector3f::skZero;
|
||||||
|
for (CCollisionInfo& info : list)
|
||||||
|
{
|
||||||
|
if (CGameCollision::IsFloor(info.GetMaterialLeft(), info.GetNormalLeft()))
|
||||||
|
{
|
||||||
|
aabb.accumulateBounds(info.GetPoint());
|
||||||
|
aabb.accumulateBounds(info.GetExtreme());
|
||||||
|
normAccum += info.GetNormalLeft();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normAccum.canBeNormalized())
|
||||||
|
normAccum.normalize();
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
|
||||||
|
zeus::CAABox actorAABB = actor.GetBoundingBox();
|
||||||
|
if (normAccum.z >= 0.f)
|
||||||
|
{
|
||||||
|
zextent = aabb.max.z - actorAABB.min.z + 0.02f;
|
||||||
|
if (zextent > stepUp)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zextent = aabb.min.z - actorAABB.max.z - 0.02f;
|
||||||
|
if (zextent < -stepDown)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
actor.MoveCollisionPrimitive({0.f, 0.f, zextent});
|
||||||
|
|
||||||
|
if (!CGameCollision::DetectCollisionBoolean_Cached(mgr, cache, *actor.GetCollisionPrimitive(),
|
||||||
|
actor.GetPrimitiveTransform(), filter, nearList))
|
||||||
|
{
|
||||||
|
fOut = zextent;
|
||||||
|
actor.SetTranslation(actor.GetTranslation() + zeus::CVector3f(0.f, 0.f, zextent));
|
||||||
|
actor.MoveCollisionPrimitive(zeus::CVector3f::skZero);
|
||||||
|
|
||||||
|
bool floor = false;
|
||||||
|
for (CCollisionInfo& info : list)
|
||||||
|
{
|
||||||
|
if (CGameCollision::IsFloor(info.GetMaterialLeft(), info.GetNormalLeft()))
|
||||||
|
{
|
||||||
|
floor = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!floor)
|
||||||
|
mgr.SendScriptMsg(&actor, kInvalidUniqueId, EScriptObjectMessage::LandOnNotFloor);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CGroundMovement::MoveGroundColliderZ(CAreaCollisionCache& cache, CStateManager& mgr, CPhysicsActor& actor,
|
||||||
|
const CMaterialFilter& filter, rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
|
float amt, float&, CCollisionInfoList& list, TUniqueId& idOut)
|
||||||
|
{
|
||||||
|
actor.MoveCollisionPrimitive({0.f, 0.f, amt});
|
||||||
|
|
||||||
|
zeus::CAABox aabb = zeus::CAABox::skInvertedBox;
|
||||||
|
if (CGameCollision::DetectCollision_Cached(mgr, cache, *actor.GetCollisionPrimitive(),
|
||||||
|
actor.GetPrimitiveTransform(), filter, nearList, idOut, list))
|
||||||
|
{
|
||||||
|
for (CCollisionInfo& info : list)
|
||||||
|
{
|
||||||
|
aabb.accumulateBounds(info.GetPoint());
|
||||||
|
aabb.accumulateBounds(info.GetExtreme());
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CAABox actorAABB = actor.GetBoundingBox();
|
||||||
|
float zextent;
|
||||||
|
if (amt > 0.f)
|
||||||
|
zextent = aabb.min.z - actorAABB.max.z - 0.02f + amt;
|
||||||
|
else
|
||||||
|
zextent = aabb.max.z - actorAABB.min.z + 0.02f + amt;
|
||||||
|
|
||||||
|
actor.MoveCollisionPrimitive({0.f, 0.f, zextent});
|
||||||
|
|
||||||
|
if (!CGameCollision::DetectCollisionBoolean_Cached(mgr, cache, *actor.GetCollisionPrimitive(),
|
||||||
|
actor.GetPrimitiveTransform(), filter, nearList))
|
||||||
|
{
|
||||||
|
actor.SetTranslation(actor.GetTranslation() + zeus::CVector3f(0.f, 0.f, zextent));
|
||||||
|
actor.MoveCollisionPrimitive(zeus::CVector3f::skZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool floor = false;
|
||||||
|
for (CCollisionInfo& info : list)
|
||||||
|
{
|
||||||
|
if (CGameCollision::IsFloor(info.GetMaterialLeft(), info.GetNormalLeft()))
|
||||||
|
{
|
||||||
|
floor = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!floor)
|
||||||
|
mgr.SendScriptMsg(&actor, kInvalidUniqueId, EScriptObjectMessage::LandOnNotFloor);
|
||||||
|
|
||||||
|
CCollisionInfoList filteredList;
|
||||||
|
if (amt > 0.f)
|
||||||
|
CollisionUtil::FilterByClosestNormal({0.f, 0.f, -1.f}, list, filteredList);
|
||||||
|
else
|
||||||
|
CollisionUtil::FilterByClosestNormal({0.f, 0.f, 1.f}, list, filteredList);
|
||||||
|
|
||||||
|
if (filteredList.GetCount() > 0)
|
||||||
|
CGameCollision::MakeCollisionCallbacks(mgr, actor, idOut, filteredList);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroundMovement::MoveGroundColliderXY(CAreaCollisionCache& cache, CStateManager& mgr, CPhysicsActor& actor,
|
||||||
|
const CMaterialFilter& filter, rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
|
float dt)
|
||||||
|
{
|
||||||
|
bool didCollide = false;
|
||||||
|
bool isPlayer = actor.GetMaterialList().HasMaterial(EMaterialTypes::Player);
|
||||||
|
float remDt = dt;
|
||||||
|
float originalDt = dt;
|
||||||
|
TCastToPtr<CPhysicsActor> otherActor;
|
||||||
|
CCollisionInfoList collisionList;
|
||||||
|
CMotionState newMState = actor.PredictMotion_Internal(dt);
|
||||||
|
float transMag = newMState.x0_translation.magnitude();
|
||||||
|
float divMag;
|
||||||
|
if (isPlayer)
|
||||||
|
divMag = std::max(transMag / 5.f, 0.005f);
|
||||||
|
else
|
||||||
|
divMag = std::max(transMag / 3.f, 0.02f);
|
||||||
|
|
||||||
|
float minExtent = 0.5f * CGameCollision::GetMinExtentForCollisionPrimitive(*actor.GetCollisionPrimitive());
|
||||||
|
if (transMag > minExtent)
|
||||||
|
{
|
||||||
|
dt = minExtent * (dt / transMag);
|
||||||
|
originalDt = dt;
|
||||||
|
newMState = actor.PredictMotion_Internal(dt);
|
||||||
|
divMag = std::min(divMag, minExtent);
|
||||||
|
}
|
||||||
|
|
||||||
|
float nonCollideDt = dt;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
actor.MoveCollisionPrimitive(newMState.x0_translation);
|
||||||
|
collisionList.Clear();
|
||||||
|
TUniqueId otherId = kInvalidUniqueId;
|
||||||
|
bool collided = CGameCollision::DetectCollision_Cached(mgr, cache, *actor.GetCollisionPrimitive(),
|
||||||
|
actor.GetPrimitiveTransform(), filter, nearList,
|
||||||
|
otherId, collisionList);
|
||||||
|
if (collided)
|
||||||
|
otherActor = mgr.ObjectById(otherId);
|
||||||
|
actor.MoveCollisionPrimitive(zeus::CVector3f::skZero);
|
||||||
|
if (collided)
|
||||||
|
{
|
||||||
|
didCollide = true;
|
||||||
|
if (newMState.x0_translation.magnitude() < divMag)
|
||||||
|
{
|
||||||
|
CCollisionInfoList backfaceFilteredList, floorFilteredList;
|
||||||
|
zeus::CVector3f deltaVel = actor.GetVelocity();
|
||||||
|
if (otherActor)
|
||||||
|
deltaVel -= otherActor->GetVelocity();
|
||||||
|
CollisionUtil::FilterOutBackfaces(deltaVel, collisionList, backfaceFilteredList);
|
||||||
|
CAABoxFilter::FilterBoxFloorCollisions(backfaceFilteredList, floorFilteredList);
|
||||||
|
CGameCollision::MakeCollisionCallbacks(mgr, actor, otherId, floorFilteredList);
|
||||||
|
if (floorFilteredList.GetCount() == 0 && isPlayer)
|
||||||
|
{
|
||||||
|
CMotionState lastNonCollideState = actor.GetLastNonCollidingState();
|
||||||
|
lastNonCollideState.x1c_velocity *= 0.5f;
|
||||||
|
lastNonCollideState.x28_angularMomentum *= 0.5f;
|
||||||
|
actor.SetMotionState(lastNonCollideState);
|
||||||
|
}
|
||||||
|
for (const CCollisionInfo& info : floorFilteredList)
|
||||||
|
{
|
||||||
|
CCollisionInfo infoCopy = info;
|
||||||
|
float restitution = CGameCollision::GetCoefficientOfRestitution(infoCopy) +
|
||||||
|
actor.GetCoefficientOfRestitutionModifier();
|
||||||
|
if (otherActor)
|
||||||
|
CGameCollision::CollideWithDynamicBodyNoRot(actor, *otherActor, infoCopy, restitution, true);
|
||||||
|
else
|
||||||
|
CGameCollision::CollideWithStaticBodyNoRot(actor, infoCopy.GetMaterialLeft(), infoCopy.GetMaterialRight(),
|
||||||
|
infoCopy.GetNormalLeft(), restitution, true);
|
||||||
|
}
|
||||||
|
remDt -= dt;
|
||||||
|
nonCollideDt = std::min(originalDt, remDt);
|
||||||
|
dt = nonCollideDt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nonCollideDt *= 0.5f;
|
||||||
|
dt *= 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
actor.AddMotionState(newMState);
|
||||||
|
remDt -= dt;
|
||||||
|
dt = nonCollideDt;
|
||||||
|
actor.MoveCollisionPrimitive(zeus::CVector3f::skZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
newMState = actor.PredictMotion_Internal(dt);
|
||||||
|
} while (remDt > 0.f);
|
||||||
|
|
||||||
|
if (!didCollide && !actor.GetMaterialList().HasMaterial(EMaterialTypes::GroundCollider))
|
||||||
|
mgr.SendScriptMsg(&actor, kInvalidUniqueId, EScriptObjectMessage::Falling);
|
||||||
|
|
||||||
|
actor.MoveCollisionPrimitive(zeus::CVector3f::skZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroundMovement::CollisionDamping(const zeus::CVector3f&, const zeus::CVector3f&, const zeus::CVector3f&,
|
||||||
|
float, float)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroundMovement::MoveGroundCollider_New(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
||||||
|
const rstl::reserved_vector<TUniqueId, 1024>* nearList)
|
||||||
|
{
|
||||||
|
zeus::CAABox motionVol = actor.GetMotionVolume(dt);
|
||||||
|
rstl::reserved_vector<TUniqueId, 1024> useNearList;
|
||||||
|
if (nearList)
|
||||||
|
useNearList = *nearList;
|
||||||
|
else
|
||||||
|
mgr.BuildColliderList(useNearList, actor, motionVol);
|
||||||
|
|
||||||
|
CAreaCollisionCache cache(motionVol);
|
||||||
|
CGameCollision::BuildAreaCollisionCache(mgr, cache);
|
||||||
|
CPlayer& player = static_cast<CPlayer&>(actor);
|
||||||
|
player.x9c5_28_slidingOnWall = false;
|
||||||
|
bool startingJump = player.x258_movementState == CPlayer::EPlayerMovementState::StartingJump;
|
||||||
|
bool dampUnderwater = false;
|
||||||
|
if (player.x9c4_31_dampUnderwaterMotion)
|
||||||
|
{
|
||||||
|
if (!mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit))
|
||||||
|
dampUnderwater = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool noJump = (player.x258_movementState != CPlayer::EPlayerMovementState::StartingJump &&
|
||||||
|
player.x258_movementState != CPlayer::EPlayerMovementState::Jump);
|
||||||
|
|
||||||
|
float stepDown = player.GetStepDownHeight();
|
||||||
|
float stepUp = player.GetStepUpHeight();
|
||||||
|
|
||||||
|
bool x108 = true;
|
||||||
|
CMaterialList material(EMaterialTypes::Unknown);
|
||||||
|
SMoveObjectResult result;
|
||||||
|
|
||||||
|
if (!startingJump)
|
||||||
|
{
|
||||||
|
SMovementOptions opts;
|
||||||
|
opts.x0_ = false;
|
||||||
|
opts.x4_ = 0.f;
|
||||||
|
opts.x8_ = 0.f;
|
||||||
|
opts.xc_ = 0.37f;
|
||||||
|
opts.x10_ = 0.25f;
|
||||||
|
opts.x14_ = 0.f;
|
||||||
|
opts.x18_ = true;
|
||||||
|
opts.x19_ = false;
|
||||||
|
opts.x1a_ = noJump;
|
||||||
|
opts.x1c_ = 4;
|
||||||
|
opts.x20_ = 0.002f;
|
||||||
|
opts.x24_ = 0.f;
|
||||||
|
opts.x28_ = 1.f;
|
||||||
|
opts.x2c_ = 0.f;
|
||||||
|
opts.x30_ = 0.02f;
|
||||||
|
opts.x3c_ = player.GetLastFloorPlaneNormal();
|
||||||
|
opts.x34_ = 0.2f;
|
||||||
|
opts.x38_ = player.GetMaximumPlayerPositiveVerticalVelocity(mgr);
|
||||||
|
|
||||||
|
if (noJump)
|
||||||
|
{
|
||||||
|
zeus::CVector3f vel = player.GetVelocity();
|
||||||
|
vel.z = 0.f;
|
||||||
|
actor.SetVelocityWR(vel);
|
||||||
|
actor.x15c_force.z = 0.f;
|
||||||
|
actor.x150_momentum.z = 0.f;
|
||||||
|
actor.x168_impulse.z = 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPhysicsState physStatePre = actor.GetPhysicsState();
|
||||||
|
CMaterialList material = MoveObjectAnalytical(mgr, actor, dt, useNearList, cache, opts, result);
|
||||||
|
CPhysicsState physStatePost = actor.GetPhysicsState();
|
||||||
|
|
||||||
|
if (material.XOR({EMaterialTypes::Unknown}))
|
||||||
|
{
|
||||||
|
SMovementOptions optsCopy = opts;
|
||||||
|
zeus::CVector3f postToPre = physStatePre.GetTranslation() - physStatePost.GetTranslation();
|
||||||
|
float f27 = postToPre.magSquared();
|
||||||
|
optsCopy.x19_ = noJump;
|
||||||
|
float quarterStepUp = 0.25f * stepUp;
|
||||||
|
rstl::reserved_vector<CPhysicsState, 2> physStateList;
|
||||||
|
rstl::reserved_vector<float, 2> floatList;
|
||||||
|
rstl::reserved_vector<CCollisionInfo, 2> collisionInfoList;
|
||||||
|
rstl::reserved_vector<TUniqueId, 2> uniqueIdList;
|
||||||
|
rstl::reserved_vector<CMaterialList, 2> materialListList;
|
||||||
|
bool done = false;
|
||||||
|
for (int i=0 ; i < 2 && !done ; ++i)
|
||||||
|
{
|
||||||
|
double useStepUp = (i == 0) ? quarterStepUp : stepUp;
|
||||||
|
actor.SetPhysicsState(physStatePre);
|
||||||
|
CCollisionInfo collisionInfo;
|
||||||
|
TUniqueId id = kInvalidUniqueId;
|
||||||
|
CGameCollision::DetectCollision_Cached_Moving(mgr, cache, *actor.GetCollisionPrimitive(),
|
||||||
|
actor.GetTransform(), actor.GetMaterialFilter(),
|
||||||
|
useNearList, {0.f, 0.f, 1.f}, id, collisionInfo,
|
||||||
|
useStepUp);
|
||||||
|
if (collisionInfo.IsValid())
|
||||||
|
{
|
||||||
|
useStepUp = std::max(0.0, useStepUp - optsCopy.x20_);
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useStepUp > 0.0005)
|
||||||
|
{
|
||||||
|
actor.SetTranslation(actor.GetTranslation() + zeus::CVector3f(0.f, 0.f, useStepUp));
|
||||||
|
|
||||||
|
SMoveObjectResult result;
|
||||||
|
CMaterialList material = MoveObjectAnalytical(mgr, actor, dt, useNearList, cache, optsCopy, result);
|
||||||
|
CCollisionInfo collisionInfo;
|
||||||
|
double useStepDown = useStepUp + stepDown;
|
||||||
|
TUniqueId id = kInvalidUniqueId;
|
||||||
|
if (useStepDown > 0.0)
|
||||||
|
{
|
||||||
|
CGameCollision::DetectCollision_Cached_Moving(mgr, cache, *actor.GetCollisionPrimitive(),
|
||||||
|
actor.GetTransform(), actor.GetMaterialFilter(),
|
||||||
|
useNearList, {0.f, 0.f, -1.f}, id, collisionInfo,
|
||||||
|
useStepDown);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
useStepDown = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float minStep = std::min(useStepUp, useStepDown);
|
||||||
|
zeus::CVector3f offsetStep = actor.GetTranslation() - zeus::CVector3f(0.f, 0.f, minStep);
|
||||||
|
bool canBlock = (collisionInfo.IsValid() &&
|
||||||
|
CGameCollision::CanBlock(collisionInfo.GetMaterialLeft(), collisionInfo.GetNormalLeft()));
|
||||||
|
zeus::CVector3f postToPre = physStatePre.GetTranslation() - offsetStep;
|
||||||
|
float f26 = postToPre.magSquared();
|
||||||
|
if (canBlock && f27 < f26)
|
||||||
|
{
|
||||||
|
useStepDown = std::max(0.0, useStepDown - 0.0005);
|
||||||
|
actor.SetTranslation(actor.GetTranslation() - zeus::CVector3f(0.f, 0.f, useStepDown));
|
||||||
|
physStateList.push_back(actor.GetPhysicsState());
|
||||||
|
floatList.push_back(f26);
|
||||||
|
collisionInfoList.push_back(collisionInfo);
|
||||||
|
uniqueIdList.push_back(id);
|
||||||
|
materialListList.push_back(material);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (physStateList.size() == 0)
|
||||||
|
{
|
||||||
|
actor.SetPhysicsState(physStatePost);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float maxFloat = -1.0e10f;
|
||||||
|
int maxIdx = -1;
|
||||||
|
for (int i=0 ; i<physStateList.size() ; ++i)
|
||||||
|
{
|
||||||
|
if (maxFloat < floatList[i])
|
||||||
|
{
|
||||||
|
maxFloat = floatList[i];
|
||||||
|
maxIdx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actor.SetPhysicsState(physStateList[maxIdx]);
|
||||||
|
mgr.SendScriptMsg(&actor, kInvalidUniqueId, EScriptObjectMessage::OnFloor);
|
||||||
|
if (CEntity* ent = mgr.ObjectById(uniqueIdList[maxIdx]))
|
||||||
|
{
|
||||||
|
result.x0_id.emplace(uniqueIdList[maxIdx]);
|
||||||
|
result.x8_collision.emplace(collisionInfoList[maxIdx]);
|
||||||
|
if (TCastToPtr<CScriptPlatform> plat = ent)
|
||||||
|
mgr.SendScriptMsg(ent, actor.GetUniqueId(), EScriptObjectMessage::AddPlatformRider);
|
||||||
|
}
|
||||||
|
|
||||||
|
CCollisionInfo& cInfo = collisionInfoList[maxIdx];
|
||||||
|
CGameCollision::SendMaterialMessage(mgr, cInfo.GetMaterialLeft(), actor);
|
||||||
|
x108 = false;
|
||||||
|
actor.SetLastFloorPlaneNormal({cInfo.GetNormalLeft()});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SMovementOptions opts;
|
||||||
|
opts.x0_ = true;
|
||||||
|
opts.x4_ = dampUnderwater ? 35.f : 1.f;
|
||||||
|
opts.x8_ = dampUnderwater ? 5.f : 0.f;
|
||||||
|
opts.xc_ = dampUnderwater ? 0.05f : 0.37f;
|
||||||
|
opts.x10_ = dampUnderwater ? 0.01f : 0.25f;
|
||||||
|
opts.x14_ = dampUnderwater ? 0.2f : 0.f;
|
||||||
|
opts.x18_ = false;
|
||||||
|
opts.x19_ = false;
|
||||||
|
opts.x1a_ = false;
|
||||||
|
opts.x1c_ = 4;
|
||||||
|
opts.x20_ = 0.002f;
|
||||||
|
opts.x24_ = 0.f;
|
||||||
|
opts.x28_ = 1.f;
|
||||||
|
opts.x2c_ = 0.1f;
|
||||||
|
opts.x30_ = dampUnderwater ? 0.2f : 0.2f;
|
||||||
|
opts.x3c_ = player.GetLastFloorPlaneNormal();
|
||||||
|
opts.x38_ = player.GetMaximumPlayerPositiveVerticalVelocity(mgr);
|
||||||
|
|
||||||
|
material = MoveObjectAnalytical(mgr, actor, dt, useNearList, cache, opts, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x108)
|
||||||
|
{
|
||||||
|
// TODO: Finish
|
||||||
|
}
|
||||||
|
|
||||||
|
actor.ClearForcesAndTorques();
|
||||||
|
if (material.HasMaterial(EMaterialTypes::Wall))
|
||||||
|
player.SetPlayerHitWallDuringMove();
|
||||||
|
|
||||||
|
if (result.x0_id)
|
||||||
|
{
|
||||||
|
CCollisionInfoList list;
|
||||||
|
list.Add(*result.x8_collision, false);
|
||||||
|
CGameCollision::MakeCollisionCallbacks(mgr, actor, *result.x0_id, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMotionState mState = actor.GetMotionState();
|
||||||
|
mState.x0_translation = actor.GetLastNonCollidingState().x0_translation;
|
||||||
|
mState.x1c_velocity = actor.GetLastNonCollidingState().x1c_velocity;
|
||||||
|
actor.SetLastNonCollidingState(mState);
|
||||||
|
|
||||||
|
const CCollisionPrimitive* prim = actor.GetCollisionPrimitive();
|
||||||
|
if (prim->GetPrimType() == FOURCC('AABX'))
|
||||||
|
{
|
||||||
|
// TODO: Finish
|
||||||
|
}
|
||||||
|
else if (prim->GetPrimType() == FOURCC('SPHR'))
|
||||||
|
{
|
||||||
|
// TODO: Finish
|
||||||
|
}
|
||||||
|
|
||||||
|
CGameCollision::CollisionFailsafe(mgr, cache, actor, *prim, useNearList, 0.f, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroundMovement::RemoveNormalComponent(const zeus::CVector3f&, const zeus::CVector3f&, const zeus::CVector3f&, float&)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGroundMovement::RemoveNormalComponent(const zeus::CVector3f&, const zeus::CVector3f&)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CMaterialList CGroundMovement::MoveObjectAnalytical(CStateManager& mgr, CPhysicsActor& actor, float,
|
||||||
|
rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
|
CAreaCollisionCache& cache, const SMovementOptions& opts,
|
||||||
|
SMoveObjectResult& result)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
#ifndef __URDE_CGROUNDMOVEMENT_HPP__
|
||||||
|
#define __URDE_CGROUNDMOVEMENT_HPP__
|
||||||
|
|
||||||
|
#include "RetroTypes.hpp"
|
||||||
|
#include "Collision/CCollisionInfo.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
class CPhysicsActor;
|
||||||
|
class CStateManager;
|
||||||
|
class CAreaCollisionCache;
|
||||||
|
class CMaterialFilter;
|
||||||
|
class CCollisionInfoList;
|
||||||
|
|
||||||
|
class CGroundMovement
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct SMovementOptions
|
||||||
|
{
|
||||||
|
bool x0_;
|
||||||
|
float x4_;
|
||||||
|
float x8_;
|
||||||
|
float xc_;
|
||||||
|
float x10_;
|
||||||
|
float x14_;
|
||||||
|
bool x18_;
|
||||||
|
bool x19_;
|
||||||
|
bool x1a_;
|
||||||
|
u32 x1c_;
|
||||||
|
float x20_;
|
||||||
|
float x24_;
|
||||||
|
float x28_;
|
||||||
|
float x2c_;
|
||||||
|
float x30_;
|
||||||
|
float x34_;
|
||||||
|
float x38_;
|
||||||
|
std::experimental::optional<zeus::CVector3f> x3c_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SMoveObjectResult
|
||||||
|
{
|
||||||
|
std::experimental::optional<TUniqueId> x0_id;
|
||||||
|
std::experimental::optional<CCollisionInfo> x8_collision;
|
||||||
|
u32 x6c_;
|
||||||
|
float x70_;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void CheckFalling(CPhysicsActor& actor, CStateManager& mgr, float);
|
||||||
|
static void MoveGroundCollider(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
||||||
|
const rstl::reserved_vector<TUniqueId, 1024>* nearList);
|
||||||
|
static bool ResolveUpDown(CAreaCollisionCache& cache, CStateManager& mgr, CPhysicsActor& actor,
|
||||||
|
const CMaterialFilter& filter, rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
|
float, float, float&, CCollisionInfoList& list);
|
||||||
|
static bool MoveGroundColliderZ(CAreaCollisionCache& cache, CStateManager& mgr, CPhysicsActor& actor,
|
||||||
|
const CMaterialFilter& filter, rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
|
float, float&, CCollisionInfoList& list, TUniqueId& idOut);
|
||||||
|
static void MoveGroundColliderXY(CAreaCollisionCache& cache, CStateManager& mgr, CPhysicsActor& actor,
|
||||||
|
const CMaterialFilter& filter, rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
|
float);
|
||||||
|
static void CollisionDamping(const zeus::CVector3f&, const zeus::CVector3f&, const zeus::CVector3f&,
|
||||||
|
float, float);
|
||||||
|
static void MoveGroundCollider_New(CStateManager& mgr, CPhysicsActor& actor, float,
|
||||||
|
const rstl::reserved_vector<TUniqueId, 1024>* nearList);
|
||||||
|
static void RemoveNormalComponent(const zeus::CVector3f&, const zeus::CVector3f&, const zeus::CVector3f&, float&);
|
||||||
|
static void RemoveNormalComponent(const zeus::CVector3f&, const zeus::CVector3f&);
|
||||||
|
static CMaterialList MoveObjectAnalytical(CStateManager& mgr, CPhysicsActor& actor, float,
|
||||||
|
rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
|
CAreaCollisionCache& cache, const SMovementOptions& opts,
|
||||||
|
SMoveObjectResult& result);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __URDE_CGROUNDMOVEMENT_HPP__
|
|
@ -88,6 +88,7 @@ set(CHARACTER_SOURCES
|
||||||
CAnimSysContext.hpp
|
CAnimSysContext.hpp
|
||||||
CBodyState.hpp CBodyState.cpp
|
CBodyState.hpp CBodyState.cpp
|
||||||
CBodyStateCmdMgr.hpp CBodyStateCmdMgr.cpp
|
CBodyStateCmdMgr.hpp CBodyStateCmdMgr.cpp
|
||||||
CBodyController.hpp CBodyController.cpp)
|
CBodyController.hpp CBodyController.cpp
|
||||||
|
CGroundMovement.hpp CGroundMovement.cpp)
|
||||||
|
|
||||||
runtime_add_list(Character CHARACTER_SOURCES)
|
runtime_add_list(Character CHARACTER_SOURCES)
|
||||||
|
|
|
@ -28,6 +28,8 @@ public:
|
||||||
x0_list.push_back(info.GetSwapped());
|
x0_list.push_back(info.GetSwapped());
|
||||||
}
|
}
|
||||||
void Clear() { x0_list.clear(); }
|
void Clear() { x0_list.clear(); }
|
||||||
|
const CCollisionInfo& Front() const { return x0_list.front(); }
|
||||||
|
const CCollisionInfo& GetItem(int i) const { return x0_list[i]; }
|
||||||
rstl::reserved_vector<CCollisionInfo, 32>::iterator end() { return x0_list.end(); }
|
rstl::reserved_vector<CCollisionInfo, 32>::iterator end() { return x0_list.end(); }
|
||||||
rstl::reserved_vector<CCollisionInfo, 32>::const_iterator end() const { return x0_list.end(); }
|
rstl::reserved_vector<CCollisionInfo, 32>::const_iterator end() const { return x0_list.end(); }
|
||||||
rstl::reserved_vector<CCollisionInfo, 32>::iterator begin() { return x0_list.begin(); }
|
rstl::reserved_vector<CCollisionInfo, 32>::iterator begin() { return x0_list.begin(); }
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "CollisionUtil.hpp"
|
#include "CollisionUtil.hpp"
|
||||||
#include "World/CScriptPlatform.hpp"
|
#include "World/CScriptPlatform.hpp"
|
||||||
#include "CCollidableSphere.hpp"
|
#include "CCollidableSphere.hpp"
|
||||||
|
#include "Character/CGroundMovement.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -21,9 +22,9 @@ static float CollisionImpulseFiniteVsInfinite(float mass, float velNormDot, floa
|
||||||
return mass * ((1.f / restitution) * velNormDot);
|
return mass * ((1.f / restitution) * velNormDot);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float CollisionImpulseFiniteVsFinite(float mass, float velNormDot, float restitution, float f4)
|
static float CollisionImpulseFiniteVsFinite(float mass0, float mass1, float velNormDot, float restitution)
|
||||||
{
|
{
|
||||||
return (-(1.f + f4) * restitution) / ((1.f / mass) + (1.f / velNormDot));
|
return (-(1.f + restitution) * velNormDot) / ((1.f / mass0) + (1.f / mass1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameCollision::InitCollision()
|
void CGameCollision::InitCollision()
|
||||||
|
@ -68,36 +69,13 @@ void CGameCollision::MovePlayer(CStateManager& mgr, CPhysicsActor& actor, float
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (actor.GetMaterialList().HasMaterial(EMaterialTypes::GroundCollider))
|
if (actor.GetMaterialList().HasMaterial(EMaterialTypes::GroundCollider))
|
||||||
MoveGroundCollider_New(mgr, actor, dt, colliderList);
|
CGroundMovement::MoveGroundCollider_New(mgr, actor, dt, colliderList);
|
||||||
else
|
else
|
||||||
MoveAndCollide(mgr, actor, dt, CBallFilter(actor), colliderList);
|
MoveAndCollide(mgr, actor, dt, CBallFilter(actor), colliderList);
|
||||||
}
|
}
|
||||||
actor.SetAngularEnabled(false);
|
actor.SetAngularEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameCollision::MoveGroundCollider(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList)
|
|
||||||
{
|
|
||||||
CMotionState oldState = actor.GetMotionState();
|
|
||||||
CMotionState newState = actor.PredictMotion_Internal(dt);
|
|
||||||
newState.x0_translation.magnitude();
|
|
||||||
actor.GetMaterialFilter();
|
|
||||||
zeus::CAABox motionVol = actor.GetMotionVolume(dt);
|
|
||||||
rstl::reserved_vector<TUniqueId, 1024> augmentedColliderList;
|
|
||||||
if (colliderList)
|
|
||||||
augmentedColliderList = *colliderList;
|
|
||||||
mgr.BuildColliderList(augmentedColliderList, actor, motionVol);
|
|
||||||
CAreaCollisionCache cache(motionVol);
|
|
||||||
actor.GetCollisionPrimitive()->GetPrimType();
|
|
||||||
// TODO: finish
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGameCollision::MoveGroundCollider_New(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList)
|
|
||||||
{
|
|
||||||
// TODO: finish
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGameCollision::MoveAndCollide(CStateManager& mgr, CPhysicsActor& actor, float dt, const ICollisionFilter& filter,
|
void CGameCollision::MoveAndCollide(CStateManager& mgr, CPhysicsActor& actor, float dt, const ICollisionFilter& filter,
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList)
|
const rstl::reserved_vector<TUniqueId, 1024>* colliderList)
|
||||||
{
|
{
|
||||||
|
@ -246,7 +224,7 @@ void CGameCollision::Move(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
||||||
if (actor.GetMaterialList().HasMaterial(EMaterialTypes::Player))
|
if (actor.GetMaterialList().HasMaterial(EMaterialTypes::Player))
|
||||||
MovePlayer(mgr, actor, dt, colliderList);
|
MovePlayer(mgr, actor, dt, colliderList);
|
||||||
else if (actor.GetMaterialList().HasMaterial(EMaterialTypes::GroundCollider))
|
else if (actor.GetMaterialList().HasMaterial(EMaterialTypes::GroundCollider))
|
||||||
MoveGroundCollider(mgr, actor, dt, colliderList);
|
CGroundMovement::MoveGroundCollider(mgr, actor, dt, colliderList);
|
||||||
else
|
else
|
||||||
MoveAndCollide(mgr, actor, dt, CAABoxFilter(actor), colliderList);
|
MoveAndCollide(mgr, actor, dt, CAABoxFilter(actor), colliderList);
|
||||||
}
|
}
|
||||||
|
@ -587,6 +565,17 @@ bool CGameCollision::DetectCollision_Cached(CStateManager& mgr, CAreaCollisionCa
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CGameCollision::DetectCollision_Cached_Moving(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||||
|
const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||||
|
const CMaterialFilter& filter,
|
||||||
|
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
|
const zeus::CVector3f& vec,
|
||||||
|
TUniqueId& idOut, CCollisionInfo& infoOut, double&)
|
||||||
|
{
|
||||||
|
// TODO: Finish
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool CGameCollision::DetectStaticCollision(CStateManager& mgr, const CCollisionPrimitive& prim,
|
bool CGameCollision::DetectStaticCollision(CStateManager& mgr, const CCollisionPrimitive& prim,
|
||||||
const zeus::CTransform& xf, const CMaterialFilter& filter,
|
const zeus::CTransform& xf, const CMaterialFilter& filter,
|
||||||
CCollisionInfoList& list)
|
CCollisionInfoList& list)
|
||||||
|
@ -777,16 +766,80 @@ void CGameCollision::ResolveCollisions(CPhysicsActor& a0, CPhysicsActor* a1, con
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameCollision::CollideWithDynamicBodyNoRot(CPhysicsActor& a0, CPhysicsActor& a1,
|
void CGameCollision::CollideWithDynamicBodyNoRot(CPhysicsActor& a0, CPhysicsActor& a1,
|
||||||
const CCollisionInfo& info, float restitution, bool)
|
const CCollisionInfo& info, float restitution, bool zeroZ)
|
||||||
{
|
{
|
||||||
/* TODO: Finish */
|
zeus::CVector3f normal = info.GetNormalLeft();
|
||||||
|
if (zeroZ)
|
||||||
|
normal.z = 0.f;
|
||||||
|
|
||||||
|
zeus::CVector3f relVel = GetActorRelativeVelocities(a0, &a1);
|
||||||
|
float velNormDot = relVel.dot(normal);
|
||||||
|
|
||||||
|
float a0MaxCollisionVel = std::max(a0.GetVelocity().magnitude(), a0.GetMaximumCollisionVelocity());
|
||||||
|
float a1MaxCollisionVel = std::max(a1.GetVelocity().magnitude(), a1.GetMaximumCollisionVelocity());
|
||||||
|
|
||||||
|
bool a0Move = !a0.GetMaterialList().HasMaterial(EMaterialTypes::Immovable) && a0.GetMass() != 0.f;
|
||||||
|
bool a1Move = !a1.GetMaterialList().HasMaterial(EMaterialTypes::Immovable) && a1.GetMass() != 0.f;
|
||||||
|
|
||||||
|
if (velNormDot < -0.0001f)
|
||||||
|
{
|
||||||
|
if (a0Move)
|
||||||
|
{
|
||||||
|
if (a1Move)
|
||||||
|
{
|
||||||
|
float impulse = CollisionImpulseFiniteVsFinite(a0.GetMass(), a1.GetMass(), velNormDot, restitution);
|
||||||
|
a0.ApplyImpulseWR(normal * impulse, zeus::CAxisAngle::sIdentity);
|
||||||
|
a1.ApplyImpulseWR(normal * -impulse, zeus::CAxisAngle::sIdentity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float impulse = CollisionImpulseFiniteVsInfinite(a0.GetMass(), velNormDot, restitution);
|
||||||
|
a0.ApplyImpulseWR(normal * impulse, zeus::CAxisAngle::sIdentity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (a1Move)
|
||||||
|
{
|
||||||
|
float impulse = CollisionImpulseFiniteVsInfinite(a1.GetMass(), velNormDot, restitution);
|
||||||
|
a1.ApplyImpulseWR(normal * -impulse, zeus::CAxisAngle::sIdentity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a0.SetVelocityWR(zeus::CVector3f::skZero);
|
||||||
|
a1.SetVelocityWR(zeus::CVector3f::skZero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a0.UseCollisionImpulses();
|
||||||
|
a1.UseCollisionImpulses();
|
||||||
|
}
|
||||||
|
else if (velNormDot < 0.1f)
|
||||||
|
{
|
||||||
|
if (a0Move)
|
||||||
|
{
|
||||||
|
float impulse = 0.05f * a0.GetMass();
|
||||||
|
a0.ApplyImpulseWR(normal * impulse, zeus::CAxisAngle::sIdentity);
|
||||||
|
a0.UseCollisionImpulses();
|
||||||
|
}
|
||||||
|
if (a1Move)
|
||||||
|
{
|
||||||
|
float impulse = -0.05f * a1.GetMass();
|
||||||
|
a1.ApplyImpulseWR(normal * impulse, zeus::CAxisAngle::sIdentity);
|
||||||
|
a1.UseCollisionImpulses();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a0.GetVelocity().magnitude() > a0MaxCollisionVel)
|
||||||
|
a0.SetVelocityWR(a0.GetVelocity().normalized() * a0MaxCollisionVel);
|
||||||
|
if (a1.GetVelocity().magnitude() > a1MaxCollisionVel)
|
||||||
|
a1.SetVelocityWR(a1.GetVelocity().normalized() * a1MaxCollisionVel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameCollision::CollideWithStaticBodyNoRot(CPhysicsActor& a0, const CMaterialList& m0, const CMaterialList& m1,
|
void CGameCollision::CollideWithStaticBodyNoRot(CPhysicsActor& a0, const CMaterialList& m0, const CMaterialList& m1,
|
||||||
const zeus::CUnitVector3f& normal, float restitution, bool b)
|
const zeus::CUnitVector3f& normal, float restitution, bool zeroZ)
|
||||||
{
|
{
|
||||||
zeus::CUnitVector3f useNorm = normal;
|
zeus::CUnitVector3f useNorm = normal;
|
||||||
if (b && m0.HasMaterial(EMaterialTypes::Player) && !m1.HasMaterial(EMaterialTypes::Floor))
|
if (zeroZ && m0.HasMaterial(EMaterialTypes::Player) && !m1.HasMaterial(EMaterialTypes::Floor))
|
||||||
useNorm.z = 0.f;
|
useNorm.z = 0.f;
|
||||||
|
|
||||||
if (useNorm.canBeNormalized())
|
if (useNorm.canBeNormalized())
|
||||||
|
@ -825,7 +878,37 @@ void CGameCollision::CollisionFailsafe(CStateManager& mgr, CAreaCollisionCache&
|
||||||
actor.SetNumTicksStuck(actor.GetNumTicksStuck() + 1);
|
actor.SetNumTicksStuck(actor.GetNumTicksStuck() + 1);
|
||||||
if (actor.GetNumTicksStuck() < failsafeTicks)
|
if (actor.GetNumTicksStuck() < failsafeTicks)
|
||||||
return;
|
return;
|
||||||
/* TODO: Finish */
|
|
||||||
|
CMotionState oldMState = actor.GetMotionState();
|
||||||
|
CMotionState lastNonCollide = actor.GetLastNonCollidingState();
|
||||||
|
actor.SetMotionState(lastNonCollide);
|
||||||
|
if (!DetectCollisionBoolean_Cached(mgr, cache, prim, actor.GetPrimitiveTransform(),
|
||||||
|
actor.GetMaterialFilter(), nearList))
|
||||||
|
{
|
||||||
|
lastNonCollide.x1c_velocity *= 0.5f;
|
||||||
|
lastNonCollide.x28_angularMomentum *= 0.5f;
|
||||||
|
actor.SetLastNonCollidingState(lastNonCollide);
|
||||||
|
//++gDebugPrintCount;
|
||||||
|
actor.SetNumTicksStuck(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
actor.SetMotionState(oldMState);
|
||||||
|
if (auto nonIntersectVec = FindNonIntersectingVector(mgr, cache, actor, prim, nearList))
|
||||||
|
{
|
||||||
|
oldMState.x0_translation += *nonIntersectVec;
|
||||||
|
actor.SetMotionState(oldMState);
|
||||||
|
actor.SetLastNonCollidingState(actor.GetMotionState());
|
||||||
|
//++gDebugPrintCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//++gDebugPrintCount;
|
||||||
|
lastNonCollide.x1c_velocity *= 0.5f;
|
||||||
|
lastNonCollide.x28_angularMomentum *= 0.5f;
|
||||||
|
actor.SetLastNonCollidingState(lastNonCollide);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -833,4 +916,117 @@ void CGameCollision::CollisionFailsafe(CStateManager& mgr, CAreaCollisionCache&
|
||||||
actor.SetNumTicksStuck(0);
|
actor.SetNumTicksStuck(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::experimental::optional<zeus::CVector3f>
|
||||||
|
CGameCollision::FindNonIntersectingVector(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||||
|
CPhysicsActor& actor, const CCollisionPrimitive& prim,
|
||||||
|
const rstl::reserved_vector<TUniqueId, 1024>& nearList)
|
||||||
|
{
|
||||||
|
zeus::CTransform xf = actor.GetPrimitiveTransform();
|
||||||
|
zeus::CVector3f center = prim.CalculateAABox(xf).center();
|
||||||
|
for (int i=2 ; i<1000 ; i+=(i/2))
|
||||||
|
{
|
||||||
|
float pos = i * 0.005f;
|
||||||
|
float neg = -pos;
|
||||||
|
for (int j=0 ; j<26 ; ++j)
|
||||||
|
{
|
||||||
|
zeus::CVector3f vec;
|
||||||
|
switch (j)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
vec = {0.f, pos, 0.f};
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
vec = {0.f, neg, 0.f};
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
vec = {pos, 0.f, 0.f};
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
vec = {neg, 0.f, 0.f};
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
vec = {0.f, 0.f, pos};
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
vec = {0.f, 0.f, neg};
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
vec = {0.f, pos, pos};
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
vec = {0.f, neg, neg};
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
vec = {0.f, neg, pos};
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
vec = {0.f, pos, neg};
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
vec = {pos, 0.f, pos};
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
vec = {neg, 0.f, neg};
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
vec = {neg, 0.f, pos};
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
vec = {pos, 0.f, neg};
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
vec = {pos, pos, 0.f};
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
vec = {neg, neg, 0.f};
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
vec = {neg, pos, 0.f};
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
vec = {pos, neg, 0.f};
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
|
vec = {pos, pos, pos};
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
vec = {neg, pos, pos};
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
vec = {pos, neg, pos};
|
||||||
|
break;
|
||||||
|
case 21:
|
||||||
|
vec = {neg, neg, pos};
|
||||||
|
break;
|
||||||
|
case 22:
|
||||||
|
vec = {pos, pos, neg};
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
vec = {neg, pos, neg};
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
vec = {pos, neg, neg};
|
||||||
|
break;
|
||||||
|
case 25:
|
||||||
|
vec = {neg, neg, neg};
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CVector3f worldPoint = vec + xf.origin;
|
||||||
|
if (mgr.GetWorld()->GetAreaAlways(mgr.GetNextAreaId())->GetAABB().pointInside(worldPoint))
|
||||||
|
{
|
||||||
|
if (mgr.RayCollideWorld(center, center + vec, nearList,
|
||||||
|
CMaterialFilter::skPassEverything, actor))
|
||||||
|
{
|
||||||
|
if (!DetectCollisionBoolean_Cached(mgr, cache, prim, xf, actor.GetMaterialFilter(), nearList))
|
||||||
|
return {vec};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,6 @@ class CGameCollision
|
||||||
{
|
{
|
||||||
static void MovePlayer(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
static void MovePlayer(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList);
|
const rstl::reserved_vector<TUniqueId, 1024>* colliderList);
|
||||||
static void MoveGroundCollider(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList);
|
|
||||||
static void MoveGroundCollider_New(CStateManager& mgr, CPhysicsActor& actor, float dt,
|
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList);
|
|
||||||
static void MoveAndCollide(CStateManager& mgr, CPhysicsActor& actor, float dt, const ICollisionFilter& filter,
|
static void MoveAndCollide(CStateManager& mgr, CPhysicsActor& actor, float dt, const ICollisionFilter& filter,
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>* colliderList);
|
const rstl::reserved_vector<TUniqueId, 1024>* colliderList);
|
||||||
static zeus::CVector3f GetActorRelativeVelocities(const CPhysicsActor& act0, const CPhysicsActor* act1);
|
static zeus::CVector3f GetActorRelativeVelocities(const CPhysicsActor& act0, const CPhysicsActor* act1);
|
||||||
|
@ -84,6 +80,12 @@ public:
|
||||||
const CMaterialFilter& filter,
|
const CMaterialFilter& filter,
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
TUniqueId& idOut, CCollisionInfoList& infoList);
|
TUniqueId& idOut, CCollisionInfoList& infoList);
|
||||||
|
static bool DetectCollision_Cached_Moving(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||||
|
const CCollisionPrimitive& prim, const zeus::CTransform& xf,
|
||||||
|
const CMaterialFilter& filter,
|
||||||
|
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
|
const zeus::CVector3f& vec,
|
||||||
|
TUniqueId& idOut, CCollisionInfo& infoOut, double&);
|
||||||
static bool DetectStaticCollision(CStateManager& mgr, const CCollisionPrimitive& prim,
|
static bool DetectStaticCollision(CStateManager& mgr, const CCollisionPrimitive& prim,
|
||||||
const zeus::CTransform& xf, const CMaterialFilter& filter,
|
const zeus::CTransform& xf, const CMaterialFilter& filter,
|
||||||
CCollisionInfoList& list);
|
CCollisionInfoList& list);
|
||||||
|
@ -105,6 +107,10 @@ public:
|
||||||
CPhysicsActor& actor, const CCollisionPrimitive& prim,
|
CPhysicsActor& actor, const CCollisionPrimitive& prim,
|
||||||
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
const rstl::reserved_vector<TUniqueId, 1024>& nearList,
|
||||||
float, u32 failsafeTicks);
|
float, u32 failsafeTicks);
|
||||||
|
static std::experimental::optional<zeus::CVector3f>
|
||||||
|
FindNonIntersectingVector(CStateManager& mgr, CAreaCollisionCache& cache,
|
||||||
|
CPhysicsActor& actor, const CCollisionPrimitive& prim,
|
||||||
|
const rstl::reserved_vector<TUniqueId, 1024>& nearList);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,11 @@ public:
|
||||||
{
|
{
|
||||||
return other.x0_list & x0_list;
|
return other.x0_list & x0_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 XOR(const CMaterialList& other) const
|
||||||
|
{
|
||||||
|
return x0_list ^ other.x0_list;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,26 @@ void FilterOutBackfaces(const zeus::CVector3f& vec, const CCollisionInfoList& in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FilterByClosestNormal(const zeus::CVector3f& norm, const CCollisionInfoList& in, CCollisionInfoList& out)
|
||||||
|
{
|
||||||
|
float maxDot = -1.1f;
|
||||||
|
int idx = -1;
|
||||||
|
int i=0;
|
||||||
|
for (const CCollisionInfo& info : in)
|
||||||
|
{
|
||||||
|
float dot = info.GetNormalLeft().dot(norm);
|
||||||
|
if (dot > maxDot)
|
||||||
|
{
|
||||||
|
maxDot = dot;
|
||||||
|
idx = i;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx != -1)
|
||||||
|
out.Add(in.GetItem(i), false);
|
||||||
|
}
|
||||||
|
|
||||||
static const zeus::CVector3f AABBNormalTable[] =
|
static const zeus::CVector3f AABBNormalTable[] =
|
||||||
{
|
{
|
||||||
{-1.f, 0.f, 0.f},
|
{-1.f, 0.f, 0.f},
|
||||||
|
|
|
@ -16,6 +16,7 @@ u32 RaySphereIntersection_Double(const zeus::CSphere&, const zeus::CVector3f&, c
|
||||||
bool RaySphereIntersection(const zeus::CSphere& sphere, const zeus::CVector3f& pos, const zeus::CVector3f& dir,
|
bool RaySphereIntersection(const zeus::CSphere& sphere, const zeus::CVector3f& pos, const zeus::CVector3f& dir,
|
||||||
float mag, float& T, zeus::CVector3f& point);
|
float mag, float& T, zeus::CVector3f& point);
|
||||||
void FilterOutBackfaces(const zeus::CVector3f& vec, const CCollisionInfoList& in, CCollisionInfoList& out);
|
void FilterOutBackfaces(const zeus::CVector3f& vec, const CCollisionInfoList& in, CCollisionInfoList& out);
|
||||||
|
void FilterByClosestNormal(const zeus::CVector3f& norm, const CCollisionInfoList& in, CCollisionInfoList& out);
|
||||||
bool AABoxAABoxIntersection(const zeus::CAABox& aabb0, const CMaterialList& list0,
|
bool AABoxAABoxIntersection(const zeus::CAABox& aabb0, const CMaterialList& list0,
|
||||||
const zeus::CAABox& aabb1, const CMaterialList& list1,
|
const zeus::CAABox& aabb1, const CMaterialList& list1,
|
||||||
CCollisionInfoList& infoList);
|
CCollisionInfoList& infoList);
|
||||||
|
|
|
@ -114,6 +114,7 @@ class TCastToPtr : public IVisitor
|
||||||
protected:
|
protected:
|
||||||
T* ptr = nullptr;
|
T* ptr = nullptr;
|
||||||
public:
|
public:
|
||||||
|
TCastToPtr() = default;
|
||||||
TCastToPtr(CEntity* p);
|
TCastToPtr(CEntity* p);
|
||||||
TCastToPtr(CEntity& p);
|
TCastToPtr(CEntity& p);
|
||||||
|
|
||||||
|
@ -134,6 +135,7 @@ template <class T>
|
||||||
class TCastToConstPtr : TCastToPtr<T>
|
class TCastToConstPtr : TCastToPtr<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
TCastToConstPtr() = default;
|
||||||
TCastToConstPtr(const CEntity* p) : TCastToPtr<T>(const_cast<CEntity*>(p)) {}
|
TCastToConstPtr(const CEntity* p) : TCastToPtr<T>(const_cast<CEntity*>(p)) {}
|
||||||
TCastToConstPtr(const CEntity& p) : TCastToPtr<T>(const_cast<CEntity&>(p)) {}
|
TCastToConstPtr(const CEntity& p) : TCastToPtr<T>(const_cast<CEntity&>(p)) {}
|
||||||
const T* GetPtr() const { return TCastToPtr<T>::ptr; }
|
const T* GetPtr() const { return TCastToPtr<T>::ptr; }
|
||||||
|
|
|
@ -78,6 +78,7 @@ public:
|
||||||
|
|
||||||
class CPhysicsActor : public CActor
|
class CPhysicsActor : public CActor
|
||||||
{
|
{
|
||||||
|
friend class CGroundMovement;
|
||||||
protected:
|
protected:
|
||||||
float xe8_mass;
|
float xe8_mass;
|
||||||
float xec_massRecip;
|
float xec_massRecip;
|
||||||
|
@ -108,7 +109,7 @@ protected:
|
||||||
CCollidableAABox x1c0_collisionPrimitive;
|
CCollidableAABox x1c0_collisionPrimitive;
|
||||||
zeus::CVector3f x1e8_primitiveOffset;
|
zeus::CVector3f x1e8_primitiveOffset;
|
||||||
CMotionState x1f4_lastNonCollidingState;
|
CMotionState x1f4_lastNonCollidingState;
|
||||||
bool x234_ = false;
|
std::experimental::optional<zeus::CVector3f> x228_lastFloorPlaneNormal;
|
||||||
float x238_maximumCollisionVelocity = 1000000.0f;
|
float x238_maximumCollisionVelocity = 1000000.0f;
|
||||||
float x23c_stepUpHeight;
|
float x23c_stepUpHeight;
|
||||||
float x240_stepDownHeight;
|
float x240_stepDownHeight;
|
||||||
|
@ -138,7 +139,7 @@ public:
|
||||||
zeus::CVector3f GetPrimitiveOffset();
|
zeus::CVector3f GetPrimitiveOffset();
|
||||||
void MoveCollisionPrimitive(const zeus::CVector3f& offset);
|
void MoveCollisionPrimitive(const zeus::CVector3f& offset);
|
||||||
void SetBoundingBox(const zeus::CAABox& box);
|
void SetBoundingBox(const zeus::CAABox& box);
|
||||||
zeus::CAABox GetMotionVolume(float f31) const;
|
zeus::CAABox GetMotionVolume(float dt) const;
|
||||||
zeus::CVector3f CalculateNewVelocityWR_UsingImpulses() const;
|
zeus::CVector3f CalculateNewVelocityWR_UsingImpulses() const;
|
||||||
zeus::CAABox GetBoundingBox() const;
|
zeus::CAABox GetBoundingBox() const;
|
||||||
const zeus::CAABox& GetBaseBoundingBox() const;
|
const zeus::CAABox& GetBaseBoundingBox() const;
|
||||||
|
@ -153,9 +154,12 @@ public:
|
||||||
void SetMass(float mass);
|
void SetMass(float mass);
|
||||||
void SetAngularVelocityOR(const zeus::CAxisAngle& angVel);
|
void SetAngularVelocityOR(const zeus::CAxisAngle& angVel);
|
||||||
zeus::CAxisAngle GetAngularVelocityOR() const;
|
zeus::CAxisAngle GetAngularVelocityOR() const;
|
||||||
|
const zeus::CAxisAngle& GetAngularVelocityWR() const { return x144_angularVelocity; }
|
||||||
void SetAngularVelocityWR(const zeus::CAxisAngle& angVel);
|
void SetAngularVelocityWR(const zeus::CAxisAngle& angVel);
|
||||||
void SetVelocityWR(const zeus::CVector3f& vel);
|
void SetVelocityWR(const zeus::CVector3f& vel);
|
||||||
void SetVelocityOR(const zeus::CVector3f& vel);
|
void SetVelocityOR(const zeus::CVector3f& vel);
|
||||||
|
void SetMomentumWR(const zeus::CVector3f& m) { x150_momentum = m; }
|
||||||
|
const zeus::CVector3f& GetMomentum() const { return x150_momentum; }
|
||||||
const zeus::CVector3f& GetVelocity() const { return x138_velocity; }
|
const zeus::CVector3f& GetVelocity() const { return x138_velocity; }
|
||||||
zeus::CVector3f GetTotalForcesWR() const;
|
zeus::CVector3f GetTotalForcesWR() const;
|
||||||
void RotateInOneFrameOR(const zeus::CQuaternion& q, float d);
|
void RotateInOneFrameOR(const zeus::CQuaternion& q, float d);
|
||||||
|
@ -186,6 +190,8 @@ public:
|
||||||
void SetNumTicksPartialUpdate(u32 t) { x250_numTicksPartialUpdate = t; }
|
void SetNumTicksPartialUpdate(u32 t) { x250_numTicksPartialUpdate = t; }
|
||||||
u32 GetNumTicksStuck() const { return x24c_numTicksStuck; }
|
u32 GetNumTicksStuck() const { return x24c_numTicksStuck; }
|
||||||
void SetNumTicksStuck(u32 t) { x24c_numTicksStuck = t; }
|
void SetNumTicksStuck(u32 t) { x24c_numTicksStuck = t; }
|
||||||
|
const std::experimental::optional<zeus::CVector3f>& GetLastFloorPlaneNormal() const { return x228_lastFloorPlaneNormal; }
|
||||||
|
void SetLastFloorPlaneNormal(const std::experimental::optional<zeus::CVector3f>& n) { x228_lastFloorPlaneNormal = n; }
|
||||||
|
|
||||||
CMotionState PredictMotion_Internal(float) const;
|
CMotionState PredictMotion_Internal(float) const;
|
||||||
CMotionState PredictMotion(float dt) const;
|
CMotionState PredictMotion(float dt) const;
|
||||||
|
|
|
@ -947,6 +947,12 @@ bool CPlayer::ObjectInScanningRange(TUniqueId id, const CStateManager& mgr) cons
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPlayer::SetPlayerHitWallDuringMove()
|
||||||
|
{
|
||||||
|
x9c5_29_hitWall = true;
|
||||||
|
x2d0_ = 1;
|
||||||
|
}
|
||||||
|
|
||||||
void CPlayer::Touch() {}
|
void CPlayer::Touch() {}
|
||||||
|
|
||||||
void CPlayer::CVisorSteam::SetSteam(float a, float b, float c, ResId d, bool e)
|
void CPlayer::CVisorSteam::SetSteam(float a, float b, float c, ResId d, bool e)
|
||||||
|
|
|
@ -27,6 +27,7 @@ class CPlayer : public CPhysicsActor
|
||||||
friend class CFirstPersonCamera;
|
friend class CFirstPersonCamera;
|
||||||
friend class CPlayerCameraBob;
|
friend class CPlayerCameraBob;
|
||||||
friend class CMorphBall;
|
friend class CMorphBall;
|
||||||
|
friend class CGroundMovement;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class EPlayerScanState
|
enum class EPlayerScanState
|
||||||
|
@ -318,13 +319,13 @@ private:
|
||||||
bool x9c4_28_ : 1;
|
bool x9c4_28_ : 1;
|
||||||
bool x9c4_29_ : 1;
|
bool x9c4_29_ : 1;
|
||||||
bool x9c4_30_ : 1;
|
bool x9c4_30_ : 1;
|
||||||
bool x9c4_31_ : 1;
|
bool x9c4_31_dampUnderwaterMotion : 1;
|
||||||
bool x9c5_24_ : 1;
|
bool x9c5_24_ : 1;
|
||||||
bool x9c5_25_splashUpdated : 1;
|
bool x9c5_25_splashUpdated : 1;
|
||||||
bool x9c5_26_ : 1;
|
bool x9c5_26_ : 1;
|
||||||
bool x9c5_27_ : 1;
|
bool x9c5_27_ : 1;
|
||||||
bool x9c5_28_ : 1;
|
bool x9c5_28_slidingOnWall : 1;
|
||||||
bool x9c5_29_ : 1;
|
bool x9c5_29_hitWall : 1;
|
||||||
bool x9c5_30_ : 1;
|
bool x9c5_30_ : 1;
|
||||||
bool x9c5_31_ : 1;
|
bool x9c5_31_ : 1;
|
||||||
bool x9c6_24_ : 1;
|
bool x9c6_24_ : 1;
|
||||||
|
@ -543,6 +544,7 @@ public:
|
||||||
const std::vector<TUniqueId>& GetNearbyOrbitObjects() const { return x344_nearbyOrbitObjects; }
|
const std::vector<TUniqueId>& GetNearbyOrbitObjects() const { return x344_nearbyOrbitObjects; }
|
||||||
const std::vector<TUniqueId>& GetOnScreenOrbitObjects() const { return x354_onScreenOrbitObjects; }
|
const std::vector<TUniqueId>& GetOnScreenOrbitObjects() const { return x354_onScreenOrbitObjects; }
|
||||||
const std::vector<TUniqueId>& GetOffScreenOrbitObjects() const { return x364_offScreenOrbitObjects; }
|
const std::vector<TUniqueId>& GetOffScreenOrbitObjects() const { return x364_offScreenOrbitObjects; }
|
||||||
|
void SetPlayerHitWallDuringMove();
|
||||||
|
|
||||||
void Touch();
|
void Touch();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue