diff --git a/src/Components/Box.h b/src/Components/Box.h new file mode 100644 index 0000000..b9ddea7 --- /dev/null +++ b/src/Components/Box.h @@ -0,0 +1,21 @@ +#ifndef Components_Box_h__ +#define Components_Box_h__ + +#include "Component.h" + +namespace Components +{ + +struct Box : Component +{ + Box() + : Width(1.f), Height(1.f), Depth(1.f){ } + + float Width; + float Height; + float Depth; +}; + +} + +#endif // Components_Box_h__ diff --git a/src/Components/Physics.h b/src/Components/Physics.h new file mode 100644 index 0000000..956ae7a --- /dev/null +++ b/src/Components/Physics.h @@ -0,0 +1,19 @@ +#ifndef Components_Physics_h__ +#define Components_Physics_h__ + +#include "Component.h" + +namespace Components +{ + +struct Physics : Component +{ + Physics() + : Mass(0.f) { } + + float Mass; +}; + +} + +#endif // Components_Physics_h__ diff --git a/src/Components/Sphere.h b/src/Components/Sphere.h new file mode 100644 index 0000000..2d089dd --- /dev/null +++ b/src/Components/Sphere.h @@ -0,0 +1,19 @@ +#ifndef Components_Sphere_h__ +#define Components_Sphere_h__ + +#include "Component.h" + +namespace Components +{ + +struct Sphere : Component +{ + Sphere() + : Radius(1.f){ } + + float Radius; +}; + +} + +#endif // Components_Sphere_h__ diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 274ad52..9272005 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -17,24 +17,47 @@ void GameWorld::Initialize() auto freeSteering = AddComponent(camera, "FreeSteering"); } - { - auto terrain = CreateEntity(); - auto transform = AddComponent(terrain, "Transform"); - transform->Position = glm::vec3(0, -5, 0); - transform->Scale = glm::vec3(1000.0f, 1, 1000.0f); - transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); - auto model = AddComponent(terrain, "Model"); - model->ModelFile = "Models/Placeholders/PhysicsTest/Plane.obj"; - } { + auto ground = CreateEntity(); + auto transform = AddComponent(ground, "Transform"); + transform->Position = glm::vec3(0, 0, 0); + transform->Scale = glm::vec3(1000.0f, 1.0f, 1000.0f); + transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); + auto model = AddComponent(ground, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube.obj"; + auto box = AddComponent(ground, "Box"); + box->Width = 500; + box->Height = 0.5; + box->Depth = 500; + + auto physics = AddComponent(ground, "Physics"); + physics->Mass = 10; + } + + for(int i = 0; i < 10; i++) + { + auto ball = CreateEntity(); + auto transform = AddComponent(ball, "Transform"); + transform->Position = glm::vec3(0, 5 + i*2, 0); + transform->Scale = glm::vec3(1.0f, 1.0f, 1.0f); + transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); + auto model = AddComponent(ball, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Sphere.obj"; + auto sphere = AddComponent(ball, "Sphere"); + sphere->Radius = 0.5; + auto physics = AddComponent(ball, "Physics"); + physics->Mass = 1; + } + + /*{ auto entity = CreateEntity(); AddComponent(entity, "Transform"); auto emitter = AddComponent(entity, "SoundEmitter"); emitter->Path = "Sounds/korvring.wav"; emitter->Loop = true; GetSystem("SoundSystem")->PlaySound(emitter); - } + }*/ } void GameWorld::Update(double dt) @@ -56,7 +79,9 @@ void GameWorld::RegisterComponents() m_ComponentFactory.Register("Transform", []() { return new Components::Transform(); }); m_ComponentFactory.Register("FreeSteering", []() { return new Components::FreeSteering(); }); - ///m_ComponentFactory.Register("Physics", []() { return new Components::Physics(); }); + m_ComponentFactory.Register("Physics", []() { return new Components::Physics(); }); + m_ComponentFactory.Register("Sphere", []() { return new Components::Sphere(); }); + m_ComponentFactory.Register("Box", []() { return new Components::Box (); }); } void GameWorld::RegisterSystems() diff --git a/src/GameWorld.h b/src/GameWorld.h index 9694daf..b40807e 100755 --- a/src/GameWorld.h +++ b/src/GameWorld.h @@ -27,6 +27,10 @@ #include "Components/Template.h" #include "Components/Transform.h" +#include "Components/Physics.h" +#include "Components/Sphere.h" +#include "Components/Box.h" + class GameWorld : public World { public: diff --git a/src/Systems/PhysicsSystem.cpp b/src/Systems/PhysicsSystem.cpp index eef803f..c70c8fc 100644 --- a/src/Systems/PhysicsSystem.cpp +++ b/src/Systems/PhysicsSystem.cpp @@ -28,13 +28,13 @@ Systems::PhysicsSystem::PhysicsSystem(World* world) : System(world) -{ +{ + { + hkMemorySystem::FrameInfo finfo(500 * 1024); // Allocate 500KB of Physics solver buffer + hkMemoryRouter* memoryRouter = hkMemoryInitUtil::initDefault(hkMallocAllocator::m_defaultMallocAllocator, finfo); + hkBaseSystem::init(memoryRouter, HavokErrorReport); - hkMemorySystem::FrameInfo finfo(500 * 1024); // Allocate 500KB of Physics solver buffer - hkMemoryRouter* memoryRouter = hkMemoryInitUtil::initDefault(hkMallocAllocator::m_defaultMallocAllocator, finfo); - hkBaseSystem::init(memoryRouter, HavokErrorReport); - hkpWorldCinfo worldInfo; worldInfo.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM); worldInfo.m_gravity = hkVector4(0.0f, -9.8f, 0.0f); @@ -43,7 +43,7 @@ Systems::PhysicsSystem::PhysicsSystem(World* world) : System(world) // You must specify the size of the broad phase - objects should not be simulated outside this region worldInfo.setBroadPhaseWorldSize(1000.0f); m_PhysicsWorld = new hkpWorld(worldInfo); - + } // Register all collision agents, even though only box - box will be used in this particular example. // It's important to register collision agents before adding any entities to the world. hkpAgentRegisterUtil::registerAllAgents(m_PhysicsWorld->getCollisionDispatcher()); @@ -58,7 +58,7 @@ Systems::PhysicsSystem::PhysicsSystem(World* world) : System(world) context->addWorld(m_PhysicsWorld); // add the physics world so the viewers can see it SetupVisualDebugger(context); - SetupPhysics(m_PhysicsWorld); + //SetupPhysics(m_PhysicsWorld); } void Systems::PhysicsSystem::Update(double dt) @@ -70,6 +70,83 @@ void Systems::PhysicsSystem::Update(double dt) } void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) +{ + auto transformComponent = m_World->GetComponent(entity, "Transform"); + if (!transformComponent) + return; + + if (m_RigidBodies.find(entity) == m_RigidBodies.end()) + { + SetUpPhysicsState(entity, parent); + } + else + { + hkVector4 position = m_RigidBodies[entity]->getPosition(); + transformComponent->Position = glm::vec3(position(0), position(1), position(2)); + hkQuaternion orientation = m_RigidBodies[entity]->getRotation(); + transformComponent->Orientation = glm::quat(orientation(3),orientation(0), orientation(1), orientation(2)); + } + + +} + +void Systems::PhysicsSystem::SetUpPhysicsState(EntityID entity, EntityID parent) +{ + auto transformComponent = m_World->GetComponent(entity, "Transform"); + if (!transformComponent) + return; + + auto physicsComponent = m_World->GetComponent(entity, "Physics"); + if (!physicsComponent) + return; + + auto sphereComponent = m_World->GetComponent(entity, "Sphere"); + auto boxComponent = m_World->GetComponent(entity, "Box"); + + + hkpConvexShape* shape; + hkpRigidBodyCinfo rigidBodyInfo; + hkMassProperties massProperties; + + + if (sphereComponent) + { + shape = new hkpSphereShape(sphereComponent->Radius); + rigidBodyInfo.m_shape = shape; + rigidBodyInfo.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA; + + hkpInertiaTensorComputer::computeSphereVolumeMassProperties(sphereComponent->Radius, physicsComponent->Mass, massProperties); + + } + else if (boxComponent) + { + shape = new hkpBoxShape(hkVector4(boxComponent->Width, boxComponent->Height, boxComponent->Depth)); + rigidBodyInfo.m_shape = shape; + rigidBodyInfo.m_motionType = hkpMotion::MOTION_FIXED; + hkReal thickness = 0.1; + hkpInertiaTensorComputer::computeBoxSurfaceMassProperties(hkVector4(boxComponent->Width - thickness, boxComponent->Height - thickness, boxComponent->Depth - thickness), physicsComponent->Mass, thickness, massProperties); + } + else + { + return; + } + + rigidBodyInfo.m_position.set(transformComponent->Position.x, transformComponent->Position.y, transformComponent->Position.z); + rigidBodyInfo.m_inertiaTensor = massProperties.m_inertiaTensor; + rigidBodyInfo.m_centerOfMass = massProperties.m_centerOfMass; + rigidBodyInfo.m_mass = massProperties.m_mass; + + // Create RigidBody + hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo); + shape->removeReference(); + + m_PhysicsWorld->addEntity(rigidBody); + m_RigidBodies[entity] = rigidBody; + rigidBody->removeReference(); + +} + +void Systems::PhysicsSystem::TearDownPhysicsState(EntityID entity, EntityID parent) { } @@ -84,15 +161,6 @@ void Systems::PhysicsSystem::OnComponentRemoved(std::string type, Component* com } -void Systems::PhysicsSystem::SetUpPhysicsState(EntityID entity, EntityID parent) -{ - -} - -void Systems::PhysicsSystem::TearDownPhysicsState(EntityID entity, EntityID parent) -{ - -} void Systems::PhysicsSystem::SetupVisualDebugger(hkpPhysicsContext* worlds) { @@ -125,50 +193,3 @@ void HK_CALL Systems::PhysicsSystem::HavokErrorReport(const char* msg, void*) LOG_DEBUG("%s", msg); } - -void Systems::PhysicsSystem::SetupPhysics(hkpWorld* physicsWorld) -{ - // Create the floor as a fixed box - { - hkpRigidBodyCinfo boxInfo; - hkVector4 boxSize(5.0f, 0.5f, 5.0f); - hkpBoxShape* boxShape = new hkpBoxShape(boxSize); - boxInfo.m_shape = boxShape; - boxInfo.m_motionType = hkpMotion::MOTION_FIXED; - boxInfo.m_position.set(0.0f, 0.0f, 0.0f); - boxInfo.m_restitution = 0.9f; - - hkpRigidBody* floor = new hkpRigidBody(boxInfo); - boxShape->removeReference(); - - physicsWorld->addEntity(floor); - floor->removeReference(); - } - - // Create a moving sphere - { - hkReal sphereRadius = 0.5f; - hkpConvexShape* sphereShape = new hkpSphereShape(sphereRadius); - - hkpRigidBodyCinfo sphereInfo; - sphereInfo.m_shape = sphereShape; - sphereInfo.m_position.set(0.0f, 5.0f, 0.0f); - sphereInfo.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA; - - // Compute mass properties - hkReal sphereMass = 10.0f; - hkMassProperties sphereMassProperties; - hkpInertiaTensorComputer::computeSphereVolumeMassProperties(sphereRadius, sphereMass, sphereMassProperties); - sphereInfo.m_inertiaTensor = sphereMassProperties.m_inertiaTensor; - sphereInfo.m_centerOfMass = sphereMassProperties.m_centerOfMass; - sphereInfo.m_mass = sphereMassProperties.m_mass; - - // Create sphere RigidBody - hkpRigidBody* sphereRigidBody = new hkpRigidBody(sphereInfo); - sphereShape->removeReference(); - - physicsWorld->addEntity(sphereRigidBody); - g_ball = sphereRigidBody; - sphereRigidBody->removeReference(); - } -} \ No newline at end of file diff --git a/src/Systems/PhysicsSystem.h b/src/Systems/PhysicsSystem.h index daec8d8..e0856ed 100644 --- a/src/Systems/PhysicsSystem.h +++ b/src/Systems/PhysicsSystem.h @@ -7,8 +7,9 @@ #include "System.h" #include "Components/Transform.h" - - +#include "Components/Physics.h" +#include "Components/Sphere.h" +#include "Components/Box.h" // Math and base include @@ -38,7 +39,7 @@ #include #include - +#include namespace Systems { @@ -63,10 +64,10 @@ private: void SetupVisualDebugger(hkpPhysicsContext* worlds); void StepVisualDebugger(); static void HK_CALL HavokErrorReport(const char* msg, void*); - void SetupPhysics(hkpWorld* physicsWorld); - hkpRigidBody* g_ball; + std::unordered_map m_RigidBodies; + }; } diff --git a/vs11/Returngeance/Returngeance.vcxproj b/vs11/Returngeance/Returngeance.vcxproj index ed68d23..662155f 100644 --- a/vs11/Returngeance/Returngeance.vcxproj +++ b/vs11/Returngeance/Returngeance.vcxproj @@ -118,14 +118,17 @@ + + + diff --git a/vs11/Returngeance/Returngeance.vcxproj.filters b/vs11/Returngeance/Returngeance.vcxproj.filters index e78c08b..346e46f 100644 --- a/vs11/Returngeance/Returngeance.vcxproj.filters +++ b/vs11/Returngeance/Returngeance.vcxproj.filters @@ -130,6 +130,15 @@ Systems + + Components + + + Components + + + Components +