chore: Physics Component abstraction and addition of tests (#1159)

* Make serialize actually virtual

yep

* Abstract to PhysicsComponent

Move shared functionality of all physics related classes to a base class.

Tested that there were no failed to unserialize errors when in main gameplay in Gnarled Forest or in a race.

Tested that 2 players were able to see each other in the above scenarios just fine as well.

* Update PhantomPhysicsComponent.cpp

* Add SimplePhysicsTest

* Add construction test

* Update SimplePhysicsComponentTests.cpp

* remove flags and fix override

* Update VendorComponent.h
This commit is contained in:
David Markowitz 2023-10-09 13:19:38 -07:00 committed by GitHub
parent d8ac148cee
commit ad003634f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 242 additions and 279 deletions

View File

@ -18,6 +18,7 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp"
"MovingPlatformComponent.cpp" "MovingPlatformComponent.cpp"
"PetComponent.cpp" "PetComponent.cpp"
"PhantomPhysicsComponent.cpp" "PhantomPhysicsComponent.cpp"
"PhysicsComponent.cpp"
"PlayerForcedMovementComponent.cpp" "PlayerForcedMovementComponent.cpp"
"PossessableComponent.cpp" "PossessableComponent.cpp"
"PossessorComponent.cpp" "PossessorComponent.cpp"

View File

@ -15,15 +15,12 @@
#include "LevelProgressionComponent.h" #include "LevelProgressionComponent.h"
#include "eStateChangeType.h" #include "eStateChangeType.h"
ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Component(entity) { ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : PhysicsComponent(entity) {
m_Position = {};
m_Rotation = NiQuaternion::IDENTITY;
m_Velocity = {}; m_Velocity = {};
m_AngularVelocity = {}; m_AngularVelocity = {};
m_InJetpackMode = false; m_InJetpackMode = false;
m_IsOnGround = true; m_IsOnGround = true;
m_IsOnRail = false; m_IsOnRail = false;
m_DirtyPosition = true;
m_DirtyVelocity = true; m_DirtyVelocity = true;
m_DirtyAngularVelocity = true; m_DirtyAngularVelocity = true;
m_dpEntity = nullptr; m_dpEntity = nullptr;
@ -202,26 +199,14 @@ void ControllablePhysicsComponent::UpdateXml(tinyxml2::XMLDocument* doc) {
} }
void ControllablePhysicsComponent::SetPosition(const NiPoint3& pos) { void ControllablePhysicsComponent::SetPosition(const NiPoint3& pos) {
if (m_Static) { if (m_Static) return;
return; PhysicsComponent::SetPosition(pos);
}
m_Position.x = pos.x;
m_Position.y = pos.y;
m_Position.z = pos.z;
m_DirtyPosition = true;
if (m_dpEntity) m_dpEntity->SetPosition(pos); if (m_dpEntity) m_dpEntity->SetPosition(pos);
} }
void ControllablePhysicsComponent::SetRotation(const NiQuaternion& rot) { void ControllablePhysicsComponent::SetRotation(const NiQuaternion& rot) {
if (m_Static) { if (m_Static) return;
return; PhysicsComponent::SetRotation(rot);
}
m_Rotation = rot;
m_DirtyPosition = true;
if (m_dpEntity) m_dpEntity->SetRotation(rot); if (m_dpEntity) m_dpEntity->SetRotation(rot);
} }

View File

@ -6,7 +6,7 @@
#include "NiPoint3.h" #include "NiPoint3.h"
#include "NiQuaternion.h" #include "NiQuaternion.h"
#include "tinyxml2.h" #include "tinyxml2.h"
#include "Component.h" #include "PhysicsComponent.h"
#include "dpCollisionChecks.h" #include "dpCollisionChecks.h"
#include "PhantomPhysicsComponent.h" #include "PhantomPhysicsComponent.h"
#include "eBubbleType.h" #include "eBubbleType.h"
@ -19,7 +19,7 @@ enum class eStateChangeType : uint32_t;
/** /**
* Handles the movement of controllable Entities, e.g. enemies and players * Handles the movement of controllable Entities, e.g. enemies and players
*/ */
class ControllablePhysicsComponent : public Component { class ControllablePhysicsComponent : public PhysicsComponent {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::CONTROLLABLE_PHYSICS; static const eReplicaComponentType ComponentType = eReplicaComponentType::CONTROLLABLE_PHYSICS;
@ -36,26 +36,14 @@ public:
* If the entity is static, this is a no-op. * If the entity is static, this is a no-op.
* @param pos The position to set * @param pos The position to set
*/ */
void SetPosition(const NiPoint3& pos); void SetPosition(const NiPoint3& pos) override;
/**
* Returns the current position of the entity
* @return The current position of the entity
*/
const NiPoint3& GetPosition() const { return m_Position; }
/** /**
* Sets the rotation of this entity, ensures this change is serialized next tick. If the entity is static, this is * Sets the rotation of this entity, ensures this change is serialized next tick. If the entity is static, this is
* a no-op. * a no-op.
* @param rot the rotation to set * @param rot the rotation to set
*/ */
void SetRotation(const NiQuaternion& rot); void SetRotation(const NiQuaternion& rot) override;
/**
* Returns the current rotation of this entity
* @return the current rotation of this entity
*/
const NiQuaternion& GetRotation() const { return m_Rotation; }
/** /**
* Sets the current velocity of this entity, ensures that this change is serialized next tick. If the entity is * Sets the current velocity of this entity, ensures that this change is serialized next tick. If the entity is
@ -322,21 +310,6 @@ private:
*/ */
dpEntity* m_dpEntity; dpEntity* m_dpEntity;
/**
* Whether or not the position is dirty, forcing a serialization update of the position
*/
bool m_DirtyPosition;
/**
* The current position of the entity
*/
NiPoint3 m_Position;
/**
* The current rotation of the entity
*/
NiQuaternion m_Rotation;
/** /**
* Whether or not the velocity is dirty, forcing a serialization of the velocity * Whether or not the velocity is dirty, forcing a serialization of the velocity
*/ */

View File

@ -27,14 +27,13 @@
#include "dpShapeBox.h" #include "dpShapeBox.h"
#include "dpShapeSphere.h" #include "dpShapeSphere.h"
PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : Component(parent) { PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : PhysicsComponent(parent) {
m_Position = m_Parent->GetDefaultPosition(); m_Position = m_Parent->GetDefaultPosition();
m_Rotation = m_Parent->GetDefaultRotation(); m_Rotation = m_Parent->GetDefaultRotation();
m_Scale = m_Parent->GetDefaultScale(); m_Scale = m_Parent->GetDefaultScale();
m_dpEntity = nullptr; m_dpEntity = nullptr;
m_EffectInfoDirty = false; m_EffectInfoDirty = false;
m_PositionInfoDirty = false;
m_IsPhysicsEffectActive = false; m_IsPhysicsEffectActive = false;
m_EffectType = ePhysicsEffectType::PUSH; m_EffectType = ePhysicsEffectType::PUSH;
@ -307,18 +306,7 @@ void PhantomPhysicsComponent::CreatePhysics() {
} }
void PhantomPhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { void PhantomPhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
outBitStream->Write(m_PositionInfoDirty || bIsInitialUpdate); PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
if (m_PositionInfoDirty || bIsInitialUpdate) {
outBitStream->Write(m_Position.x);
outBitStream->Write(m_Position.y);
outBitStream->Write(m_Position.z);
outBitStream->Write(m_Rotation.x);
outBitStream->Write(m_Rotation.y);
outBitStream->Write(m_Rotation.z);
outBitStream->Write(m_Rotation.w);
m_PositionInfoDirty = false;
}
outBitStream->Write(m_EffectInfoDirty || bIsInitialUpdate); outBitStream->Write(m_EffectInfoDirty || bIsInitialUpdate);
if (m_EffectInfoDirty || bIsInitialUpdate) { if (m_EffectInfoDirty || bIsInitialUpdate) {
@ -426,13 +414,11 @@ void PhantomPhysicsComponent::SetMax(uint32_t max) {
} }
void PhantomPhysicsComponent::SetPosition(const NiPoint3& pos) { void PhantomPhysicsComponent::SetPosition(const NiPoint3& pos) {
m_Position = pos; PhysicsComponent::SetPosition(pos);
if (m_dpEntity) m_dpEntity->SetPosition(pos); if (m_dpEntity) m_dpEntity->SetPosition(pos);
} }
void PhantomPhysicsComponent::SetRotation(const NiQuaternion& rot) { void PhantomPhysicsComponent::SetRotation(const NiQuaternion& rot) {
m_Rotation = rot; PhysicsComponent::SetRotation(rot);
if (m_dpEntity) m_dpEntity->SetRotation(rot); if (m_dpEntity) m_dpEntity->SetRotation(rot);
} }

View File

@ -11,8 +11,8 @@
#include <vector> #include <vector>
#include "CppScripts.h" #include "CppScripts.h"
#include "InvalidScript.h" #include "InvalidScript.h"
#include "Component.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
#include "PhysicsComponent.h"
class LDFBaseData; class LDFBaseData;
class Entity; class Entity;
@ -25,7 +25,7 @@ enum class ePhysicsEffectType : uint32_t ;
* trigger gameplay events, for example the bus in Avant Gardens that moves around when the player touches its physics * trigger gameplay events, for example the bus in Avant Gardens that moves around when the player touches its physics
* body. Optionally this object can also have effects, like the fans in AG. * body. Optionally this object can also have effects, like the fans in AG.
*/ */
class PhantomPhysicsComponent : public Component { class PhantomPhysicsComponent : public PhysicsComponent {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::PHANTOM_PHYSICS; static const eReplicaComponentType ComponentType = eReplicaComponentType::PHANTOM_PHYSICS;
@ -75,29 +75,17 @@ public:
*/ */
void SetPhysicsEffectActive(bool val) { m_IsPhysicsEffectActive = val; m_EffectInfoDirty = true; } void SetPhysicsEffectActive(bool val) { m_IsPhysicsEffectActive = val; m_EffectInfoDirty = true; }
/**
* Returns the position of this physics object
* @return the position of this physics object
*/
const NiPoint3& GetPosition() const { return m_Position; }
/** /**
* Sets the position of this physics object * Sets the position of this physics object
* @param pos the position to set * @param pos the position to set
*/ */
void SetPosition(const NiPoint3& pos); void SetPosition(const NiPoint3& pos) override;
/**
* Returns the rotation of this physics object
* @return the rotation of this physics object
*/
const NiQuaternion& GetRotation() const { return m_Rotation; }
/** /**
* Sets the rotation of this physics object * Sets the rotation of this physics object
* @param rot the rotation to set * @param rot the rotation to set
*/ */
void SetRotation(const NiQuaternion& rot); void SetRotation(const NiQuaternion& rot) override;
/** /**
* Returns the effect that's currently active, defaults to 0 * Returns the effect that's currently active, defaults to 0
@ -134,27 +122,11 @@ public:
void SetMax(uint32_t max); void SetMax(uint32_t max);
private: private:
/**
* The position of the physics object
*/
NiPoint3 m_Position;
/**
* The rotation of the physics object
*/
NiQuaternion m_Rotation;
/** /**
* A scale to apply to the size of the physics object * A scale to apply to the size of the physics object
*/ */
float m_Scale; float m_Scale;
/**
* Whether or not the position has changed and needs to be serialized
*/
bool m_PositionInfoDirty;
/** /**
* Whether or not the effect has changed and needs to be serialized * Whether or not the effect has changed and needs to be serialized
*/ */

View File

@ -0,0 +1,21 @@
#include "PhysicsComponent.h"
PhysicsComponent::PhysicsComponent(Entity* parent) : Component(parent) {
m_Position = NiPoint3::ZERO;
m_Rotation = NiQuaternion::IDENTITY;
m_DirtyPosition = false;
}
void PhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
outBitStream->Write(bIsInitialUpdate || m_DirtyPosition);
if (bIsInitialUpdate || m_DirtyPosition) {
outBitStream->Write(m_Position.x);
outBitStream->Write(m_Position.y);
outBitStream->Write(m_Position.z);
outBitStream->Write(m_Rotation.x);
outBitStream->Write(m_Rotation.y);
outBitStream->Write(m_Rotation.z);
outBitStream->Write(m_Rotation.w);
if (!bIsInitialUpdate) m_DirtyPosition = false;
}
}

View File

@ -0,0 +1,32 @@
#ifndef __PHYSICSCOMPONENT__H__
#define __PHYSICSCOMPONENT__H__
#include "Component.h"
#include "NiPoint3.h"
#include "NiQuaternion.h"
namespace Raknet {
class BitStream;
};
class PhysicsComponent : public Component {
public:
PhysicsComponent(Entity* parent);
virtual ~PhysicsComponent() = default;
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
const NiPoint3& GetPosition() const { return m_Position; }
virtual void SetPosition(const NiPoint3& pos) { if (m_Position == pos) return; m_Position = pos; m_DirtyPosition = true; }
const NiQuaternion& GetRotation() const { return m_Rotation; }
virtual void SetRotation(const NiQuaternion& rot) { if (m_Rotation == rot) return; m_Rotation = rot; m_DirtyPosition = true; }
protected:
NiPoint3 m_Position;
NiQuaternion m_Rotation;
bool m_DirtyPosition;
};
#endif //!__PHYSICSCOMPONENT__H__

View File

@ -1,32 +1,16 @@
/* /*
* Darkflame Universe * Darkflame Universe
* Copyright 2019 * Copyright 2023
*/ */
#include "RigidbodyPhantomPhysicsComponent.h" #include "RigidbodyPhantomPhysicsComponent.h"
#include "Entity.h" #include "Entity.h"
RigidbodyPhantomPhysicsComponent::RigidbodyPhantomPhysicsComponent(Entity* parent) : Component(parent) { RigidbodyPhantomPhysicsComponent::RigidbodyPhantomPhysicsComponent(Entity* parent) : PhysicsComponent(parent) {
m_Position = m_Parent->GetDefaultPosition(); m_Position = m_Parent->GetDefaultPosition();
m_Rotation = m_Parent->GetDefaultRotation(); m_Rotation = m_Parent->GetDefaultRotation();
m_IsDirty = true;
}
RigidbodyPhantomPhysicsComponent::~RigidbodyPhantomPhysicsComponent() {
} }
void RigidbodyPhantomPhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) { void RigidbodyPhantomPhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
outBitStream->Write(m_IsDirty || bIsInitialUpdate); PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
if (m_IsDirty || bIsInitialUpdate) {
outBitStream->Write(m_Position.x);
outBitStream->Write(m_Position.y);
outBitStream->Write(m_Position.z);
outBitStream->Write(m_Rotation.x);
outBitStream->Write(m_Rotation.y);
outBitStream->Write(m_Rotation.z);
outBitStream->Write(m_Rotation.w);
m_IsDirty = false;
}
} }

View File

@ -1,71 +1,29 @@
/* /*
* Darkflame Universe * Darkflame Universe
* Copyright 2019 * Copyright 2023
*/ */
#ifndef RIGIDBODYPHANTOMPHYSICS_H #ifndef __RIGIDBODYPHANTOMPHYSICS_H__
#define RIGIDBODYPHANTOMPHYSICS_H #define __RIGIDBODYPHANTOMPHYSICS_H__
#include "BitStream.h" #include "BitStream.h"
#include "dCommonVars.h" #include "dCommonVars.h"
#include "NiPoint3.h" #include "NiPoint3.h"
#include "NiQuaternion.h" #include "NiQuaternion.h"
#include "Component.h" #include "PhysicsComponent.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
/** /**
* Component that handles rigid bodies that can be interacted with, mostly client-side rendered. An example is the * Component that handles rigid bodies that can be interacted with, mostly client-side rendered. An example is the
* bananas that fall from trees in GF. * bananas that fall from trees in GF.
*/ */
class RigidbodyPhantomPhysicsComponent : public Component { class RigidbodyPhantomPhysicsComponent : public PhysicsComponent {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS; static const eReplicaComponentType ComponentType = eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS;
RigidbodyPhantomPhysicsComponent(Entity* parent); RigidbodyPhantomPhysicsComponent(Entity* parent);
~RigidbodyPhantomPhysicsComponent() override;
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
/**
* Returns the position of this entity
* @return the position of this entity
*/
NiPoint3& GetPosition() { return m_Position; }
/**
* Sets the position of this entity
* @param pos the position to set
*/
void SetPosition(const NiPoint3& pos) { m_Position = pos; m_IsDirty = true; }
/**
* Returns the rotation of this entity
* @return the rotation of this entity
*/
NiQuaternion& GetRotation() { return m_Rotation; }
/**
* Sets the rotation for this entity
* @param rot the rotation to tset
*/
void SetRotation(const NiQuaternion& rot) { m_Rotation = rot; m_IsDirty = true; }
private:
/**
* The position of this entity
*/
NiPoint3 m_Position;
/**
* The rotation of this entity
*/
NiQuaternion m_Rotation;
/**
* Whether or not the component should be serialized
*/
bool m_IsDirty;
}; };
#endif // RIGIDBODYPHANTOMPHYSICS_H #endif // __RIGIDBODYPHANTOMPHYSICS_H__

View File

@ -13,10 +13,9 @@
#include "Entity.h" #include "Entity.h"
SimplePhysicsComponent::SimplePhysicsComponent(uint32_t componentID, Entity* parent) : Component(parent) { SimplePhysicsComponent::SimplePhysicsComponent(uint32_t componentID, Entity* parent) : PhysicsComponent(parent) {
m_Position = m_Parent->GetDefaultPosition(); m_Position = m_Parent->GetDefaultPosition();
m_Rotation = m_Parent->GetDefaultRotation(); m_Rotation = m_Parent->GetDefaultRotation();
m_IsDirty = true;
const auto& climbable_type = m_Parent->GetVar<std::u16string>(u"climbable"); const auto& climbable_type = m_Parent->GetVar<std::u16string>(u"climbable");
if (climbable_type == u"wall") { if (climbable_type == u"wall") {
@ -54,19 +53,7 @@ void SimplePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIs
} else { } else {
outBitStream->Write0(); outBitStream->Write0();
} }
PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
outBitStream->Write(m_IsDirty || bIsInitialUpdate);
if (m_IsDirty || bIsInitialUpdate) {
outBitStream->Write(m_Position.x);
outBitStream->Write(m_Position.y);
outBitStream->Write(m_Position.z);
outBitStream->Write(m_Rotation.x);
outBitStream->Write(m_Rotation.y);
outBitStream->Write(m_Rotation.z);
outBitStream->Write(m_Rotation.w);
m_IsDirty = false;
}
} }
uint32_t SimplePhysicsComponent::GetPhysicsMotionState() const { uint32_t SimplePhysicsComponent::GetPhysicsMotionState() const {

View File

@ -10,7 +10,7 @@
#include "RakNetTypes.h" #include "RakNetTypes.h"
#include "NiPoint3.h" #include "NiPoint3.h"
#include "NiQuaternion.h" #include "NiQuaternion.h"
#include "Component.h" #include "PhysicsComponent.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
class Entity; class Entity;
@ -26,7 +26,7 @@ enum class eClimbableType : int32_t {
/** /**
* Component that serializes locations of entities to the client * Component that serializes locations of entities to the client
*/ */
class SimplePhysicsComponent : public Component { class SimplePhysicsComponent : public PhysicsComponent {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::SIMPLE_PHYSICS; static const eReplicaComponentType ComponentType = eReplicaComponentType::SIMPLE_PHYSICS;
@ -35,30 +35,6 @@ public:
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
/**
* Returns the position of this entity
* @return the position of this entity
*/
NiPoint3& GetPosition() { return m_Position; }
/**
* Sets the position of this entity
* @param pos the position to set
*/
void SetPosition(const NiPoint3& pos) { m_Position = pos; m_IsDirty = true; }
/**
* Returns the rotation of this entity
* @return the rotation of this entity
*/
NiQuaternion& GetRotation() { return m_Rotation; }
/**
* Sets the rotation of this entity
* @param rot
*/
void SetRotation(const NiQuaternion& rot) { m_Rotation = rot; m_IsDirty = true; }
/** /**
* Returns the velocity of this entity * Returns the velocity of this entity
* @return the velocity of this entity * @return the velocity of this entity
@ -108,17 +84,6 @@ public:
void SetClimbableType(const eClimbableType& value) { m_ClimbableType = value; } void SetClimbableType(const eClimbableType& value) { m_ClimbableType = value; }
private: private:
/**
* The current position of the entity
*/
NiPoint3 m_Position = NiPoint3::ZERO;
/**
* The current rotation of the entity
*/
NiQuaternion m_Rotation = NiQuaternion::IDENTITY;
/** /**
* The current velocity of the entity * The current velocity of the entity
*/ */
@ -134,11 +99,6 @@ private:
*/ */
bool m_DirtyVelocity = true; bool m_DirtyVelocity = true;
/**
* Whether or not the position has changed
*/
bool m_IsDirty = true;
/** /**
* The current physics motion state * The current physics motion state
*/ */

View File

@ -1,9 +1,7 @@
#include "VehiclePhysicsComponent.h" #include "VehiclePhysicsComponent.h"
#include "EntityManager.h" #include "EntityManager.h"
VehiclePhysicsComponent::VehiclePhysicsComponent(Entity* parent) : Component(parent) { VehiclePhysicsComponent::VehiclePhysicsComponent(Entity* parent) : PhysicsComponent(parent) {
m_Position = NiPoint3::ZERO;
m_Rotation = NiQuaternion::IDENTITY;
m_Velocity = NiPoint3::ZERO; m_Velocity = NiPoint3::ZERO;
m_AngularVelocity = NiPoint3::ZERO; m_AngularVelocity = NiPoint3::ZERO;
m_IsOnGround = true; m_IsOnGround = true;
@ -14,22 +12,6 @@ VehiclePhysicsComponent::VehiclePhysicsComponent(Entity* parent) : Component(par
m_EndBehavior = GeneralUtils::GenerateRandomNumber<uint32_t>(0, 7); m_EndBehavior = GeneralUtils::GenerateRandomNumber<uint32_t>(0, 7);
} }
VehiclePhysicsComponent::~VehiclePhysicsComponent() {
}
void VehiclePhysicsComponent::SetPosition(const NiPoint3& pos) {
if (pos == m_Position) return;
m_DirtyPosition = true;
m_Position = pos;
}
void VehiclePhysicsComponent::SetRotation(const NiQuaternion& rot) {
if (rot == m_Rotation) return;
m_DirtyPosition = true;
m_Rotation = rot;
}
void VehiclePhysicsComponent::SetVelocity(const NiPoint3& vel) { void VehiclePhysicsComponent::SetVelocity(const NiPoint3& vel) {
if (vel == m_Velocity) return; if (vel == m_Velocity) return;
m_DirtyPosition = true; m_DirtyPosition = true;
@ -60,10 +42,6 @@ void VehiclePhysicsComponent::SetRemoteInputInfo(const RemoteInputInfo& remoteIn
m_DirtyRemoteInput = true; m_DirtyRemoteInput = true;
} }
void VehiclePhysicsComponent::SetDirtyPosition(bool val) {
m_DirtyPosition = val;
}
void VehiclePhysicsComponent::SetDirtyVelocity(bool val) { void VehiclePhysicsComponent::SetDirtyVelocity(bool val) {
m_DirtyVelocity = val; m_DirtyVelocity = val;
} }

View File

@ -2,7 +2,7 @@
#include "BitStream.h" #include "BitStream.h"
#include "Entity.h" #include "Entity.h"
#include "Component.h" #include "PhysicsComponent.h"
#include "eReplicaComponentType.h" #include "eReplicaComponentType.h"
struct RemoteInputInfo { struct RemoteInputInfo {
@ -26,41 +26,16 @@ struct RemoteInputInfo {
/** /**
* Physics component for vehicles. * Physics component for vehicles.
*/ */
class VehiclePhysicsComponent : public Component { class VehiclePhysicsComponent : public PhysicsComponent {
public: public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::VEHICLE_PHYSICS; static const eReplicaComponentType ComponentType = eReplicaComponentType::VEHICLE_PHYSICS;
VehiclePhysicsComponent(Entity* parentEntity); VehiclePhysicsComponent(Entity* parentEntity);
~VehiclePhysicsComponent() override;
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override; void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
void Update(float deltaTime) override; void Update(float deltaTime) override;
/**
* Sets the position
* @param pos the new position
*/
void SetPosition(const NiPoint3& pos);
/**
* Gets the position
* @return the position
*/
const NiPoint3& GetPosition() const { return m_Position; }
/**
* Sets the rotation
* @param rot the new rotation
*/
void SetRotation(const NiQuaternion& rot);
/**
* Gets the rotation
* @return the rotation
*/
const NiQuaternion& GetRotation() const { return m_Rotation; }
/** /**
* Sets the velocity * Sets the velocity
* @param vel the new velocity * @param vel the new velocity
@ -115,10 +90,6 @@ public:
void SetRemoteInputInfo(const RemoteInputInfo&); void SetRemoteInputInfo(const RemoteInputInfo&);
private: private:
bool m_DirtyPosition;
NiPoint3 m_Position;
NiQuaternion m_Rotation;
bool m_DirtyVelocity; bool m_DirtyVelocity;
NiPoint3 m_Velocity; NiPoint3 m_Velocity;

View File

@ -1,5 +1,6 @@
set(DCOMPONENTS_TESTS set(DCOMPONENTS_TESTS
"DestroyableComponentTests.cpp" "DestroyableComponentTests.cpp"
"SimplePhysicsComponentTests.cpp"
) )
# Get the folder name and prepend it to the files above # Get the folder name and prepend it to the files above

View File

@ -0,0 +1,154 @@
#include "GameDependencies.h"
#include <gtest/gtest.h>
#include "BitStream.h"
#include "SimplePhysicsComponent.h"
#include "Entity.h"
#include "eReplicaComponentType.h"
#include "eStateChangeType.h"
class SimplePhysicsTest : public GameDependenciesTest {
protected:
std::unique_ptr<Entity> baseEntity;
SimplePhysicsComponent* simplePhysicsComponent;
CBITSTREAM;
void SetUp() override {
SetUpDependencies();
baseEntity = std::make_unique<Entity>(15, GameDependenciesTest::info);
simplePhysicsComponent = new SimplePhysicsComponent(1, baseEntity.get());
baseEntity->AddComponent(SimplePhysicsComponent::ComponentType, simplePhysicsComponent);
simplePhysicsComponent->SetClimbableType(eClimbableType::CLIMBABLE_TYPE_WALL);
simplePhysicsComponent->SetPosition(NiPoint3(1.0f, 2.0f, 3.0f));
simplePhysicsComponent->SetRotation(NiQuaternion(1.0f, 2.0f, 3.0f, 4.0f));
simplePhysicsComponent->SetVelocity(NiPoint3(5.0f, 6.0f, 7.0f));
simplePhysicsComponent->SetAngularVelocity(NiPoint3(5.0f, 6.0f, 7.0f));
simplePhysicsComponent->SetPhysicsMotionState(2);
}
void TearDown() override {
TearDownDependencies();
}
};
TEST_F(SimplePhysicsTest, SimplePhysicsSerializeTest) {
simplePhysicsComponent->Serialize(&bitStream, false);
constexpr uint32_t sizeOfStream = 3 + BYTES_TO_BITS(3 * sizeof(NiPoint3)) + BYTES_TO_BITS(1 * sizeof(NiQuaternion)) + 1 * BYTES_TO_BITS(sizeof(uint32_t));
ASSERT_EQ(bitStream.GetNumberOfBitsUsed(), sizeOfStream);
bool dirtyVelocityFlag;
bitStream.Read(dirtyVelocityFlag);
ASSERT_EQ(dirtyVelocityFlag, true);
NiPoint3 velocity;
bitStream.Read(velocity.x);
bitStream.Read(velocity.y);
bitStream.Read(velocity.z);
ASSERT_EQ(velocity, NiPoint3(5.0f, 6.0f, 7.0f));
NiPoint3 angularVelocity;
bitStream.Read(angularVelocity.x);
bitStream.Read(angularVelocity.y);
bitStream.Read(angularVelocity.z);
ASSERT_EQ(angularVelocity, NiPoint3(5.0f, 6.0f, 7.0f));
bool dirtyPhysicsMotionStateFlag;
bitStream.Read(dirtyPhysicsMotionStateFlag);
ASSERT_EQ(dirtyPhysicsMotionStateFlag, true);
uint32_t physicsMotionState;
bitStream.Read(physicsMotionState);
ASSERT_EQ(physicsMotionState, 2.0f);
bool dirtyPositionFlag;
bitStream.Read(dirtyPositionFlag);
ASSERT_EQ(dirtyPositionFlag, true);
NiPoint3 position;
bitStream.Read(position.x);
bitStream.Read(position.y);
bitStream.Read(position.z);
ASSERT_EQ(position, NiPoint3(1.0f, 2.0f, 3.0f));
NiQuaternion rotation;
bitStream.Read(rotation.x);
bitStream.Read(rotation.y);
bitStream.Read(rotation.z);
bitStream.Read(rotation.w);
ASSERT_EQ(rotation, NiQuaternion(1.0f, 2.0f, 3.0f, 4.0f));
}
TEST_F(SimplePhysicsTest, SimplePhysicsConstructionTest) {
simplePhysicsComponent->Serialize(&bitStream, true);
constexpr uint32_t sizeOfStream = 4 + BYTES_TO_BITS(1 * sizeof(int32_t)) + BYTES_TO_BITS(3 * sizeof(NiPoint3)) + BYTES_TO_BITS(1 * sizeof(NiQuaternion)) + 1 * BYTES_TO_BITS(sizeof(uint32_t));
ASSERT_EQ(bitStream.GetNumberOfBitsUsed(), sizeOfStream);
bool dirtyClimbableTypeFlag;
bitStream.Read(dirtyClimbableTypeFlag);
ASSERT_EQ(dirtyClimbableTypeFlag, true);
int32_t climbableType;
bitStream.Read(climbableType);
ASSERT_EQ(climbableType, 2);
bool dirtyVelocityFlag;
bitStream.Read(dirtyVelocityFlag);
ASSERT_EQ(dirtyVelocityFlag, true);
NiPoint3 velocity;
bitStream.Read(velocity.x);
bitStream.Read(velocity.y);
bitStream.Read(velocity.z);
ASSERT_EQ(velocity, NiPoint3(5.0f, 6.0f, 7.0f));
NiPoint3 angularVelocity;
bitStream.Read(angularVelocity.x);
bitStream.Read(angularVelocity.y);
bitStream.Read(angularVelocity.z);
ASSERT_EQ(angularVelocity, NiPoint3(5.0f, 6.0f, 7.0f));
bool dirtyPhysicsMotionStateFlag;
bitStream.Read(dirtyPhysicsMotionStateFlag);
ASSERT_EQ(dirtyPhysicsMotionStateFlag, true);
uint32_t physicsMotionState;
bitStream.Read(physicsMotionState);
ASSERT_EQ(physicsMotionState, 2.0f);
bool dirtyPositionFlag;
bitStream.Read(dirtyPositionFlag);
ASSERT_EQ(dirtyPositionFlag, true);
NiPoint3 position;
bitStream.Read(position.x);
bitStream.Read(position.y);
bitStream.Read(position.z);
ASSERT_EQ(position, NiPoint3(1.0f, 2.0f, 3.0f));
NiQuaternion rotation;
bitStream.Read(rotation.x);
bitStream.Read(rotation.y);
bitStream.Read(rotation.z);
bitStream.Read(rotation.w);
ASSERT_EQ(rotation, NiQuaternion(1.0f, 2.0f, 3.0f, 4.0f));
}
TEST_F(SimplePhysicsTest, SimplePhysicsGettersAndSettersTest) {
ASSERT_EQ(simplePhysicsComponent->GetClimabbleType(), eClimbableType::CLIMBABLE_TYPE_WALL);
ASSERT_EQ(simplePhysicsComponent->GetPosition(), NiPoint3(1.0f, 2.0f, 3.0f));
ASSERT_EQ(simplePhysicsComponent->GetRotation(), NiQuaternion(1.0f, 2.0f, 3.0f, 4.0f));
ASSERT_EQ(simplePhysicsComponent->GetVelocity(), NiPoint3(5.0f, 6.0f, 7.0f));
ASSERT_EQ(simplePhysicsComponent->GetAngularVelocity(), NiPoint3(5.0f, 6.0f, 7.0f));
ASSERT_EQ(simplePhysicsComponent->GetPhysicsMotionState(), 2);
simplePhysicsComponent->SetClimbableType(eClimbableType::CLIMBABLE_TYPE_LADDER);
simplePhysicsComponent->SetPosition(NiPoint3(4.0f, 5.0f, 6.0f));
simplePhysicsComponent->SetRotation(NiQuaternion(4.0f, 5.0f, 6.0f, 7.0f));
simplePhysicsComponent->SetVelocity(NiPoint3(6.0f, 7.0f, 8.0f));
simplePhysicsComponent->SetAngularVelocity(NiPoint3(6.0f, 7.0f, 8.0f));
simplePhysicsComponent->SetPhysicsMotionState(3);
ASSERT_EQ(simplePhysicsComponent->GetClimabbleType(), eClimbableType::CLIMBABLE_TYPE_LADDER);
ASSERT_EQ(simplePhysicsComponent->GetPosition(), NiPoint3(4.0f, 5.0f, 6.0f));
ASSERT_EQ(simplePhysicsComponent->GetRotation(), NiQuaternion(4.0f, 5.0f, 6.0f, 7.0f));
ASSERT_EQ(simplePhysicsComponent->GetVelocity(), NiPoint3(6.0f, 7.0f, 8.0f));
ASSERT_EQ(simplePhysicsComponent->GetAngularVelocity(), NiPoint3(6.0f, 7.0f, 8.0f));
ASSERT_EQ(simplePhysicsComponent->GetPhysicsMotionState(), 3);
}