diff --git a/Runtime/Collision/CCollidableOBBTreeGroup.cpp b/Runtime/Collision/CCollidableOBBTreeGroup.cpp index ae227ca47..de3cdf98e 100644 --- a/Runtime/Collision/CCollidableOBBTreeGroup.cpp +++ b/Runtime/Collision/CCollidableOBBTreeGroup.cpp @@ -7,7 +7,7 @@ namespace urde const CCollisionPrimitive::Type CCollidableOBBTreeGroup::sType(CCollidableOBBTreeGroup::SetStaticTableIndex, "CCollidableOBBTreeGroup"); u32 CCollidableOBBTreeGroup::sTableIndex = -1; -CCollidableOBBTreeGroup::CCollidableOBBTreeGroup(CInputStream& in) +CCollidableOBBTreeGroupContainer::CCollidableOBBTreeGroupContainer(CInputStream& in) { u32 treeCount = in.readUint32Big(); x0_trees.reserve(treeCount); @@ -24,6 +24,17 @@ CCollidableOBBTreeGroup::CCollidableOBBTreeGroup(CInputStream& in) x10_aabbs.push_back(CCollidableOBBTree(tree.get(), CMaterialList()).CalculateLocalAABox()); } +CCollidableOBBTreeGroupContainer::CCollidableOBBTreeGroupContainer(const zeus::CVector3f &, const zeus::CVector3f &) +{ +} + +CCollidableOBBTreeGroup::CCollidableOBBTreeGroup(const CCollidableOBBTreeGroupContainer* container, + const CMaterialList& matList) +: CCollisionPrimitive(matList) +, x10_container(container) +{ +} + void CCollidableOBBTreeGroup::ResetTestStats() const { @@ -36,12 +47,12 @@ u32 CCollidableOBBTreeGroup::GetTableIndex() const zeus::CAABox CCollidableOBBTreeGroup::CalculateAABox(const zeus::CTransform& xf) const { - return x10_aabbs.front().getTransformedAABox(xf); + return x10_container->x20_aabox.getTransformedAABox(xf); } zeus::CAABox CCollidableOBBTreeGroup::CalculateLocalAABox() const { - return x10_aabbs.front(); + return x10_container->x20_aabox; } FourCC CCollidableOBBTreeGroup::GetPrimType() const @@ -98,7 +109,7 @@ CFactoryFnReturn FCollidableOBBTreeGroupFactory(const SObjectTag &tag, CInputStr const CVParamTransfer& vparms, CObjectReference* selfRef) { - return TToken::GetIObjObjectFor(std::make_unique(in)); + return TToken::GetIObjObjectFor(std::make_unique(in)); } } diff --git a/Runtime/Collision/CCollidableOBBTreeGroup.hpp b/Runtime/Collision/CCollidableOBBTreeGroup.hpp index 7e9a0a5cb..6ae7a5e8d 100644 --- a/Runtime/Collision/CCollidableOBBTreeGroup.hpp +++ b/Runtime/Collision/CCollidableOBBTreeGroup.hpp @@ -9,15 +9,25 @@ namespace urde { +class CCollidableOBBTreeGroupContainer +{ + friend class CCollidableOBBTreeGroup; + std::vector> x0_trees; + std::vector x10_aabbs; + zeus::CAABox x20_aabox; +public: + CCollidableOBBTreeGroupContainer(CInputStream& in); + CCollidableOBBTreeGroupContainer(const zeus::CVector3f&, const zeus::CVector3f&); +}; + class CCollidableOBBTreeGroup : public CCollisionPrimitive { static const Type sType; static u32 sTableIndex; - std::vector> x0_trees; - std::vector x10_aabbs; - + const CCollidableOBBTreeGroupContainer* x10_container; public: CCollidableOBBTreeGroup(CInputStream& in); + CCollidableOBBTreeGroup(const CCollidableOBBTreeGroupContainer*, const CMaterialList&); virtual ~CCollidableOBBTreeGroup() {} void ResetTestStats() const; diff --git a/Runtime/Collision/CCollisionActor.cpp b/Runtime/Collision/CCollisionActor.cpp index 08f952617..b56a54057 100644 --- a/Runtime/Collision/CCollisionActor.cpp +++ b/Runtime/Collision/CCollisionActor.cpp @@ -1,5 +1,10 @@ #include "CCollisionActor.hpp" +#include "Camera/CGameCamera.hpp" +#include "CStateManager.hpp" #include "World/CActorParameters.hpp" +#include "Collision/CCollidableOBBTreeGroup.hpp" +#include "Collision/CCollidableSphere.hpp" +#include "TCastTo.hpp" namespace urde { @@ -12,24 +17,54 @@ CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, co : CPhysicsActor(uid1, active, "CollisionActor", CEntityInfo(aId, CEntity::NullConnectionList), zeus::CTransform::Identity(), CModelData::CModelDataNull(), gkDefaultCollisionActorMaterials, zeus::CAABox::skNullBox, SMoverData(mass), CActorParameters::None(), 0.3f, 0.1f) +, x258_primitiveType(EPrimitiveType::OBBTreeGroup) +, x25c_owner(uid2) +, x260_boxSize(vec1) +, x26c_(vec2) +, x278_obbContainer(new CCollidableOBBTreeGroupContainer(vec1, vec2)) +, x27c_obbTreeGroupPrimitive(new CCollidableOBBTreeGroup(x278_obbContainer.get(), GetMaterialList())) { + SetCoefficientOfRestitutionModifier(0.5f); + SetCallTouch(false); + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude( + {EMaterialTypes::Solid}, {EMaterialTypes::CollisionActor, EMaterialTypes::ThirtyEight})); } -CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, const zeus::CVector3f& vec, bool active, - float mass) +CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, const zeus::CVector3f& boxSize, + bool active, float mass) : CPhysicsActor(uid1, active, "CollisionActor", CEntityInfo(aId, CEntity::NullConnectionList), zeus::CTransform::Identity(), CModelData::CModelDataNull(), gkDefaultCollisionActorMaterials, zeus::CAABox::skNullBox, SMoverData(mass), CActorParameters::None(), 0.3f, 0.1f) +, x258_primitiveType(EPrimitiveType::AABox) +, x25c_owner(uid2) +, x260_boxSize(boxSize) +, x280_aaboxPrimitive(new CCollidableAABox(zeus::CAABox(-0.5f * boxSize, 0.5f * boxSize), + CMaterialList(EMaterialTypes::Solid, EMaterialTypes::ThirtyEight))) { + SetCoefficientOfRestitutionModifier(0.5f); + SetCallTouch(false); + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude( + {EMaterialTypes::Solid}, {EMaterialTypes::CollisionActor, EMaterialTypes::ThirtyEight})); } -CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, bool active, float, float mass) +CCollisionActor::CCollisionActor(TUniqueId uid1, TAreaId aId, TUniqueId uid2, bool active, float radius, float mass) : CPhysicsActor(uid1, active, "CollisionActor", CEntityInfo(aId, CEntity::NullConnectionList), zeus::CTransform::Identity(), CModelData::CModelDataNull(), gkDefaultCollisionActorMaterials, zeus::CAABox::skNullBox, SMoverData(mass), CActorParameters::None(), 0.3f, 0.1f) +, x258_primitiveType(EPrimitiveType::Sphere) +, x25c_owner(uid2) +, x284_spherePrimitive(new CCollidableSphere(zeus::CSphere(zeus::CVector3f::skZero, radius), + CMaterialList(EMaterialTypes::ThirtyEight, EMaterialTypes::Solid))) +, x288_sphereRadius(radius) { + SetCoefficientOfRestitutionModifier(0.5f); + SetCallTouch(false); + SetMaterialFilter(CMaterialFilter::MakeIncludeExclude( + {EMaterialTypes::Solid}, {EMaterialTypes::CollisionActor, EMaterialTypes::ThirtyEight})); } +void CCollisionActor::Accept(IVisitor& visitor) { visitor.Visit(this); } + void CCollisionActor::AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) {} CHealthInfo* CCollisionActor::HealthInfo() { return &x28c_healthInfo; } @@ -43,4 +78,59 @@ const CDamageVulnerability* CCollisionActor::GetDamageVulnerability(const zeus:: } void CCollisionActor::SetDamageVulnerability(const CDamageVulnerability& vuln) { x294_damageVuln = vuln; } + +zeus::CVector3f CCollisionActor::GetScanObjectIndicatorPosition(const CStateManager& mgr) +{ + const CGameCamera* gameCamera = static_cast(mgr.GetCameraManager()->GetCurrentCamera(mgr)); + return {}; +} + +const CCollisionPrimitive* CCollisionActor::GetCollisionPrimitive() const +{ + if (x258_primitiveType == EPrimitiveType::OBBTreeGroup) + return x27c_obbTreeGroupPrimitive.get(); + if (x258_primitiveType == EPrimitiveType::AABox) + return x280_aaboxPrimitive.get(); + return x284_spherePrimitive.get(); +} + +zeus::CTransform CCollisionActor::GetPrimitiveTransform() const +{ + zeus::CTransform xf = x34_transform; + xf.origin = CPhysicsActor::GetPrimitiveTransform().origin; + return xf; +} + +rstl::optional_object CCollisionActor::GetTouchBounds() const +{ + rstl::optional_object aabox; + if (x258_primitiveType == EPrimitiveType::OBBTreeGroup) + aabox = {x27c_obbTreeGroupPrimitive->CalculateAABox(x34_transform)}; + else if (x258_primitiveType == EPrimitiveType::AABox) + aabox = {x280_aaboxPrimitive->CalculateAABox(x34_transform)}; + else if (x258_primitiveType == EPrimitiveType::Sphere) + aabox = {x280_aaboxPrimitive->CalculateAABox(x34_transform)}; + + aabox->accumulateBounds(aabox->max + x304_extendedTouchBounds); + aabox->accumulateBounds(aabox->min - x304_extendedTouchBounds); + + return aabox; +} + +void CCollisionActor::OnScanStateChanged(CActor::EScanState state, CStateManager& mgr) +{ + TCastToPtr actor = mgr.ObjectById(x25c_owner); + if (actor) + actor->OnScanStateChanged(state, mgr); + + CActor::OnScanStateChanged(state, mgr); +} + +void CCollisionActor::Touch(CActor& actor, CStateManager& mgr) +{ + x2fc_lastTouched = actor.GetUniqueId(); + mgr.SendScriptMsgAlways(x25c_owner, GetUniqueId(), EScriptObjectMessage::InternalMessage08); +} + +zeus::CVector3f CCollisionActor::GetOrbitPosition(const CStateManager&) const { return GetTouchBounds()->center(); } } diff --git a/Runtime/Collision/CCollisionActor.hpp b/Runtime/Collision/CCollisionActor.hpp index 7cecfe297..5e98e20af 100644 --- a/Runtime/Collision/CCollisionActor.hpp +++ b/Runtime/Collision/CCollisionActor.hpp @@ -4,35 +4,58 @@ #include "World/CPhysicsActor.hpp" #include "World/CHealthInfo.hpp" #include "World/CDamageVulnerability.hpp" -#include "Collision/CCollidableOBBTreeGroup.hpp" -#include "Collision/CCollidableSphere.hpp" - namespace urde { +class CCollidableSphere; +class CCollidableOBBTreeGroup; +class CCollidableOBBTreeGroupContainer; class CCollisionActor : public CPhysicsActor { - u32 x258_; - TUniqueId x25c_; + enum class EPrimitiveType + { + OBBTreeGroup, + AABox, + Sphere + }; + + EPrimitiveType x258_primitiveType; + TUniqueId x25c_owner; zeus::CVector3f x260_boxSize; - std::unique_ptr x278_obbTG1; - std::unique_ptr x27c_obbTG2; - std::unique_ptr x284_; + zeus::CVector3f x26c_; + std::unique_ptr x278_obbContainer; + std::unique_ptr x27c_obbTreeGroupPrimitive; + std::unique_ptr x280_aaboxPrimitive; + std::unique_ptr x284_spherePrimitive; float x288_sphereRadius; CHealthInfo x28c_healthInfo = CHealthInfo(0.f); CDamageVulnerability x294_damageVuln = CDamageVulnerability::NormalVulnerabilty(); - TUniqueId x2fc_lastTouched; - EWeaponCollisionResponseTypes x300_responseType; + TUniqueId x2fc_lastTouched = kInvalidUniqueId; + EWeaponCollisionResponseTypes x300_responseType = EWeaponCollisionResponseTypes::EnemyNormal; + zeus::CVector3f x304_extendedTouchBounds = zeus::CVector3f::skZero; public: CCollisionActor(TUniqueId, TAreaId, TUniqueId, const zeus::CVector3f&, const zeus::CVector3f&, bool, float); CCollisionActor(TUniqueId, TAreaId, TUniqueId, const zeus::CVector3f&, bool, float); CCollisionActor(TUniqueId, TAreaId, TUniqueId, bool, float, float); + void Accept(IVisitor &visitor); void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); CHealthInfo* HealthInfo(); const CDamageVulnerability* GetDamageVulnerability() const; const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f&, const CDamageInfo&) const; + void OnScanStateChanged(EScanState, CStateManager &); + + void Touch(CActor &, CStateManager &); + zeus::CVector3f GetOrbitPosition(const CStateManager &) const; + const CCollisionPrimitive* GetCollisionPrimitive() const; + zeus::CTransform GetPrimitiveTransform() const; + rstl::optional_object GetTouchBounds() const; void SetDamageVulnerability(const CDamageVulnerability& vuln); + const zeus::CVector3f& GetBoxSize() const { return x260_boxSize; } + TUniqueId GetOwnerId() const { return x25c_owner; } + TUniqueId GetLastTouchedObject() const { return x2fc_lastTouched; } + zeus::CVector3f GetScanObjectIndicatorPosition(const CStateManager &); + void SetExtendedTouchBounds(const zeus::CVector3f& boundExt) { x304_extendedTouchBounds = boundExt; } }; } diff --git a/Runtime/World/CPhysicsActor.cpp b/Runtime/World/CPhysicsActor.cpp index 393630472..24eae79d9 100644 --- a/Runtime/World/CPhysicsActor.cpp +++ b/Runtime/World/CPhysicsActor.cpp @@ -39,7 +39,7 @@ zeus::CVector3f CPhysicsActor::GetAimPosition(const CStateManager&, float dt) co void CPhysicsActor::CollidedWith(const TUniqueId&, const CCollisionInfoList&, CStateManager&) {} -const CCollisionPrimitive& CPhysicsActor::GetCollisionPrimitive() const { return x1c0_collisionPrimitive; } +const CCollisionPrimitive* CPhysicsActor::GetCollisionPrimitive() const { return &x1c0_collisionPrimitive; } zeus::CTransform CPhysicsActor::GetPrimitiveTransform() const { @@ -70,7 +70,7 @@ void CPhysicsActor::SetBoundingBox(const zeus::CAABox& box) zeus::CAABox CPhysicsActor::GetMotionVolume(float dt) const { - zeus::CAABox aabox = GetCollisionPrimitive().CalculateAABox(GetPrimitiveTransform()); + zeus::CAABox aabox = GetCollisionPrimitive()->CalculateAABox(GetPrimitiveTransform()); zeus::CVector3f velocity = CalculateNewVelocityWR_UsingImpulses(); const zeus::CVector3f dv = (dt * velocity); @@ -144,6 +144,11 @@ void CPhysicsActor::SetInertiaTensorScalar(float tensor) xf4_inertiaTensorRecip = 1.0f / tensor; } +void CPhysicsActor::SetCoefficientOfRestitutionModifier(float mod) +{ + x244_restitutionCoefModifier = mod; +} + void CPhysicsActor::SetMass(float mass) { xe8_mass = mass; diff --git a/Runtime/World/CPhysicsActor.hpp b/Runtime/World/CPhysicsActor.hpp index 5dbc8c557..b5ced2205 100644 --- a/Runtime/World/CPhysicsActor.hpp +++ b/Runtime/World/CPhysicsActor.hpp @@ -114,7 +114,7 @@ public: void Render(const CStateManager& mgr) const; zeus::CVector3f GetOrbitPosition(const CStateManager&) const; zeus::CVector3f GetAimPosition(const CStateManager&, float val) const; - virtual const CCollisionPrimitive& GetCollisionPrimitive() const; + virtual const CCollisionPrimitive* GetCollisionPrimitive() const; virtual zeus::CTransform GetPrimitiveTransform() const; virtual void CollidedWith(const TUniqueId&, const CCollisionInfoList&, CStateManager&); virtual float GetStepUpHeight() const; @@ -135,6 +135,7 @@ public: CMotionState GetMotionState() const; void SetMotionState(const CMotionState& mst); void SetInertiaTensorScalar(float tensor); + void SetCoefficientOfRestitutionModifier(float); void SetMass(float mass); void SetAngularVelocityOR(const zeus::CAxisAngle& angVel); zeus::CAxisAngle GetAngularVelocityOR() const; diff --git a/Runtime/World/CPlayer.cpp b/Runtime/World/CPlayer.cpp index e049a9055..26cc6b48a 100644 --- a/Runtime/World/CPlayer.cpp +++ b/Runtime/World/CPlayer.cpp @@ -288,7 +288,7 @@ void CPlayer::Teleport(const zeus::CTransform& xf, CStateManager& mgr, bool) {} zeus::CTransform CPlayer::CreateTransformFromMovementDirection() const { return {}; } -const CCollisionPrimitive& CPlayer::GetCollisionPrimitive() const { return CPhysicsActor::GetCollisionPrimitive(); } +const CCollisionPrimitive* CPlayer::GetCollisionPrimitive() const { return CPhysicsActor::GetCollisionPrimitive(); } zeus::CTransform CPlayer::GetPrimitiveTransform() const { return {}; } diff --git a/Runtime/World/CPlayer.hpp b/Runtime/World/CPlayer.hpp index 34efb63c8..2bb93cd94 100644 --- a/Runtime/World/CPlayer.hpp +++ b/Runtime/World/CPlayer.hpp @@ -396,7 +396,7 @@ public: float GetStepDownHeight() const; void Teleport(const zeus::CTransform& xf, CStateManager& mgr, bool); zeus::CTransform CreateTransformFromMovementDirection() const; - const CCollisionPrimitive& GetCollisionPrimitive() const; + const CCollisionPrimitive* GetCollisionPrimitive() const; zeus::CTransform GetPrimitiveTransform() const; bool CollidedWith(TUniqueId, const CCollisionInfoList&, CStateManager& mgr); float GetActualFirstPersonMaxVelocity() const;