From 1d0747076fc9ee743d7e0bfa7fc352b824133b98 Mon Sep 17 00:00:00 2001 From: ViktorLjung Date: Sun, 6 Apr 2014 03:39:50 +0200 Subject: [PATCH] Physics!!!!!1111oneoneonetwo --- src/Components/BoxShape.h | 4 +- src/Components/Physics.h | 7 +- src/Components/SphereShape.h | 3 +- src/GameWorld.cpp | 119 +++++++++++++- src/GameWorld.h | 5 + src/Systems/DebugSystem.cpp | 4 + src/Systems/DebugSystem.h | 21 +++ src/Systems/PhysicsSystem.cpp | 155 ++++++++++++++++++ src/Systems/PhysicsSystem.h | 49 ++++++ src/main.cpp | 2 +- vs12/Returngeance/Returngeance.vcxproj | 9 +- .../Returngeance/Returngeance.vcxproj.filters | 13 +- 12 files changed, 373 insertions(+), 18 deletions(-) create mode 100644 src/Systems/DebugSystem.cpp create mode 100644 src/Systems/DebugSystem.h create mode 100644 src/Systems/PhysicsSystem.cpp create mode 100644 src/Systems/PhysicsSystem.h diff --git a/src/Components/BoxShape.h b/src/Components/BoxShape.h index 7c301c5..6ba78be 100644 --- a/src/Components/BoxShape.h +++ b/src/Components/BoxShape.h @@ -8,7 +8,9 @@ namespace Components struct BoxShape : Component { - float height, width; + float Height; + float Width; + float Depth; }; } diff --git a/src/Components/Physics.h b/src/Components/Physics.h index 10602c8..9cfe04d 100644 --- a/src/Components/Physics.h +++ b/src/Components/Physics.h @@ -1,7 +1,6 @@ #ifndef Components_Physics_h__ #define Components_Physics_h__ -//#include "btBulletDynamicsCommon.h" #include "Component.h" namespace Components @@ -9,9 +8,9 @@ namespace Components struct Physics : Component { - float Mass; - float Inertia[3]; - //btRigidBody RigidBody; + float Mass = 0; + float Friction = 0; + glm::vec3 Gravity = glm::vec3(0, -9.82f, 0); }; } diff --git a/src/Components/SphereShape.h b/src/Components/SphereShape.h index 67edf01..85e3cb1 100644 --- a/src/Components/SphereShape.h +++ b/src/Components/SphereShape.h @@ -8,7 +8,8 @@ namespace Components struct SphereShape : Component { - float radius; + float Radius; + float RollingFriction; }; } diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 3b26464..79b810e 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -10,24 +10,115 @@ void GameWorld::Initialize() auto camera = CreateEntity(); transform = AddComponent(camera, "Transform"); - transform->Position.y = 10.f; + transform->Position.z = 150.f; + transform->Position.y = 100.f; + transform->Orientation = glm::quat(glm::vec3(glm::pi() / 8.f, 0.f, 0.f)); auto cameraComp = AddComponent(camera, "Camera"); cameraComp->FarClip = 2000.f; AddComponent(camera, "Input"); auto freeSteering = AddComponent(camera, "FreeSteering"); + auto terrain = CreateEntity(); transform = AddComponent(terrain, "Transform"); - transform->Scale = glm::vec3(.05f); - model = AddComponent(terrain, "Model"); - model->ModelFile = "Models/terrain/terrain.obj"; + transform->Scale = glm::vec3(1000.0f); + transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, glm::pi()/20.f)); + model = AddComponent(terrain, "Model"); + model->ModelFile = "Models/PhysicsTest/Plane.obj"; + auto physics = AddComponent(terrain, "Physics"); + auto Box = AddComponent(terrain, "BoxShape"); + Box->Width = 1; + Box->Height = 0; + Box->Depth = 1; + physics->Friction = 0.5f; - auto tank = CreateEntity(); + terrain = CreateEntity(); + transform = AddComponent(terrain, "Transform"); + transform->Scale = glm::vec3(1000.0f); + transform->Position = glm::vec3(-500, 0, 0); + transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, -glm::pi() / 20.f)); + model = AddComponent(terrain, "Model"); + model->ModelFile = "Models/PhysicsTest/Plane.obj"; + physics = AddComponent(terrain, "Physics"); + Box = AddComponent(terrain, "BoxShape"); + Box->Width = 1; + Box->Height = 0; + Box->Depth = 1; + physics->Friction = 0.5f; + + + + auto Boxed = CreateEntity(); + transform = AddComponent(Boxed, "Transform"); + transform->Position.y = 100.f; + transform->Position.x = 4.f; + transform->Scale = glm::vec3(5.0f); + model = AddComponent(Boxed, "Model"); + model->ModelFile = "Models/PhysicsTest/Cube.obj"; + physics = AddComponent(Boxed, "Physics"); + physics->Mass = 10; + physics->Friction = 0.5f; + Box = AddComponent(Boxed, "BoxShape"); + Box->Width = 1; + Box->Height = 1; + Box->Depth = 1; + + for (int i = 0; i < 20; i++) + { + auto Sphered = CreateEntity(); + transform = AddComponent(Sphered, "Transform"); + transform->Position.y = 15.f; + transform->Position.x = 4.f; + transform->Scale = glm::vec3(1.0f); + model = AddComponent(Sphered, "Model"); + model->ModelFile = "Models/PhysicsTest/Sphere.obj"; + physics = AddComponent(Sphered, "Physics"); + physics->Mass = 100; + physics->Friction = 0.5f; + auto sphere = AddComponent(Sphered, "SphereShape"); + sphere->Radius = 1; + sphere->RollingFriction = 0.5f; + + + { + auto tank_top = CreateEntity(Sphered); + transform = AddComponent(tank_top, "Transform"); + transform->Scale = glm::vec3(1.0f/100.f); + model = AddComponent(tank_top, "Model"); + model->ModelFile = "Models/tank/tank_top.obj"; + { + auto tank_barrel = CreateEntity(tank_top); + transform = AddComponent(tank_barrel, "Transform"); + + model = AddComponent(tank_barrel, "Model"); + model->ModelFile = "Models/tank/tank_barrel.obj"; + } + } + } + + + /*auto tank = CreateEntity(); transform = AddComponent(tank, "Transform"); transform->Position.y = 10.f; + transform->Position.x = 4.f; transform->Scale = glm::vec3(.01f); model = AddComponent(tank, "Model"); model->ModelFile = "Models/tank/tank_base.obj"; + physics = AddComponent(tank, "Physics"); + physics->Mass = 100; + physics->Friction = 0.5f;*/ + + + /*auto sphere = AddComponent(tank, "SphereShape"); + sphere->Radius = 10.*(1.f / .01f); + sphere->RollingFriction = 0.5f;*/ +/* + Box = AddComponent(tank, "BoxShape"); + Box->Width = 100; + Box->Height = 50; + Box->Depth = 100;*/ + +/* { auto tank_top = CreateEntity(tank); transform = AddComponent(tank_top, "Transform"); @@ -41,7 +132,8 @@ void GameWorld::Initialize() model = AddComponent(tank_barrel, "Model"); model->ModelFile = "Models/tank/tank_barrel.obj"; } - } + }*/ + //auto light = CreateEntity(); //transform = AddComponent(light, "Transform"); @@ -72,6 +164,11 @@ void GameWorld::RegisterComponents() m_ComponentFactory.Register("Template", []() { return new Components::Template(); }); m_ComponentFactory.Register("Transform", []() { return new Components::Transform(); }); m_ComponentFactory.Register("FreeSteering", []() { return new Components::FreeSteering(); }); + + m_ComponentFactory.Register("SphereShape", []() { return new Components::SphereShape(); }); + m_ComponentFactory.Register("BoxShape", []() { return new Components::BoxShape(); }); + m_ComponentFactory.Register("Physics", []() { return new Components::Physics(); }); + } void GameWorld::RegisterSystems() @@ -84,7 +181,12 @@ void GameWorld::RegisterSystems() //m_SystemFactory.Register("PlayerSystem", [this]() { return new Systems::PlayerSystem(this); }); m_SystemFactory.Register("FreeSteeringSystem", [this]() { return new Systems::FreeSteeringSystem(this); }); //m_SystemFactory.Register("SoundSystem", [this]() { return new Systems::SoundSystem(this); }); + + m_SystemFactory.Register("PhysicsSystem", [this]() { return new Systems::PhysicsSystem(this); }); + m_SystemFactory.Register("RenderSystem", [this]() { return new Systems::RenderSystem(this, m_Renderer); }); + + } void GameWorld::AddSystems() @@ -97,5 +199,10 @@ void GameWorld::AddSystems() //AddSystem("PlayerSystem"); AddSystem("FreeSteeringSystem"); //AddSystem("SoundSystem"); + + AddSystem("PhysicsSystem"); + AddSystem("RenderSystem"); + + } \ No newline at end of file diff --git a/src/GameWorld.h b/src/GameWorld.h index 61d8c6c..0419cca 100755 --- a/src/GameWorld.h +++ b/src/GameWorld.h @@ -13,6 +13,7 @@ #include "Systems/FreeSteeringSystem.h" #include "Systems/RenderSystem.h" //#include "Systems/SoundSystem.h" +#include "Systems/PhysicsSystem.h" #include "Components/Bounds.h" #include "Components/Camera.h" @@ -29,6 +30,10 @@ #include "Components/Template.h" #include "Components/Transform.h" +#include "Components\BoxShape.h" +#include "Components\SphereShape.h" +#include "Components\Physics.h" + class GameWorld : public World { public: diff --git a/src/Systems/DebugSystem.cpp b/src/Systems/DebugSystem.cpp new file mode 100644 index 0000000..964aa9f --- /dev/null +++ b/src/Systems/DebugSystem.cpp @@ -0,0 +1,4 @@ +#include "PrecompiledHeader.h" +#include "DebugSystem.h" +#include "World.h" + diff --git a/src/Systems/DebugSystem.h b/src/Systems/DebugSystem.h new file mode 100644 index 0000000..8a8b2a3 --- /dev/null +++ b/src/Systems/DebugSystem.h @@ -0,0 +1,21 @@ +#ifndef DebugSystem_h__ +#define DebugSystem_h__ + +#include "System.h" +#include "Components/Transform.h" + +namespace Systems +{ + + class DebugSystem : public System + { + public: + DebugSystem(World* world) + : System(world) { } + + void Update(double dt) override; + //void UpdateEntity(double dt, EntityID entity, EntityID parent) override; + }; + +} +#endif // DebugSystem_h__ \ No newline at end of file diff --git a/src/Systems/PhysicsSystem.cpp b/src/Systems/PhysicsSystem.cpp new file mode 100644 index 0000000..f074ee6 --- /dev/null +++ b/src/Systems/PhysicsSystem.cpp @@ -0,0 +1,155 @@ +#include "PrecompiledHeader.h" +#include "PhysicsSystem.h" +#include "World.h" + + + +Systems::PhysicsSystem::PhysicsSystem(World* world) : System(world) +{ + m_Broadphase = new btDbvtBroadphase(); + m_CollisionConfiguration = new btDefaultCollisionConfiguration(); + m_Dispatcher = new btCollisionDispatcher(m_CollisionConfiguration); + m_Solver = new btSequentialImpulseConstraintSolver(); + + m_DynamicsWorld = new btDiscreteDynamicsWorld(m_Dispatcher, m_Broadphase, m_Solver, m_CollisionConfiguration); + + m_DynamicsWorld->setGravity(btVector3(0, -9.82f, 0)); + +} + +void Systems::PhysicsSystem::Update(double dt) +{ + // Update entity transform in physics world + for (auto pair : *m_World->GetEntities()) { + EntityID entity = pair.first; + EntityID parent = pair.second; + + if (parent != 0) + continue; + + if (m_PhysicsData.find(entity) != m_PhysicsData.end()) { + PhysicsData* physicsData = &m_PhysicsData[entity]; + auto transformComponent = m_World->GetComponent(entity, "Transform"); + + btTransform transform; + transform.setFromOpenGLMatrix(glm::value_ptr(glm::translate(glm::mat4(), transformComponent->Position) * glm::toMat4(transformComponent->Orientation))); + physicsData->MotionState->setWorldTransform(transform); + physicsData->CollisionShape->setLocalScaling(btVector3(transformComponent->Scale.x, transformComponent->Scale.y, transformComponent->Scale.z)); + + + auto physicsComponent = m_World->GetComponent(entity, "Physics"); + physicsData->RigidBody->setGravity(btVector3(physicsComponent->Gravity.x, physicsComponent->Gravity.y, physicsComponent->Gravity.z)); + } + } + + m_DynamicsWorld->stepSimulation(dt, 10, 1.0f/60.0f); + + + + +} + +void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) +{ + auto transformComponent = m_World->GetComponent(entity, "Transform"); + if (!transformComponent) + return; + + auto physicsComponent = m_World->GetComponent(entity, "Physics"); + auto sphereShapeComponent = m_World->GetComponent(entity, "SphereShape"); + auto boxShapeComponent = m_World->GetComponent(entity, "BoxShape"); + + if (physicsComponent && (sphereShapeComponent || boxShapeComponent)) + { + if (m_PhysicsData.find(entity) == m_PhysicsData.end()) { + SetUpPhysicsState(entity); + } + + if (parent != 0) + return; + PhysicsData* physicsData = &m_PhysicsData[entity]; + + btTransform transform; + physicsData->MotionState->getWorldTransform(transform); + transformComponent->Position.x = transform.getOrigin().x(); + transformComponent->Position.y = transform.getOrigin().y(); + transformComponent->Position.z = transform.getOrigin().z(); + btVector3 angle = transform.getRotation().getAxis(); + transformComponent->Orientation.x = transform.getRotation().x(); + transformComponent->Orientation.y = transform.getRotation().y(); + transformComponent->Orientation.z = transform.getRotation().z(); + transformComponent->Orientation.w = transform.getRotation().w(); + } + else + { + if (m_PhysicsData.find(entity) != m_PhysicsData.end()) { + TearDownPhysicsState(entity); + } + } +} + +void Systems::PhysicsSystem::OnComponentCreated(std::string type, std::shared_ptr component) +{ + +} + +void Systems::PhysicsSystem::OnComponentRemoved(std::string type, Component* component) +{ + +} + +void Systems::PhysicsSystem::SetUpPhysicsState(EntityID entity) +{ + auto transformComponent = m_World->GetComponent(entity, "Transform"); + auto physicsComponent = m_World->GetComponent(entity, "Physics"); + auto sphereShapeComponent = m_World->GetComponent(entity, "SphereShape"); + auto boxShapeComponent = m_World->GetComponent(entity, "BoxShape"); + PhysicsData* physicsData = &m_PhysicsData[entity]; + + + if (boxShapeComponent) + { + physicsData->CollisionShape = new btBoxShape(btVector3(boxShapeComponent->Width, boxShapeComponent->Height, boxShapeComponent->Depth)); + } + else if(sphereShapeComponent) + { + physicsData->CollisionShape = new btSphereShape(sphereShapeComponent->Radius); + } + + if (transformComponent) + { + btTransform transform; + transform.setFromOpenGLMatrix(glm::value_ptr(glm::translate(glm::mat4(), transformComponent->Position) * glm::toMat4(transformComponent->Orientation))); + physicsData->MotionState = new btDefaultMotionState(transform); + } + + + btVector3 inertia; + if (physicsComponent->Mass != 0) + physicsData->CollisionShape->calculateLocalInertia(physicsComponent->Mass, inertia); + + btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(physicsComponent->Mass, physicsData->MotionState, physicsData->CollisionShape, inertia); + rigidBodyCI.m_friction = physicsComponent->Friction; + if (sphereShapeComponent) + { + rigidBodyCI.m_rollingFriction = sphereShapeComponent->RollingFriction; + } + + physicsData->RigidBody = new btRigidBody(rigidBodyCI); + + + + m_DynamicsWorld->addRigidBody(physicsData->RigidBody); +} + +void Systems::PhysicsSystem::TearDownPhysicsState(EntityID entity) +{ + PhysicsData* physicsData = &m_PhysicsData[entity]; + + delete physicsData->RigidBody; + delete physicsData->MotionState; + delete physicsData->CollisionShape; + + m_PhysicsData.erase(entity); +} + diff --git a/src/Systems/PhysicsSystem.h b/src/Systems/PhysicsSystem.h new file mode 100644 index 0000000..8421e34 --- /dev/null +++ b/src/Systems/PhysicsSystem.h @@ -0,0 +1,49 @@ +#ifndef PhysicsSystem_h__ +#define PhysicsSystem_h__ + +#include "System.h" +#include "Components/Transform.h" +#include "Components/Physics.h" +#include "Components/BoxShape.h" +#include "Components/SphereShape.h" + +#include "btBulletDynamicsCommon.h" +#include "LinearMath/btMatrix3x3.h" + +namespace Systems +{ + + class PhysicsSystem : public System + { + public: + PhysicsSystem(World* world); + void Update(double dt) override; + void UpdateEntity(double dt, EntityID entity, EntityID parent) override; + void OnComponentCreated(std::string type, std::shared_ptr component) override; + void OnComponentRemoved(std::string type, Component* component) override; + + private: + btBroadphaseInterface* m_Broadphase; + btDefaultCollisionConfiguration* m_CollisionConfiguration; + btCollisionDispatcher* m_Dispatcher; + btSequentialImpulseConstraintSolver* m_Solver; + btDiscreteDynamicsWorld* m_DynamicsWorld; + + struct PhysicsData + { + btRigidBody* RigidBody; + btMotionState* MotionState; + btCollisionShape* CollisionShape; + }; + std::map m_PhysicsData; + + + void SetUpPhysicsState(EntityID entity); + void TearDownPhysicsState(EntityID entity); + + + + }; +} + +#endif // PhysicsSystem_h__ diff --git a/src/main.cpp b/src/main.cpp index 5e069e8..03b63b4 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,4 +8,4 @@ int main(int argc, char* argv[]) engine.Tick(); return 0; -} \ No newline at end of file +} diff --git a/vs12/Returngeance/Returngeance.vcxproj b/vs12/Returngeance/Returngeance.vcxproj index 792a1ac..631e276 100755 --- a/vs12/Returngeance/Returngeance.vcxproj +++ b/vs12/Returngeance/Returngeance.vcxproj @@ -61,7 +61,7 @@ true - OpenAL32.lib;opengl32.lib;glu32.lib;SOIL.lib;glew32d.lib;glfw3dll.lib;BulletCollision_Debug.lib;%(AdditionalDependencies) + BulletCollision_Debug.lib;BulletDynamics_Debug.lib;LinearMath_Debug.lib;OpenAL32.lib;opengl32.lib;glu32.lib;SOIL.lib;glew32d.lib;glfw3dll.lib;%(AdditionalDependencies) @@ -80,7 +80,7 @@ true true true - OpenAL32.lib;opengl32.lib;glu32.lib;SOIL.lib;glew32.lib;glfw3dll.lib;BulletCollision.lib;%(AdditionalDependencies) + BulletCollision.lib;BulletDynamics.lib;LinearMath.lib;OpenAL32.lib;opengl32.lib;glu32.lib;SOIL.lib;glew32.lib;glfw3dll.lib;%(AdditionalDependencies) @@ -95,8 +95,10 @@ + + @@ -110,7 +112,6 @@ - @@ -137,8 +138,10 @@ + + diff --git a/vs12/Returngeance/Returngeance.vcxproj.filters b/vs12/Returngeance/Returngeance.vcxproj.filters index eb1064e..74260f3 100755 --- a/vs12/Returngeance/Returngeance.vcxproj.filters +++ b/vs12/Returngeance/Returngeance.vcxproj.filters @@ -25,6 +25,12 @@ Systems + + Systems + + + Systems + @@ -130,8 +136,11 @@ Components - - Components + + Systems + + + Systems