diff --git a/src/Components/Vehicle.h b/src/Components/Vehicle.h index 026c0aa..e61c713 100644 --- a/src/Components/Vehicle.h +++ b/src/Components/Vehicle.h @@ -3,13 +3,15 @@ #include "Component.h" + namespace Components { - struct Vehicle : Component -{ +struct Vehicle : Component +{ Vehicle() : MaxTorque(500.0f), MinRPM(1000.0f), OptimalRPM(5500.0f), MaxRPM(7500.0f), MaxSteeringAngle(35), TopSpeed(50.0f) { } + float MaxTorque; float MinRPM; float OptimalRPM; diff --git a/src/Components/Wheel.h b/src/Components/Wheel.h index d5a8d81..f000058 100644 --- a/src/Components/Wheel.h +++ b/src/Components/Wheel.h @@ -3,11 +3,15 @@ #include "Component.h" +namespace Systems { class PhysicsSystem; } + namespace Components { struct Wheel : Component { + friend class Systems::PhysicsSystem; + Wheel() : AxleID(0), Radius(0), Width(0), Mass(0), Steering(false), DownDirection(glm::vec3(0, -1, 0)), Friction(1.5f), SlipAngle(0.0f), MaxBreakingTorque(1500.0f), ConnectedToHandbrake(false), SuspensionStrength(50.0f) { } @@ -26,6 +30,9 @@ struct Wheel : Component float SlipAngle; float MaxBreakingTorque; bool ConnectedToHandbrake; + +private: + int ID; }; } diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 7da4e68..6c9e5d4 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -41,10 +41,11 @@ void GameWorld::Initialize() } + for (int i = 0; i < 1; i++) { auto car = CreateEntity(); auto transform = AddComponent(car, "Transform"); - transform->Position = glm::vec3(0, 5, 0); + transform->Position = glm::vec3(0, (i+1)*5, 0); transform->Scale = glm::vec3(3, 1, 5); transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); auto model = AddComponent(car, "Model"); @@ -56,58 +57,74 @@ void GameWorld::Initialize() box->Height = 0.5f; box->Depth = 2.5f; auto vehicle = AddComponent(car, "Vehicle"); + vehicle->TopSpeed = 500.f; + vehicle->MaxTorque = 1000.f; AddComponent(car, "Input"); { // Front Right Wheel auto ent = CreateEntity(car); auto transform = AddComponent(ent, "Transform"); + transform->Scale = glm::vec3(1)/glm::vec3(3, 1, 5); transform->Position = glm::vec3(1.1f, -0.5f, -1.3f); auto Wheel = AddComponent(ent, "Wheel"); Wheel->Hardpoint = glm::vec3(1.1f, 0.f, -1.3f);// HACK: make into component Wheel->AxleID = 0; Wheel->Mass = 10; - Wheel->Radius = 0.6f; + Wheel->Radius = 0.5f; Wheel->Steering = true; + auto model = AddComponent(ent, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; CommitEntity(ent); } { // Front Left Wheel auto ent = CreateEntity(car); auto transform = AddComponent(ent, "Transform"); + transform->Scale = glm::vec3(1)/glm::vec3(3, 1, 5); transform->Position = glm::vec3(-1.1f, -0.5f, -1.3f); auto Wheel = AddComponent(ent, "Wheel"); Wheel->Hardpoint = glm::vec3(-1.1f, 0.f, -1.3f); Wheel->AxleID = 0; Wheel->Mass = 10; - Wheel->Radius = 0.6f; + Wheel->Radius = 0.5f; Wheel->Steering = true; + auto model = AddComponent(ent, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; CommitEntity(ent); } { // Back Right Wheel auto ent = CreateEntity(car); auto transform = AddComponent(ent, "Transform"); + transform->Scale = glm::vec3(1)/glm::vec3(3, 1, 5); transform->Position = glm::vec3(1.1f, -0.5f, 1.3f); auto Wheel = AddComponent(ent, "Wheel"); Wheel->Hardpoint = glm::vec3(1.1f, 0.f, 1.3f); Wheel->AxleID = 1; Wheel->Mass = 10; - Wheel->Radius = 0.6f; + Wheel->Radius = 0.5f; Wheel->Steering = false; + Wheel->ConnectedToHandbrake = true; + auto model = AddComponent(ent, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; CommitEntity(ent); } { // Back Left Wheel auto ent = CreateEntity(car); auto transform = AddComponent(ent, "Transform"); + transform->Scale = glm::vec3(1)/glm::vec3(3, 1, 5); transform->Position = glm::vec3(-1.1f, -0.5f, 1.3f); auto Wheel = AddComponent(ent, "Wheel"); Wheel->Hardpoint = glm::vec3(-1.1f, 0.f, 1.3f); Wheel->AxleID = 1; Wheel->Mass = 10; - Wheel->Radius = 0.6f; + Wheel->Radius = 0.5f; Wheel->Steering = false; + Wheel->ConnectedToHandbrake = true; + auto model = AddComponent(ent, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; CommitEntity(ent); } diff --git a/src/GameWorld.cpp.orig b/src/GameWorld.cpp.orig new file mode 100644 index 0000000..73aac8b --- /dev/null +++ b/src/GameWorld.cpp.orig @@ -0,0 +1,233 @@ +#include "PrecompiledHeader.h" +#include "GameWorld.h" + +void GameWorld::Initialize() +{ + World::Initialize(); + + + { + auto camera = CreateEntity(); + auto transform = AddComponent(camera, "Transform"); + transform->Position.z = 20.f; + transform->Position.y = 20.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"); + CommitEntity(camera); + } + + + { + auto ground = CreateEntity(); + auto transform = AddComponent(ground, "Transform"); + transform->Position = glm::vec3(0, -5, 0); + transform->Scale = glm::vec3(1000.0f, 10.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 = 5; + box->Depth = 500; + + auto physics = AddComponent(ground, "Physics"); + physics->Mass = 10; +<<<<<<< HEAD + physics->Static = true; +======= + CommitEntity(ground); +>>>>>>> 84d6911... Barebones entity component commit events + } + + + { + auto car = CreateEntity(); + auto transform = AddComponent(car, "Transform"); + transform->Position = glm::vec3(0, 5, 0); + transform->Scale = glm::vec3(3, 1, 5); + transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); + auto model = AddComponent(car, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; + auto physics = AddComponent(car, "Physics"); + physics->Mass = 1200; + auto box = AddComponent(car, "Box"); + box->Width = 1.5f; + box->Height = 0.5f; + box->Depth = 2.5f; + auto vehicle = AddComponent(car, "Vehicle"); + AddComponent(car, "Input"); + + { + // Front Right Wheel + auto ent = CreateEntity(car); + auto transform = AddComponent(ent, "Transform"); + transform->Position = glm::vec3(1.1f, -0.5f, -1.3f); + auto Wheel = AddComponent(ent, "Wheel"); + Wheel->Hardpoint = glm::vec3(1.1f, 0.f, -1.3f);// HACK: make into component + Wheel->AxleID = 0; + Wheel->Mass = 10; + Wheel->Radius = 0.6f; + Wheel->Steering = true; + } + { + // Front Left Wheel + auto ent = CreateEntity(car); + auto transform = AddComponent(ent, "Transform"); + transform->Position = glm::vec3(-1.1f, -0.5f, -1.3f); + auto Wheel = AddComponent(ent, "Wheel"); + Wheel->Hardpoint = glm::vec3(-1.1f, 0.f, -1.3f); + Wheel->AxleID = 0; + Wheel->Mass = 10; + Wheel->Radius = 0.6f; + Wheel->Steering = true; + } + { + // Back Right Wheel + auto ent = CreateEntity(car); + auto transform = AddComponent(ent, "Transform"); + transform->Position = glm::vec3(1.1f, -0.5f, 1.3f); + auto Wheel = AddComponent(ent, "Wheel"); + Wheel->Hardpoint = glm::vec3(1.1f, 0.f, 1.3f); + Wheel->AxleID = 1; + Wheel->Mass = 10; + Wheel->Radius = 0.6f; + Wheel->Steering = false; + } + { + // Back Left Wheel + auto ent = CreateEntity(car); + auto transform = AddComponent(ent, "Transform"); + transform->Position = glm::vec3(-1.1f, -0.5f, 1.3f); + auto Wheel = AddComponent(ent, "Wheel"); + Wheel->Hardpoint = glm::vec3(-1.1f, 0.f, 1.3f); + Wheel->AxleID = 1; + Wheel->Mass = 10; + Wheel->Radius = 0.6f; + Wheel->Steering = false; + } + +<<<<<<< HEAD + } + +======= + auto model = AddComponent(TankTest, "Model"); + model->ModelFile = "Models/Placeholders/tank/Chassi.obj"; + CommitEntity(TankTest); + } + + for(int i = 0; i < 83; i++) + { + auto light = CreateEntity(); + auto transform = AddComponent(light, "Transform"); + transform->Position = glm::vec3((float)(2*i)*glm::sin((float)i), 3, (float)(2*i)*glm::cos((float)i)); + + auto pointLight = AddComponent(light, "PointLight"); + pointLight->Specular = glm::vec3(0.1f, 0.1f, 0.1f); + pointLight->Diffuse = glm::vec3(0.05f, 0.36f, 1.f); + pointLight->constantAttenuation = 0.03f; + pointLight->linearAttenuation = 0.009f; + pointLight->quadraticAttenuation = 0.07f; + pointLight->spotExponent = 0.0f; + + auto model = AddComponent(light, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/PointLight.obj"; + CommitEntity(light); + } +>>>>>>> 84d6911... Barebones entity component commit events + + + for(int i = 0; i < 50; i++) + { + auto ball = CreateEntity(); + auto transform = AddComponent(ball, "Transform"); + transform->Position = glm::vec3(243, 10 + i*10, 0); + transform->Scale = glm::vec3(10); + transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); + auto model = AddComponent(ball, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; + auto physics = AddComponent(ball, "Physics"); +<<<<<<< HEAD + physics->Mass = 100; + auto box = AddComponent(ball, "Box"); + box->Width = 5.f; + box->Height = 5.f; + box->Depth = 5.f; +======= + physics->Mass = 1; + CommitEntity(ball); +>>>>>>> 84d6911... Barebones entity component commit events + } + + { + 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) +{ + World::Update(dt); +} + +void GameWorld::RegisterComponents() +{ + m_ComponentFactory.Register("Camera", []() { return new Components::Camera(); }); + m_ComponentFactory.Register("DirectionalLight", []() { return new Components::DirectionalLight(); }); + m_ComponentFactory.Register("Input", []() { return new Components::Input(); }); + m_ComponentFactory.Register("Model", []() { return new Components::Model(); }); + m_ComponentFactory.Register("ParticleEmitter", []() { return new Components::ParticleEmitter(); }); + m_ComponentFactory.Register("PointLight", []() { return new Components::PointLight(); }); + m_ComponentFactory.Register("SoundEmitter", []() { return new Components::SoundEmitter(); }); + m_ComponentFactory.Register("Sprite", []() { return new Components::Sprite(); }); + 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("Physics", []() { return new Components::Physics(); }); + m_ComponentFactory.Register("Sphere", []() { return new Components::Sphere(); }); + m_ComponentFactory.Register("Box", []() { return new Components::Box (); }); + m_ComponentFactory.Register("Vehicle", []() { return new Components::Vehicle(); }); + m_ComponentFactory.Register("Wheel", []() { return new Components::Wheel(); }); +} + +void GameWorld::RegisterSystems() +{ + m_SystemFactory.Register("TransformSystem", [this]() { return new Systems::TransformSystem(this); }); + //m_SystemFactory.Register("LevelGenerationSystem", [this]() { return new Systems::LevelGenerationSystem(this); }); + m_SystemFactory.Register("InputSystem", [this]() { return new Systems::InputSystem(this, m_Renderer); }); + //m_SystemFactory.Register("CollisionSystem", [this]() { return new Systems::CollisionSystem(this); }); + ////m_SystemFactory.Register("ParticleSystem", [this]() { return new Systems::ParticleSystem(this); }); + //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() +{ + AddSystem("TransformSystem"); + //AddSystem("LevelGenerationSystem"); + AddSystem("InputSystem"); + //AddSystem("CollisionSystem"); + ////AddSystem("ParticleSystem"); + //AddSystem("PlayerSystem"); + AddSystem("FreeSteeringSystem"); + AddSystem("SoundSystem"); + + AddSystem("PhysicsSystem"); + + AddSystem("RenderSystem"); + + +} \ No newline at end of file diff --git a/src/Physics/VehicleSetup.cpp b/src/Physics/VehicleSetup.cpp index 559882e..1768b1e 100644 --- a/src/Physics/VehicleSetup.cpp +++ b/src/Physics/VehicleSetup.cpp @@ -253,7 +253,7 @@ void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultS suspension.m_wheelParams[i].m_hardpointChassisSpace.set(m_Wheels[i].WheelComponent->Hardpoint.x, m_Wheels[i].WheelComponent->Hardpoint.y, m_Wheels[i].WheelComponent->Hardpoint.z); - suspension.m_wheelParams[0].m_directionChassisSpace = hkVector4(m_Wheels[i].WheelComponent->DownDirection.x, m_Wheels[i].WheelComponent->DownDirection.y, m_Wheels[i].WheelComponent->DownDirection.z); + suspension.m_wheelParams[i].m_directionChassisSpace = hkVector4(m_Wheels[i].WheelComponent->DownDirection.x, m_Wheels[i].WheelComponent->DownDirection.y, m_Wheels[i].WheelComponent->DownDirection.z); } } diff --git a/src/Systems/PhysicsSystem.cpp b/src/Systems/PhysicsSystem.cpp index c7c6306..0ba5a2e 100644 --- a/src/Systems/PhysicsSystem.cpp +++ b/src/Systems/PhysicsSystem.cpp @@ -102,18 +102,36 @@ void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID p auto transformComponent = m_World->GetComponent(entity, "Transform"); if (!transformComponent) return; - - if (m_RigidBodies.find(entity) == m_RigidBodies.end()) + + auto wheelComponent = m_World->GetComponent(entity, "Wheel"); + if (wheelComponent) { - SetUpPhysicsState(entity, parent); + EntityID car = m_World->GetEntityParent(entity); + if(m_Vehicles.find(car) != m_Vehicles.end()) + { + hkVector4 position; + hkQuaternion orientation; + m_Vehicles[car]->calcCurrentPositionAndRotation(m_RigidBodies[car], m_Vehicles[car]->m_suspension, wheelComponent->ID, position, orientation); + hkVector4 chassisPosition = m_RigidBodies[car]->getPosition(); + hkQuaternion chassisOrientation = m_RigidBodies[car]->getRotation(); + glm::vec3 relativePos = glm::vec3(chassisPosition(0), chassisPosition(1), chassisPosition(2)) - glm::vec3(position(0), position(1), position(2)); + glm::quat relativeOrientation = glm::quat(orientation(3), orientation(0), orientation(1), orientation(2)); + + transformComponent->Position = relativePos; + //transformComponent->Orientation = relativeOrientation; + } } 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)); + if(m_Vehicles.find(entity) != m_Vehicles.end()) + { + 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)); + } } + // HACK: Vehicle test-controls auto vehicleComponent = m_World->GetComponent(entity, "Vehicle"); @@ -127,6 +145,118 @@ void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID p } } +void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) +{ + auto transformComponent = m_World->GetComponent(entity, "Transform"); + if (!transformComponent) + return; + + + auto wheelComponent = m_World->GetComponent(entity, "Wheel"); + if (wheelComponent) + { + wheelComponent->ID = m_Wheels.size(); + m_Wheels.push_back(entity); + } + + 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; + + if (physicsComponent->Static) + { + rigidBodyInfo.m_motionType = hkpMotion::MOTION_FIXED; + } + else + { + rigidBodyInfo.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA; + } + + hkpInertiaTensorComputer::computeSphereVolumeMassProperties(sphereComponent->Radius, physicsComponent->Mass, massProperties); + + } + else if (boxComponent) + { + hkReal thickness = 0.05; + shape = new hkpBoxShape(hkVector4(boxComponent->Width - thickness, boxComponent->Height - thickness, boxComponent->Depth - thickness)); + rigidBodyInfo.m_shape = shape; + if (physicsComponent->Static) + { + rigidBodyInfo.m_motionType = hkpMotion::MOTION_FIXED; + } + else + { + rigidBodyInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA; + } + 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); + + + auto vehicleComponent = m_World->GetComponent(entity, "Vehicle"); + if (vehicleComponent && m_Vehicles.find(entity) == m_Vehicles.end()) + { + for (int i = 0; i < m_Wheels.size(); i++) + { + if(m_World->GetEntityParent(m_Wheels[i]) != entity) + { + m_Wheels.erase(m_Wheels.begin() + i); + i--; + } + } + VehicleSetup vehicleSetup; + + // Create the basic vehicle. + m_Vehicles[entity] = new hkpVehicleInstance(rigidBody); + vehicleSetup.buildVehicle(m_World, m_PhysicsWorld, *m_Vehicles[entity], entity, m_Wheels); + // Add the vehicle's entities and phantoms to the world + m_Vehicles[entity]->addToWorld(m_PhysicsWorld); + + m_RigidBodies[entity] = rigidBody; + + // The vehicle is an action + m_PhysicsWorld->addAction(m_Vehicles[entity]); + + //m_Vehicles[entity]->m_rpm = 0.0f; // Not sure why this one should be here + m_Wheels.clear(); + shape->removeReference(); + rigidBody->removeReference(); + } + else + { + m_PhysicsWorld->addEntity(rigidBody); + m_RigidBodies[entity] = rigidBody; + shape->removeReference(); + rigidBody->removeReference(); + } +} +/* + void Systems::PhysicsSystem::SetUpPhysicsState(EntityID entity, EntityID parent) { auto transformComponent = m_World->GetComponent(entity, "Transform"); @@ -221,6 +351,8 @@ void Systems::PhysicsSystem::SetUpPhysicsState(EntityID entity, EntityID parent) rigidBody->removeReference(); } } +*/ + @@ -268,6 +400,7 @@ void Systems::PhysicsSystem::StepVisualDebugger() void HK_CALL Systems::PhysicsSystem::HavokErrorReport(const char* msg, void*) { - LOG_DEBUG("%s", msg); + LOG_INFO("%s", msg); } + diff --git a/src/Systems/PhysicsSystem.h b/src/Systems/PhysicsSystem.h index 1bbffdd..a7d917f 100644 --- a/src/Systems/PhysicsSystem.h +++ b/src/Systems/PhysicsSystem.h @@ -58,7 +58,7 @@ public: 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; - + void OnEntityCommit(EntityID entity) override; private: double m_Accumulator; @@ -75,7 +75,7 @@ private: std::unordered_map m_RigidBodies; std::unordered_map m_Vehicles; - + std::vector m_Wheels; hkpVehicleInstance* Systems::PhysicsSystem::createVehicle(VehicleSetup& vehicleSetup, hkpRigidBody* chassis); };