diff --git a/src/Camera.cpp b/src/Camera.cpp index 2db69de..1256e64 100755 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -77,7 +77,7 @@ void Camera::UpdateProjectionMatrix() void Camera::UpdateViewMatrix() { - m_ViewMatrix = glm::translate(glm::toMat4(m_Orientation), -m_Position); + m_ViewMatrix = glm::toMat4(glm::inverse(m_Orientation)) * glm::translate(-m_Position); } void Camera::FOV(float val) diff --git a/src/Components/Physics.h b/src/Components/Physics.h index 956ae7a..df819c4 100644 --- a/src/Components/Physics.h +++ b/src/Components/Physics.h @@ -9,9 +9,10 @@ namespace Components struct Physics : Component { Physics() - : Mass(0.f) { } + : Mass(0.f), Static(false){} float Mass; + bool Static; }; } diff --git a/src/Components/Vehicle.h b/src/Components/Vehicle.h new file mode 100644 index 0000000..e61c713 --- /dev/null +++ b/src/Components/Vehicle.h @@ -0,0 +1,26 @@ +#ifndef Components_Vehicle_h__ +#define Components_Vehicle_h__ + +#include "Component.h" + + +namespace Components +{ + +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; + float MaxRPM; + // Degrees + float MaxSteeringAngle; + float TopSpeed; +}; + +} + +#endif // Components_Vehicle_h__ diff --git a/src/Components/Wheel.h b/src/Components/Wheel.h new file mode 100644 index 0000000..5c005c7 --- /dev/null +++ b/src/Components/Wheel.h @@ -0,0 +1,47 @@ +#ifndef Components_Wheel_h__ +#define Components_Wheel_h__ + +#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) { } + + // The Hardpoint MUST be positioned INSIDE the chassis. + glm::vec3 Hardpoint; + unsigned int AxleID; + float Radius; + float Width; + float Mass; + bool Steering; + glm::vec3 DownDirection; + + float SuspensionStrength; + float Friction; + float SlipAngle; + float MaxBreakingTorque; + bool ConnectedToHandbrake; + +private: + int ID; + glm::quat OriginalOrientation; +}; + +} +#endif // Components_Wheel_h__ + +/* +m_currentSuspensionLength +m_suspension +m_steeringOrientationChassisSpace +m_spinAngle +*/ \ No newline at end of file diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 69f8353..19de351 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -27,122 +27,231 @@ void GameWorld::Initialize() { 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->Position = glm::vec3(0, -5, 0); + transform->Scale = glm::vec3(400.0f, 10.0f, 400.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; + box->Width = 200; + box->Height = 5; + box->Depth = 200; auto physics = AddComponent(ground, "Physics"); physics->Mass = 10; + physics->Static = true; + CommitEntity(ground); } + { auto jeep = CreateEntity(); auto transform = AddComponent(jeep, "Transform"); - transform->Position = glm::vec3(0, 1, 0); + transform->Position = glm::vec3(0, 2, 0); - auto model = AddComponent(jeep, "Model"); - model->ModelFile = "Models/JeepV2/Chassi/chassi.OBJ"; + auto physics = AddComponent(jeep, "Physics"); + physics->Mass = 1200; + auto box = AddComponent(jeep, "Box"); + box->Width = 1.487f; + box->Height = 0.727f; + box->Depth = 2.594f; + auto vehicle = AddComponent(jeep, "Vehicle"); + vehicle->TopSpeed = 500.f; + vehicle->MaxTorque = 1000.f; + AddComponent(jeep, "Input"); + + { + auto chassis = CreateEntity(jeep); + auto transform = AddComponent(chassis, "Transform"); + transform->Position = glm::vec3(0, -0.6577f, 0); + auto model = AddComponent(chassis, "Model"); + model->ModelFile = "Models/JeepV2/Chassi/chassi.OBJ"; + } + + { + auto wheel = CreateEntity(jeep); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(1.4f, 0.5546f - 0.6577f - 0.2, -0.9242f); + transform->Scale = glm::vec3(1.0f); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/JeepV2/WheelFront/wheelFront.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, 1.f, 0.f); + Wheel->AxleID = 0; + Wheel->Mass = 10; + Wheel->Radius = 0.837f; + Wheel->Steering = true; + Wheel->SuspensionStrength = 50.f; + Wheel->Friction = 4.0f; + Wheel->ConnectedToHandbrake = true; + CommitEntity(wheel); + } + + { + auto wheel = CreateEntity(jeep); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(-1.4f, 0.5546f - 0.6577f - 0.2, -0.9242f); + transform->Scale = glm::vec3(1.0f); + transform->Orientation = glm::angleAxis(glm::pi(), glm::vec3(0, 0, 1)); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/JeepV2/WheelFront/wheelFront.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, 1.f, 0.f); + Wheel->AxleID = 0; + Wheel->Mass = 10; + Wheel->Radius = 0.837f; + Wheel->Steering = true; + Wheel->SuspensionStrength = 50.f; + Wheel->Friction = 4.0f; + Wheel->ConnectedToHandbrake = true; + CommitEntity(wheel); + } + + { + auto wheel = CreateEntity(jeep); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(0.2726f, 0.2805f - 0.6577f, 1.9307f); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/JeepV2/WheelBack/wheelBack.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, 1.f, 0.f); + Wheel->AxleID = 1; + Wheel->Mass = 10; + Wheel->Radius = 0.737f; + Wheel->Steering = false; + Wheel->SuspensionStrength = 50.f; + Wheel->Friction = 4.0f; + CommitEntity(wheel); + } + + { + auto wheel = CreateEntity(jeep); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(-0.2726f, 0.2805f - 0.6577f, 1.9307f); + transform->Orientation = glm::angleAxis(glm::pi(), glm::vec3(0, 0, 1)); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/JeepV2/WheelBack/wheelBack.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, 1.f, 0.f); + Wheel->AxleID = 1; + Wheel->Mass = 10; + Wheel->Radius = 0.737f; + Wheel->Steering = false; + Wheel->SuspensionStrength = 50.f; + Wheel->Friction = 4.0f; + CommitEntity(wheel); + } CommitEntity(jeep); - - { - auto wheel = CreateEntity(jeep); - auto transform = AddComponent(wheel, "Transform"); - transform->Position = glm::vec3(1.4f, 0.5546f, -0.9242f); - auto model = AddComponent(wheel, "Model"); - model->ModelFile = "Models/JeepV2/WheelFront/wheelFront.obj"; - CommitEntity(wheel); - } - - { - auto wheel = CreateEntity(jeep); - auto transform = AddComponent(wheel, "Transform"); - transform->Position = glm::vec3(-1.4f, 0.5546f, -0.9242f); - transform->Orientation = glm::angleAxis(glm::pi(), glm::vec3(0, 0, 1)); - auto model = AddComponent(wheel, "Model"); - model->ModelFile = "Models/JeepV2/WheelFront/wheelFront.obj"; - CommitEntity(wheel); - } - - { - auto wheel = CreateEntity(jeep); - auto transform = AddComponent(wheel, "Transform"); - transform->Position = glm::vec3(0.2726f, 0.2805f, 1.9307f); - auto model = AddComponent(wheel, "Model"); - model->ModelFile = "Models/JeepV2/WheelBack/wheelBack.obj"; - CommitEntity(wheel); - } - - { - auto wheel = CreateEntity(jeep); - auto transform = AddComponent(wheel, "Transform"); - transform->Position = glm::vec3(-0.2726f, 0.2805f, 1.9307f); - transform->Orientation = glm::angleAxis(glm::pi(), glm::vec3(0, 0, 1)); - auto model = AddComponent(wheel, "Model"); - model->ModelFile = "Models/JeepV2/WheelBack/wheelBack.obj"; - CommitEntity(wheel); - } } +/* + + { + // 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, -1.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.5f; + Wheel->Steering = true; + Wheel->SuspensionStrength = 20.f; + 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, -1.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.5f; + Wheel->Steering = true; + Wheel->SuspensionStrength = 20.f; + 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, -1.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.5f; + Wheel->Steering = false; + Wheel->ConnectedToHandbrake = true; + Wheel->SuspensionStrength = 20.f; + 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, -1.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.5f; + Wheel->Steering = false; + Wheel->ConnectedToHandbrake = true; + Wheel->SuspensionStrength = 20.f; + auto model = AddComponent(ent, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; + CommitEntity(ent); + } + + CommitEntity(car); + } +*/ + + + + for(int i = 0; i < 10; i++) { - auto TankTest = CreateEntity(); - auto transform = AddComponent(TankTest, "Transform"); - transform->Position = glm::vec3(1.5f, 0.7f, 5.f); - - 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); - } - - for(int i = 0; i < 500; i++) - { - auto ball = CreateEntity(); - auto transform = AddComponent(ball, "Transform"); - transform->Position = glm::vec3(i/5.f, 5 + i*2, i/5.f); - transform->Scale = glm::vec3(1.0f, 1.0f, 1.0f); + auto cube = CreateEntity(); + auto transform = AddComponent(cube, "Transform"); + transform->Position = glm::vec3(20, 10 + i*2, 0); + transform->Scale = glm::vec3(1); 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; - CommitEntity(ball); + auto model = AddComponent(cube, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; + + auto physics = AddComponent(cube, "Physics"); + physics->Mass = 100; + auto box = AddComponent(cube, "Box"); + box->Width = 0.5f; + box->Height = 0.5f; + box->Depth = 0.5f; + CommitEntity(cube); } - /*{ + { auto entity = CreateEntity(); AddComponent(entity, "Transform"); auto emitter = AddComponent(entity, "SoundEmitter"); emitter->Path = "Sounds/korvring.wav"; emitter->Loop = true; GetSystem("SoundSystem")->PlaySound(emitter); - }*/ + CommitEntity(entity); + } } void GameWorld::Update(double dt) @@ -156,6 +265,8 @@ void GameWorld::RegisterComponents() m_ComponentFactory.Register("Template", []() { return new Components::Template(); }); 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() diff --git a/src/GameWorld.cpp.orig b/src/GameWorld.cpp.orig new file mode 100644 index 0000000..1203b42 --- /dev/null +++ b/src/GameWorld.cpp.orig @@ -0,0 +1,413 @@ +#include "PrecompiledHeader.h" +#include "GameWorld.h" + +void GameWorld::Initialize() +{ + World::Initialize(); + +<<<<<<< HEAD + m_ResourceManager.Preload("Model", "Models/Placeholders/PhysicsTest/Plane.obj"); + m_ResourceManager.Preload("Model", "Models/Placeholders/PhysicsTest/ArrowCube.obj"); + + RegisterComponents(); +======= +>>>>>>> havok + + { + 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(400.0f, 10.0f, 400.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 = 200; + box->Height = 5; + box->Depth = 200; + + auto physics = AddComponent(ground, "Physics"); + physics->Mass = 10; +<<<<<<< HEAD + CommitEntity(ground); + } + + { + auto jeep = CreateEntity(); + auto transform = AddComponent(jeep, "Transform"); + transform->Position = glm::vec3(0, 1, 0); + + auto model = AddComponent(jeep, "Model"); + model->ModelFile = "Models/JeepV2/Chassi/chassi.OBJ"; + CommitEntity(jeep); + + { + auto wheel = CreateEntity(jeep); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(1.4f, 0.5546f, -0.9242f); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/JeepV2/WheelFront/wheelFront.obj"; + CommitEntity(wheel); + } + + { + auto wheel = CreateEntity(jeep); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(-1.4f, 0.5546f, -0.9242f); + transform->Orientation = glm::angleAxis(glm::pi(), glm::vec3(0, 0, 1)); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/JeepV2/WheelFront/wheelFront.obj"; + CommitEntity(wheel); + } + + { + auto wheel = CreateEntity(jeep); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(0.2726f, 0.2805f, 1.9307f); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/JeepV2/WheelBack/wheelBack.obj"; + CommitEntity(wheel); + } + + { + auto wheel = CreateEntity(jeep); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(-0.2726f, 0.2805f, 1.9307f); + transform->Orientation = glm::angleAxis(glm::pi(), glm::vec3(0, 0, 1)); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/JeepV2/WheelBack/wheelBack.obj"; + CommitEntity(wheel); + } + } + + { + auto TankTest = CreateEntity(); + auto transform = AddComponent(TankTest, "Transform"); + transform->Position = glm::vec3(1.5f, 0.7f, 5.f); + + 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); + } + + for(int i = 0; i < 500; i++) + { + auto ball = CreateEntity(); + auto transform = AddComponent(ball, "Transform"); + transform->Position = glm::vec3(i/5.f, 5 + i*2, i/5.f); + 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; + CommitEntity(ball); +======= + physics->Static = true; + + CommitEntity(ground); + } + + + { + auto jeep = CreateEntity(); + auto transform = AddComponent(jeep, "Transform"); + transform->Position = glm::vec3(0, 2, 0); + + auto physics = AddComponent(jeep, "Physics"); + physics->Mass = 1200; + auto box = AddComponent(jeep, "Box"); + box->Width = 1.487f; + box->Height = 0.727f; + box->Depth = 2.594f; + auto vehicle = AddComponent(jeep, "Vehicle"); + vehicle->TopSpeed = 500.f; + vehicle->MaxTorque = 1000.f; + AddComponent(jeep, "Input"); + + { + auto chassis = CreateEntity(jeep); + auto transform = AddComponent(chassis, "Transform"); + transform->Position = glm::vec3(0, -0.6577f, 0); + auto model = AddComponent(chassis, "Model"); + model->ModelFile = "Models/JeepV2/Chassi/chassi.OBJ"; + } + + { + auto wheel = CreateEntity(jeep); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(1.4f, 0.5546f - 0.6577f - 0.2, -0.9242f); + transform->Scale = glm::vec3(1.0f); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/JeepV2/WheelFront/wheelFront.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, 1.f, 0.f); + Wheel->AxleID = 0; + Wheel->Mass = 10; + Wheel->Radius = 0.837f; + Wheel->Steering = true; + Wheel->SuspensionStrength = 50.f; + Wheel->Friction = 4.0f; + Wheel->ConnectedToHandbrake = true; + CommitEntity(wheel); + } + + { + auto wheel = CreateEntity(jeep); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(-1.4f, 0.5546f - 0.6577f - 0.2, -0.9242f); + transform->Scale = glm::vec3(1.0f); + transform->Orientation = glm::angleAxis(glm::pi(), glm::vec3(0, 0, 1)); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/JeepV2/WheelFront/wheelFront.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, 1.f, 0.f); + Wheel->AxleID = 0; + Wheel->Mass = 10; + Wheel->Radius = 0.837f; + Wheel->Steering = true; + Wheel->SuspensionStrength = 50.f; + Wheel->Friction = 4.0f; + Wheel->ConnectedToHandbrake = true; + CommitEntity(wheel); + } + + { + auto wheel = CreateEntity(jeep); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(0.2726f, 0.2805f - 0.6577f, 1.9307f); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/JeepV2/WheelBack/wheelBack.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, 1.f, 0.f); + Wheel->AxleID = 1; + Wheel->Mass = 10; + Wheel->Radius = 0.737f; + Wheel->Steering = false; + Wheel->SuspensionStrength = 50.f; + Wheel->Friction = 4.0f; + CommitEntity(wheel); + } + + { + auto wheel = CreateEntity(jeep); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(-0.2726f, 0.2805f - 0.6577f, 1.9307f); + transform->Orientation = glm::angleAxis(glm::pi(), glm::vec3(0, 0, 1)); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/JeepV2/WheelBack/wheelBack.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, 1.f, 0.f); + Wheel->AxleID = 1; + Wheel->Mass = 10; + Wheel->Radius = 0.737f; + Wheel->Steering = false; + Wheel->SuspensionStrength = 50.f; + Wheel->Friction = 4.0f; + CommitEntity(wheel); + } + CommitEntity(jeep); + } + +/* + + { + // 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, -1.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.5f; + Wheel->Steering = true; + Wheel->SuspensionStrength = 20.f; + 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, -1.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.5f; + Wheel->Steering = true; + Wheel->SuspensionStrength = 20.f; + 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, -1.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.5f; + Wheel->Steering = false; + Wheel->ConnectedToHandbrake = true; + Wheel->SuspensionStrength = 20.f; + 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, -1.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.5f; + Wheel->Steering = false; + Wheel->ConnectedToHandbrake = true; + Wheel->SuspensionStrength = 20.f; + auto model = AddComponent(ent, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; + CommitEntity(ent); + } + + CommitEntity(car); + } +*/ + + + + for(int i = 0; i < 10; i++) + { + auto cube = CreateEntity(); + auto transform = AddComponent(cube, "Transform"); + transform->Position = glm::vec3(20, 10 + i*2, 0); + transform->Scale = glm::vec3(1); + transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); + auto model = AddComponent(cube, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; + + auto physics = AddComponent(cube, "Physics"); + physics->Mass = 100; + auto box = AddComponent(cube, "Box"); + box->Width = 0.5f; + box->Height = 0.5f; + box->Depth = 0.5f; + CommitEntity(cube); +>>>>>>> havok + } + + { + auto entity = CreateEntity(); + AddComponent(entity, "Transform"); + auto emitter = AddComponent(entity, "SoundEmitter"); + emitter->Path = "Sounds/korvring.wav"; + emitter->Loop = true; + GetSystem("SoundSystem")->PlaySound(emitter); + CommitEntity(entity); + } +} + +void GameWorld::Update(double dt) +{ + World::Update(dt); +} + +void GameWorld::RegisterComponents() +{ +<<<<<<< HEAD + m_ComponentFactory.Register("Transform", []() { return new Components::Transform(); }); + m_ComponentFactory.Register("Template", []() { return new Components::Template(); }); +======= + 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(); }); +>>>>>>> havok + 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/GameWorld.h b/src/GameWorld.h index 05ca584..1e0f4a1 100755 --- a/src/GameWorld.h +++ b/src/GameWorld.h @@ -29,6 +29,8 @@ #include "Components/Physics.h" #include "Components/Sphere.h" #include "Components/Box.h" +#include "Components/Vehicle.h" +#include "Components/Wheel.h" class GameWorld : public World { diff --git a/src/Physics/VehicleSetup.cpp b/src/Physics/VehicleSetup.cpp new file mode 100644 index 0000000..1768b1e --- /dev/null +++ b/src/Physics/VehicleSetup.cpp @@ -0,0 +1,296 @@ +#include "PrecompiledHeader.h" +#include "Physics/VehicleSetup.h" + + + + + +void VehicleSetup::buildVehicle(World *world, const hkpWorld* physicsWorld, hkpVehicleInstance& vehicle, EntityID vehicleEntity, std::vector wheelEntities) +{ + auto vehicleComponent = world->GetComponent(vehicleEntity, "Vehicle"); + + WheelData wheelData; + for (int i = 0; i < wheelEntities.size(); i++) + { + wheelData.WheelComponent = world->GetComponent(wheelEntities[i], "Wheel"); + wheelData.TransformComponent = world->GetComponent(wheelEntities[i], "Transform"); + m_Wheels.push_back(wheelData); + } + + // + // All memory allocations are made here. + // + vehicle.m_data = new hkpVehicleData; + vehicle.m_driverInput = new hkpVehicleDefaultAnalogDriverInput; + vehicle.m_steering = new hkpVehicleDefaultSteering; + vehicle.m_engine = new hkpVehicleDefaultEngine; + vehicle.m_transmission = new hkpVehicleDefaultTransmission; + vehicle.m_brake = new hkpVehicleDefaultBrake; + vehicle.m_suspension = new hkpVehicleDefaultSuspension; + vehicle.m_aerodynamics = new hkpVehicleDefaultAerodynamics; + vehicle.m_velocityDamper = new hkpVehicleDefaultVelocityDamper; + + // For illustrative purposes we use a custom hkpVehicleRayCastWheelCollide + // which implements varying 'ground' friction in a very simple way. + vehicle.m_wheelCollide = new hkpVehicleRayCastWheelCollide; + + setupVehicleData(physicsWorld, *vehicle.m_data); + + + setupComponent(*vehicle.m_data, *static_cast(vehicle.m_driverInput)); + setupComponent(*vehicle.m_data, *static_cast(vehicle.m_steering), *vehicleComponent); + setupComponent(*vehicle.m_data, *static_cast(vehicle.m_engine), *vehicleComponent); + setupComponent(*vehicle.m_data, *static_cast(vehicle.m_transmission), *vehicleComponent); + setupComponent(*vehicle.m_data, *static_cast(vehicle.m_brake), *vehicleComponent); + setupComponent(*vehicle.m_data, *static_cast(vehicle.m_suspension), *vehicleComponent); + setupComponent(*vehicle.m_data, *static_cast(vehicle.m_aerodynamics), *vehicleComponent); + setupComponent(*vehicle.m_data, *static_cast(vehicle.m_velocityDamper), *vehicleComponent); + + setupWheelCollide(physicsWorld, vehicle, *static_cast(vehicle.m_wheelCollide)); + + + // + // Check that all components are present. + // + HK_ASSERT(0x0 , vehicle.m_data); + HK_ASSERT(0x7708674a, vehicle.m_driverInput); + HK_ASSERT(0x5a324a2d, vehicle.m_steering); + HK_ASSERT(0x7bcb2aff, vehicle.m_engine); + HK_ASSERT(0x29bddb50, vehicle.m_transmission); + HK_ASSERT(0x2b0323a2, vehicle.m_brake); + HK_ASSERT(0x7a7ade23, vehicle.m_suspension); + HK_ASSERT(0x6ec4d0ed, vehicle.m_aerodynamics); + HK_ASSERT(0x67161206, vehicle.m_wheelCollide); + + // + // Set up any variables that store cached data. + // + + + // Give driver input default values so that the vehicle (if this input is a default for non + // player cars) will drive, even if it is in circles! + + // Steering Defaults + vehicle.m_deviceStatus = new hkpVehicleDriverInputAnalogStatus; + hkpVehicleDriverInputAnalogStatus* deviceStatus = (hkpVehicleDriverInputAnalogStatus*)vehicle.m_deviceStatus; + deviceStatus->m_positionY = 0.f; + deviceStatus->m_positionX = 0.f; + deviceStatus->m_handbrakeButtonPressed = false; + deviceStatus->m_reverseButtonPressed = false; + + // + // Don't forget to call init! (This function is necessary to set up derived data) + // + vehicle.init(); +} + +void VehicleSetup::setupVehicleData(const hkpWorld* world, hkpVehicleData& data ) +{ + data.m_gravity = world->getGravity(); + + // + // The vehicleData contains information about the chassis. + // + + // The coordinates of the chassis system, used for steering the vehicle. + // up forward right + data.m_chassisOrientation.setCols(hkVector4(0, 1, 0), hkVector4(0, 0, -1), hkVector4(1, 0, 0)); + + data.m_frictionEqualizer = 0.5f; + + + // Inertia tensor for each axis is calculated by using : + // (1 / chassis_mass) * (torque(axis)Factor / chassisUnitInertia) + data.m_torqueRollFactor = 0.625f; + data.m_torquePitchFactor = 0.5f; + data.m_torqueYawFactor = 0.35f; + + data.m_chassisUnitInertiaYaw = 1.0f; + data.m_chassisUnitInertiaRoll = 1.0f; + data.m_chassisUnitInertiaPitch = 1.0f; + + // Adds or removes torque around the yaw axis + // based on the current steering angle. This will + // affect steering. + data.m_extraTorqueFactor = -0.5f; + data.m_maxVelocityForPositionalFriction = 0.0f; + + // + // Wheel specifications + // + data.m_numWheels = m_Wheels.size(); + + data.m_wheelParams.setSize(data.m_numWheels); + + for (int i = 0; i < m_Wheels.size(); i++) + { + data.m_wheelParams[i].m_axle = m_Wheels[i].WheelComponent->AxleID; + data.m_wheelParams[i].m_friction = m_Wheels[i].WheelComponent->Friction; + data.m_wheelParams[i].m_slipAngle = m_Wheels[i].WheelComponent->SlipAngle; + + // This value is also used to calculate the m_primaryTransmissionRatio. + data.m_wheelParams[i].m_radius = m_Wheels[i].WheelComponent->Radius; + data.m_wheelParams[i].m_width = m_Wheels[i].WheelComponent->Width; + data.m_wheelParams[i].m_mass = m_Wheels[i].WheelComponent->Mass; + + + // May be in wheelcomponent later + data.m_wheelParams[i].m_viscosityFriction = 0.25f; + data.m_wheelParams[i].m_maxFriction = 2.0f * data.m_wheelParams[i].m_friction; + data.m_wheelParams[i].m_forceFeedbackMultiplier = 0.1f; + data.m_wheelParams[i].m_maxContactBodyAcceleration = hkReal(data.m_gravity.length3()) * 2; + } + + + + +} + +void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultAnalogDriverInput& driverInput) +{ + // We also use an analog "driver input" class to help converting user input to vehicle behavior. + + driverInput.m_slopeChangePointX = 0.8f; + driverInput.m_initialSlope = 0.7f; + driverInput.m_deadZone = 0.0f; + driverInput.m_autoReverse = true; +} + +void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultSteering& steering, Components::Vehicle vehicleComponent ) +{ + steering.m_doesWheelSteer.setSize(data.m_numWheels); + + // degrees + steering.m_maxSteeringAngle = vehicleComponent.MaxSteeringAngle * (HK_REAL_PI / 180); + + // [mph/h] The steering angle decreases linearly + // based on your overall max speed of the vehicle. + steering.m_maxSpeedFullSteeringAngle = 70.0f * (1.605f / 3.6f); //MPH???! + + for (int i = 0; i < m_Wheels.size(); i++) + { + steering.m_doesWheelSteer[i] = m_Wheels[i].WheelComponent->Steering; + } +} + +void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultEngine& engine, Components::Vehicle vehicleComponent) +{ + engine.m_maxTorque = vehicleComponent.MaxTorque; + + engine.m_minRPM = vehicleComponent.MinRPM; + engine.m_optRPM = vehicleComponent.OptimalRPM; + + // This value is also used to calculate the m_primaryTransmissionRatio. + engine.m_maxRPM = vehicleComponent.MaxRPM; + + + + engine.m_torqueFactorAtMinRPM = 0.8f; + engine.m_torqueFactorAtMaxRPM = 0.8f; + engine.m_resistanceFactorAtMinRPM = 0.05f; + engine.m_resistanceFactorAtOptRPM = 0.1f; + engine.m_resistanceFactorAtMaxRPM = 0.3f; +} + +void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultTransmission& transmission, Components::Vehicle vehicleComponent ) +{ + int numberOfGears = 4; + transmission.m_gearsRatio.setSize(numberOfGears); + transmission.m_wheelsTorqueRatio.setSize(data.m_numWheels); + + transmission.m_downshiftRPM = 3500.0f; + transmission.m_upshiftRPM = 6500.0f; + + transmission.m_clutchDelayTime = 0.0f; + transmission.m_reverseGearRatio = 1.0f; + transmission.m_gearsRatio[0] = 2.0f; + transmission.m_gearsRatio[1] = 1.5f; + transmission.m_gearsRatio[2] = 1.0f; + transmission.m_gearsRatio[3] = 0.75f; + transmission.m_wheelsTorqueRatio[0] = 0.2f; + transmission.m_wheelsTorqueRatio[1] = 0.2f; + transmission.m_wheelsTorqueRatio[2] = 0.3f; + transmission.m_wheelsTorqueRatio[3] = 0.3f; + + + transmission.m_primaryTransmissionRatio = hkpVehicleDefaultTransmission::calculatePrimaryTransmissionRatio( + vehicleComponent.TopSpeed, + m_Wheels[0].WheelComponent->Radius, // HACK: All wheels are the same size right? + vehicleComponent.MaxRPM, + transmission.m_gearsRatio[numberOfGears - 1]); +} + +void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultBrake& brake, Components::Vehicle vehicleComponent ) +{ + brake.m_wheelBrakingProperties.setSize(data.m_numWheels); + + for (int i = 0; i < m_Wheels.size(); i++) + { + brake.m_wheelBrakingProperties[i].m_maxBreakingTorque = m_Wheels[i].WheelComponent->MaxBreakingTorque; + brake.m_wheelBrakingProperties[i].m_isConnectedToHandbrake = m_Wheels[i].WheelComponent->ConnectedToHandbrake; + + brake.m_wheelBrakingProperties[i].m_minPedalInputToBlock = 0.9f; + } + + brake.m_wheelsMinTimeToBlock = 1000.0f; +} + +void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultSuspension& suspension, Components::Vehicle vehicleComponent) +{ + suspension.m_wheelParams.setSize(data.m_numWheels); + suspension.m_wheelSpringParams.setSize(data.m_numWheels); + + for (int i = 0; i < m_Wheels.size(); i++) + { + float suspensionLength = glm::length(m_Wheels[i].TransformComponent->Position - m_Wheels[i].WheelComponent->Hardpoint); + suspension.m_wheelParams[i].m_length = suspensionLength; + suspension.m_wheelSpringParams[i].m_strength = m_Wheels[i].WheelComponent->SuspensionStrength; + + const float wd = 3.0f; + suspension.m_wheelSpringParams[i].m_dampingCompression = wd; + suspension.m_wheelSpringParams[i].m_dampingRelaxation = wd; + + + 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[i].m_directionChassisSpace = hkVector4(m_Wheels[i].WheelComponent->DownDirection.x, m_Wheels[i].WheelComponent->DownDirection.y, m_Wheels[i].WheelComponent->DownDirection.z); + } +} + +void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultAerodynamics& aerodynamics, Components::Vehicle vehicleComponent ) +{ + aerodynamics.m_airDensity = 1.3f; + // In m^2. + aerodynamics.m_frontalArea = 1.0f; + + aerodynamics.m_dragCoefficient = 0.7f; + aerodynamics.m_liftCoefficient = -0.3f; + + // Extra gavity applies in world space (independent of m_chassisCoordinateSystem). + aerodynamics.m_extraGravityws.set(0.0f, -5.0f, 0.0f); +} + +void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultVelocityDamper& velocityDamper, Components::Vehicle vehicleComponent) +{ + // Caution: setting negative damping values will add energy to system. + // Setting the value to 0 will not affect the angular velocity. + + // Damping the change of the chassis angular velocity when below m_collisionThreshold. + // This will affect turning radius and steering. + velocityDamper.m_normalSpinDamping = 0.0f; + + // Positive numbers dampen the rotation of the chassis and + // reduce the reaction of the chassis in a collision. + velocityDamper.m_collisionSpinDamping = 4.0f; + + // The threshold in m/s at which the algorithm switches from + // using the normalSpinDamping to the collisionSpinDamping. + velocityDamper.m_collisionThreshold = 1.0f; +} + +void VehicleSetup::setupWheelCollide(const hkpWorld* world, const hkpVehicleInstance& vehicle, hkpVehicleRayCastWheelCollide& wheelCollide) +{ + // Set the wheels to have the same collision filter info as the chassis. + wheelCollide.m_wheelCollisionFilterInfo = vehicle.getChassis()->getCollisionFilterInfo(); +} + diff --git a/src/Physics/VehicleSetup.h b/src/Physics/VehicleSetup.h new file mode 100644 index 0000000..b54adbd --- /dev/null +++ b/src/Physics/VehicleSetup.h @@ -0,0 +1,63 @@ +#ifndef Physics_Vehicle_h__ +#define Physics_Vehicle_h__ + +//#include "PrecompiledHeader.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +// Vehicle page 425 in documentation +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "World.h" +#include "Components/Vehicle.h" +#include "Components/Wheel.h" +#include "Components/Transform.h" + +class VehicleSetup +{ +public: + virtual void VehicleSetup::buildVehicle(World *world, const hkpWorld* physicsWorld, hkpVehicleInstance& vehicle, EntityID vehicleEntity, std::vector wheelEntities); + +public: + struct WheelData + { + Components::Wheel* WheelComponent; + Components::Transform* TransformComponent; + }; + + std::vector m_Wheels; + + virtual void setupVehicleData(const hkpWorld* world, hkpVehicleData& data); + virtual void setupComponent(const hkpVehicleData& data, hkpVehicleDefaultAnalogDriverInput& driverInput); + virtual void setupComponent(const hkpVehicleData& data, hkpVehicleDefaultEngine& engine, Components::Vehicle vehicleComponent); + virtual void setupComponent(const hkpVehicleData& data, hkpVehicleDefaultSteering& steering, Components::Vehicle vehicleComponent); + + virtual void setupComponent(const hkpVehicleData& data, hkpVehicleDefaultTransmission& transmission, Components::Vehicle vehicleComponent); + virtual void setupComponent(const hkpVehicleData& data, hkpVehicleDefaultBrake& brake, Components::Vehicle vehicleComponent ); + virtual void setupComponent(const hkpVehicleData& data, hkpVehicleDefaultSuspension& suspension, Components::Vehicle vehicleComponent); + virtual void setupComponent(const hkpVehicleData& data, hkpVehicleDefaultAerodynamics& aerodynamics, Components::Vehicle vehicleComponent ); + virtual void setupComponent(const hkpVehicleData& data, hkpVehicleDefaultVelocityDamper& velocityDamper, Components::Vehicle vehicleComponent); + + virtual void setupWheelCollide(const hkpWorld* world, const hkpVehicleInstance& vehicle, hkpVehicleRayCastWheelCollide& wheelCollide); +}; + +#endif // Physics_Vehicle_h__ diff --git a/src/Shaders/Fragment.glsl b/src/Shaders/Fragment.glsl index 11a43ab..1909e84 100755 --- a/src/Shaders/Fragment.glsl +++ b/src/Shaders/Fragment.glsl @@ -52,7 +52,7 @@ void main() //float bias = 0.001 * tan(acos(cosTheta)); // cosTheta is dot( n,l ), clamped between 0 and 1 //bias = clamp(bias, 0.0, 0.01); float visibility = 1.0; - if (Input.ShadowCoord.x >= 0.0 && Input.ShadowCoord.x <= 1.0 && Input.ShadowCoord.y >= 0.0 && Input.ShadowCoord.y <= 1.0) + /*if (Input.ShadowCoord.x >= 0.0 && Input.ShadowCoord.x <= 1.0 && Input.ShadowCoord.y >= 0.0 && Input.ShadowCoord.y <= 1.0) { float bias = 0.00005; vec4 shadowMapValue = texture(shadowMap, Input.ShadowCoord.xy); @@ -60,7 +60,7 @@ void main() { visibility = 0.3; } - } + }*/ vec3 totalLighting = La * Ka * visibility; diff --git a/src/Systems/PhysicsSystem.cpp b/src/Systems/PhysicsSystem.cpp index 6ec3b45..bdcf371 100644 --- a/src/Systems/PhysicsSystem.cpp +++ b/src/Systems/PhysicsSystem.cpp @@ -25,10 +25,9 @@ #include "PhysicsSystem.h" #include "World.h" - - Systems::PhysicsSystem::PhysicsSystem(World* world) : System(world) { + m_Accumulator = 0; { hkMemorySystem::FrameInfo finfo(500 * 1024); // Allocate 500KB of Physics solver buffer hkMemoryRouter* memoryRouter = hkMemoryInitUtil::initDefault(hkMallocAllocator::m_defaultMallocAllocator, finfo); @@ -41,7 +40,7 @@ Systems::PhysicsSystem::PhysicsSystem(World* world) : System(world) worldInfo.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_FIX_ENTITY; // just fix the entity if the object falls off too far // You must specify the size of the broad phase - objects should not be simulated outside this region - worldInfo.setBroadPhaseWorldSize(10000.0f); + 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. @@ -64,11 +63,39 @@ Systems::PhysicsSystem::PhysicsSystem(World* world) : System(world) void Systems::PhysicsSystem::RegisterComponents(ComponentFactory* cf) { cf->Register("Physics", []() { return new Components::Physics(); }); + cf->Register("Box", []() { return new Components::Box(); }); + cf->Register("Sphere", []() { return new Components::Sphere(); }); + cf->Register("Vehicle", []() { return new Components::Vehicle(); }); + cf->Register("Wheel", []() { return new Components::Wheel(); }); } void Systems::PhysicsSystem::Update(double dt) { - static const double timestep = 1 / 60.0; + for (auto pair : *m_World->GetEntities()) + { + EntityID entity = pair.first; + + if (m_RigidBodies.find(entity) == m_RigidBodies.end()) + continue; + + auto transformComponent = m_World->GetComponent(entity, "Transform"); + if (!transformComponent) + continue; + + + if(m_RigidBodies[entity]->isActive()) + { + hkVector4 position(transformComponent->Position.x, transformComponent->Position.y, transformComponent->Position.z); + hkQuaternion rotation(transformComponent->Orientation.x, transformComponent->Orientation.y, transformComponent->Orientation.z, transformComponent->Orientation.w); + m_RigidBodies[entity]->setPositionAndRotation(position, rotation); + } + + } + + + + + static const double timestep = 1 / 30.0; m_Accumulator += dt; while (m_Accumulator >= timestep) { @@ -85,21 +112,165 @@ 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()) + { + m_Vehicles[car]->getChassis()->activate(); + + hkVector4 hardPoint = m_Vehicles[car]->m_suspension->m_wheelParams[wheelComponent->ID].m_hardpointChassisSpace; + hkVector4 suspensionDirection = m_Vehicles[car]->m_suspension->m_wheelParams[wheelComponent->ID].m_directionChassisSpace; + hkReal suspensionLength = m_Vehicles[car]->m_wheelsInfo[wheelComponent->ID].m_currentSuspensionLength; + glm::vec3 position = glm::vec3(hardPoint(0) + (suspensionDirection(0) * suspensionLength), hardPoint(1) + (suspensionDirection(1) * suspensionLength), hardPoint(2) + (suspensionDirection(2) * suspensionLength)); + transformComponent->Position = position; + + hkQuaternion steeringOrientation = m_Vehicles[car]->m_wheelsInfo[wheelComponent->ID].m_steeringOrientationChassisSpace; + hkReal spinAngle = -m_Vehicles[car]->m_wheelsInfo[wheelComponent->ID].m_spinAngle; + glm::quat orientation = glm::quat(steeringOrientation(3), steeringOrientation(0), steeringOrientation(1), steeringOrientation(2)) * glm::angleAxis(spinAngle, glm::vec3(1, 0, 0)); + transformComponent->Orientation = orientation * wheelComponent->OriginalOrientation; + } } 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()) + { + if(m_RigidBodies[entity]->isActive()) + { + 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"); + auto inputComponent = m_World->GetComponent(entity, "Input"); + if (vehicleComponent && inputComponent) + { + hkpVehicleDriverInputAnalogStatus* deviceStatus = (hkpVehicleDriverInputAnalogStatus*)m_Vehicles[entity]->m_deviceStatus; + deviceStatus->m_positionY = inputComponent->KeyState[GLFW_KEY_UP] * -1 + inputComponent->KeyState[GLFW_KEY_DOWN] * 1; + deviceStatus->m_positionX = inputComponent->KeyState[GLFW_KEY_LEFT] * -1 + inputComponent->KeyState[GLFW_KEY_RIGHT] * 1; + deviceStatus->m_handbrakeButtonPressed = inputComponent->KeyState[GLFW_KEY_RIGHT_CONTROL]; + } +} + +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(); + wheelComponent->OriginalOrientation = transformComponent->Orientation; + 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) { @@ -124,17 +295,32 @@ void Systems::PhysicsSystem::SetUpPhysicsState(EntityID entity, EntityID parent) { shape = new hkpSphereShape(sphereComponent->Radius); rigidBodyInfo.m_shape = shape; - rigidBodyInfo.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA; + + 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) { - shape = new hkpBoxShape(hkVector4(boxComponent->Width, boxComponent->Height, boxComponent->Depth)); + hkReal thickness = 0.05; + shape = new hkpBoxShape(hkVector4(boxComponent->Width - thickness, boxComponent->Height - thickness, boxComponent->Depth - thickness)); rigidBodyInfo.m_shape = shape; - rigidBodyInfo.m_motionType = hkpMotion::MOTION_FIXED; - hkReal thickness = 0.1; + 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 @@ -149,13 +335,41 @@ void Systems::PhysicsSystem::SetUpPhysicsState(EntityID entity, EntityID parent) // Create RigidBody hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo); - shape->removeReference(); + - m_PhysicsWorld->addEntity(rigidBody); - m_RigidBodies[entity] = rigidBody; - rigidBody->removeReference(); + auto vehicleComponent = m_World->GetComponent(entity, "Vehicle"); + if (vehicleComponent && m_Vehicles.find(entity) == m_Vehicles.end()) + { + VehicleSetup vehicleSetup; + // Create the basic vehicle. + m_Vehicles[entity] = new hkpVehicleInstance(rigidBody); + vehicleSetup.buildVehicle(m_PhysicsWorld, *m_Vehicles[entity]); + // 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 + + shape->removeReference(); + rigidBody->removeReference(); + } + else + { + m_PhysicsWorld->addEntity(rigidBody); + m_RigidBodies[entity] = rigidBody; + shape->removeReference(); + rigidBody->removeReference(); + } } +*/ + + + void Systems::PhysicsSystem::TearDownPhysicsState(EntityID entity, EntityID parent) { @@ -201,5 +415,6 @@ 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.cpp.orig b/src/Systems/PhysicsSystem.cpp.orig new file mode 100644 index 0000000..1f3913f --- /dev/null +++ b/src/Systems/PhysicsSystem.cpp.orig @@ -0,0 +1,426 @@ +#include "PrecompiledHeader.h" + +// We’re not using anything product specific yet. We undef these so we don’t get the usual +// product initialization for the products. +#undef HK_FEATURE_PRODUCT_AI +#undef HK_FEATURE_PRODUCT_ANIMATION +#undef HK_FEATURE_PRODUCT_CLOTH +#undef HK_FEATURE_PRODUCT_DESTRUCTION_2012 +#undef HK_FEATURE_PRODUCT_DESTRUCTION +#undef HK_FEATURE_PRODUCT_BEHAVIOR +#undef HK_FEATURE_PRODUCT_PHYSICS_2012 +//#undef HK_FEATURE_PRODUCT_PHYSICS +// Also we’re not using any serialization/versioning so we don’t need any of these. +#define HK_EXCLUDE_FEATURE_SerializeDeprecatedPre700 +#define HK_EXCLUDE_FEATURE_RegisterVersionPatches +#define HK_EXCLUDE_FEATURE_RegisterReflectedClasses +#define HK_EXCLUDE_FEATURE_MemoryTracker +#define HK_CLASSES_FILE "Common/Serialize/classlist/hkClasses.h" +#include "Common/Serialize/Util/hkBuiltinTypeRegistry.cxx" +#define HK_COMPAT_FILE "Common/Compat/hkCompatVersions.h" +// This include generates an initialization function based on the products +// and the excluded features. +#include +#include +#include "PhysicsSystem.h" +#include "World.h" + + + +Systems::PhysicsSystem::PhysicsSystem(World* world) : System(world) +{ + m_Accumulator = 0; + { + 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); + worldInfo.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_FIX_ENTITY; // just fix the entity if the object falls off too far + + // You must specify the size of the broad phase - objects should not be simulated outside this region + worldInfo.setBroadPhaseWorldSize(10000.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()); + + // + // Initialize the visual debugger so we can connect remotely to the simulation + // The context must exist beyond the use of the VDB instance, and you can make + // whatever contexts you like for your own viewer types. + // + hkpPhysicsContext* context = new hkpPhysicsContext; + hkpPhysicsContext::registerAllPhysicsProcesses(); // all the physics viewers + context->addWorld(m_PhysicsWorld); // add the physics world so the viewers can see it + SetupVisualDebugger(context); + + //SetupPhysics(m_PhysicsWorld); +} + +void Systems::PhysicsSystem::RegisterComponents(ComponentFactory* cf) +{ + cf->Register("Physics", []() { return new Components::Physics(); }); +} + +void Systems::PhysicsSystem::Update(double dt) +{ +<<<<<<< HEAD + static const double timestep = 1 / 60.0; +======= + for (auto pair : *m_World->GetEntities()) + { + EntityID entity = pair.first; + + if (m_RigidBodies.find(entity) == m_RigidBodies.end()) + continue; + + auto transformComponent = m_World->GetComponent(entity, "Transform"); + if (!transformComponent) + continue; + + + if(m_RigidBodies[entity]->isActive()) + { + hkVector4 position(transformComponent->Position.x, transformComponent->Position.y, transformComponent->Position.z); + hkQuaternion rotation(transformComponent->Orientation.x, transformComponent->Orientation.y, transformComponent->Orientation.z, transformComponent->Orientation.w); + m_RigidBodies[entity]->setPositionAndRotation(position, rotation); + } + + } + + + + + static const double timestep = 1 / 30.0; +>>>>>>> havok + m_Accumulator += dt; + while (m_Accumulator >= timestep) + { + m_PhysicsWorld->stepDeltaTime(timestep); + m_Accumulator -= timestep; + } + + // Step the visual debugger + StepVisualDebugger(); +} + +void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) +{ + auto transformComponent = m_World->GetComponent(entity, "Transform"); + if (!transformComponent) + return; + + auto wheelComponent = m_World->GetComponent(entity, "Wheel"); + if (wheelComponent) + { + EntityID car = m_World->GetEntityParent(entity); + if(m_Vehicles.find(car) != m_Vehicles.end()) + { + m_Vehicles[car]->getChassis()->activate(); + + hkVector4 hardPoint = m_Vehicles[car]->m_suspension->m_wheelParams[wheelComponent->ID].m_hardpointChassisSpace; + hkVector4 suspensionDirection = m_Vehicles[car]->m_suspension->m_wheelParams[wheelComponent->ID].m_directionChassisSpace; + hkReal suspensionLength = m_Vehicles[car]->m_wheelsInfo[wheelComponent->ID].m_currentSuspensionLength; + glm::vec3 position = glm::vec3(hardPoint(0) + (suspensionDirection(0) * suspensionLength), hardPoint(1) + (suspensionDirection(1) * suspensionLength), hardPoint(2) + (suspensionDirection(2) * suspensionLength)); + transformComponent->Position = position; + + hkQuaternion steeringOrientation = m_Vehicles[car]->m_wheelsInfo[wheelComponent->ID].m_steeringOrientationChassisSpace; + hkReal spinAngle = -m_Vehicles[car]->m_wheelsInfo[wheelComponent->ID].m_spinAngle; + glm::quat orientation = glm::quat(steeringOrientation(3), steeringOrientation(0), steeringOrientation(1), steeringOrientation(2)) * glm::angleAxis(spinAngle, glm::vec3(1, 0, 0)); + transformComponent->Orientation = orientation * wheelComponent->OriginalOrientation; + } + } + else + { + if(m_Vehicles.find(entity) != m_Vehicles.end()) + { + if(m_RigidBodies[entity]->isActive()) + { + 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"); + auto inputComponent = m_World->GetComponent(entity, "Input"); + if (vehicleComponent && inputComponent) + { + hkpVehicleDriverInputAnalogStatus* deviceStatus = (hkpVehicleDriverInputAnalogStatus*)m_Vehicles[entity]->m_deviceStatus; + deviceStatus->m_positionY = inputComponent->KeyState[GLFW_KEY_UP] * -1 + inputComponent->KeyState[GLFW_KEY_DOWN] * 1; + deviceStatus->m_positionX = inputComponent->KeyState[GLFW_KEY_LEFT] * -1 + inputComponent->KeyState[GLFW_KEY_RIGHT] * 1; + deviceStatus->m_handbrakeButtonPressed = inputComponent->KeyState[GLFW_KEY_RIGHT_CONTROL]; + } +} + +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(); + wheelComponent->OriginalOrientation = transformComponent->Orientation; + 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"); + 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; + + 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()) + { + VehicleSetup vehicleSetup; + + // Create the basic vehicle. + m_Vehicles[entity] = new hkpVehicleInstance(rigidBody); + vehicleSetup.buildVehicle(m_PhysicsWorld, *m_Vehicles[entity]); + // 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 + + shape->removeReference(); + rigidBody->removeReference(); + } + else + { + m_PhysicsWorld->addEntity(rigidBody); + m_RigidBodies[entity] = rigidBody; + shape->removeReference(); + rigidBody->removeReference(); + } +} +*/ + + + + +void Systems::PhysicsSystem::TearDownPhysicsState(EntityID entity, EntityID parent) +{ + +} + +void Systems::PhysicsSystem::OnComponentCreated(std::string type, std::shared_ptr component) +{ + +} + +void Systems::PhysicsSystem::OnComponentRemoved(std::string type, Component* component) +{ + +} + + +void Systems::PhysicsSystem::SetupVisualDebugger(hkpPhysicsContext* worlds) +{ + // Setup the visual debugger + hkArray contexts; + contexts.pushBack(worlds); + + m_VisualDebugger = new hkVisualDebugger(contexts); + m_VisualDebugger->serve(); + + // Allocate memory for internal profiling information + // You can discard this if you do not want Havok profiling information + hkMonitorStream& stream = hkMonitorStream::getInstance(); + stream.resize(500 * 1024); // 500K for timer info + stream.reset(); + +} + +void Systems::PhysicsSystem::StepVisualDebugger() +{ + // Step the debugger + m_VisualDebugger->step(); + + // Reset internal profiling info for next frame + hkMonitorStream::getInstance().reset(); +} + +void HK_CALL Systems::PhysicsSystem::HavokErrorReport(const char* msg, void*) +{ + LOG_INFO("%s", msg); +} +<<<<<<< HEAD +======= + + +>>>>>>> havok diff --git a/src/Systems/PhysicsSystem.h b/src/Systems/PhysicsSystem.h index 626bbcd..f5ca539 100644 --- a/src/Systems/PhysicsSystem.h +++ b/src/Systems/PhysicsSystem.h @@ -1,18 +1,15 @@ #ifndef PhysicsSystem_h__ #define PhysicsSystem_h__ - - - - #include "System.h" #include "Components/Transform.h" #include "Components/Physics.h" #include "Components/Sphere.h" #include "Components/Box.h" +#include "Components/Vehicle.h" +#include "Components/Input.h" // Math and base include - #include #include #include @@ -29,8 +26,6 @@ #include #include - - #include #include #include @@ -39,6 +34,8 @@ #include #include +#include "Physics/VehicleSetup.h" + #include namespace Systems { @@ -53,10 +50,9 @@ 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; hkpWorld* m_PhysicsWorld; @@ -70,7 +66,10 @@ private: void SetupPhysics(hkpWorld* physicsWorld); std::unordered_map m_RigidBodies; + std::unordered_map m_Vehicles; + std::vector m_Wheels; + hkpVehicleInstance* Systems::PhysicsSystem::createVehicle(VehicleSetup& vehicleSetup, hkpRigidBody* chassis); }; } diff --git a/src/Systems/PhysicsSystem.h.orig b/src/Systems/PhysicsSystem.h.orig new file mode 100644 index 0000000..5e00aa1 --- /dev/null +++ b/src/Systems/PhysicsSystem.h.orig @@ -0,0 +1,91 @@ +#ifndef PhysicsSystem_h__ +#define PhysicsSystem_h__ + + + + + +#include "System.h" +#include "Components/Transform.h" +#include "Components/Physics.h" +#include "Components/Sphere.h" +#include "Components/Box.h" +#include "Components/Vehicle.h" +#include "Components/Input.h" + +// Math and base include + +#include +#include +#include +#include +#include +#include +#include +#include + +// Dynamics includes +#include +#include +#include +#include +#include + + + +#include +#include +#include + +// Visual Debugger includes +#include +#include + + + +#include "Physics/VehicleSetup.h" + + +#include +namespace Systems +{ + +class PhysicsSystem : public System +{ +public: + PhysicsSystem(World* world); + void RegisterComponents(ComponentFactory* cf) override; + + 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; + void OnEntityCommit(EntityID entity) override; + +private: +<<<<<<< HEAD + +======= +>>>>>>> havok + double m_Accumulator; + hkpWorld* m_PhysicsWorld; + + void SetUpPhysicsState(EntityID entity, EntityID parent); + void TearDownPhysicsState(EntityID entity, EntityID parent); + + hkVisualDebugger* m_VisualDebugger; + void SetupVisualDebugger(hkpPhysicsContext* worlds); + void StepVisualDebugger(); + static void HK_CALL HavokErrorReport(const char* msg, void*); + void SetupPhysics(hkpWorld* physicsWorld); + + std::unordered_map m_RigidBodies; + std::unordered_map m_Vehicles; + std::vector m_Wheels; + + hkpVehicleInstance* Systems::PhysicsSystem::createVehicle(VehicleSetup& vehicleSetup, hkpRigidBody* chassis); +}; + +} + +#endif // PhysicsSystem_h__ diff --git a/src/Systems/RenderSystem.cpp b/src/Systems/RenderSystem.cpp index d8c3c19..fe254f4 100755 --- a/src/Systems/RenderSystem.cpp +++ b/src/Systems/RenderSystem.cpp @@ -47,8 +47,8 @@ void Systems::RenderSystem::UpdateEntity(double dt, EntityID entity, EntityID pa auto cameraComponent = m_World->GetComponent(entity, "Camera"); if (cameraComponent != nullptr) { - m_Renderer->GetCamera()->Position(transformComponent->Position); - m_Renderer->GetCamera()->Orientation(transformComponent->Orientation); + m_Renderer->GetCamera()->Position(m_TransformSystem->AbsolutePosition(entity)); + m_Renderer->GetCamera()->Orientation(m_TransformSystem->AbsoluteOrientation(entity)); m_Renderer->GetCamera()->FOV(cameraComponent->FOV); m_Renderer->GetCamera()->NearClip(cameraComponent->NearClip); diff --git a/vs11/Returngeance/Returngeance.vcxproj b/vs11/Returngeance/Returngeance.vcxproj index 4726981..65ee872 100755 --- a/vs11/Returngeance/Returngeance.vcxproj +++ b/vs11/Returngeance/Returngeance.vcxproj @@ -65,7 +65,7 @@ true - OpenAL32.lib;opengl32.lib;glu32.lib;SOIL.lib;glew32d.lib;glfw3.lib;hkBase.lib;hkVisualize.lib;hkInternal.lib;hkSerialize.lib;hkGeometryUtilities.lib;hkcdInternal.lib;hkcdCollide.lib;hkpCollide.lib;hkpConstraint.lib;hkpConstraintSolver.lib;hkpDynamics.lib;hkpInternal.lib;hkpUtilities.lib;hkSceneData.lib;%(AdditionalDependencies) + OpenAL32.lib;opengl32.lib;glu32.lib;SOIL.lib;glew32d.lib;glfw3.lib;hkBase.lib;hkVisualize.lib;hkInternal.lib;hkSerialize.lib;hkGeometryUtilities.lib;hkcdInternal.lib;hkcdCollide.lib;hkpCollide.lib;hkpConstraint.lib;hkpConstraintSolver.lib;hkpDynamics.lib;hkpInternal.lib;hkpUtilities.lib;hkSceneData.lib;hkpVehicle.lib;%(AdditionalDependencies) /ignore:4221 @@ -89,7 +89,7 @@ true true true - OpenAL32.lib;opengl32.lib;glu32.lib;SOIL.lib;glew32.lib;glfw3.lib;hkaAnimation.lib;hkaInternal.lib;hkaPhysics2012Bridge.lib;hkBase.lib;hkcdCollide.lib;hkcdInternal.lib;hkCompat.lib;hkgBridge.lib;hkgCommon.lib;hkgDx11.lib;hkgDx9s.lib;hkGeometryUtilities.lib;hkgOglES.lib;hkgOglES2.lib;hkgOgls.lib;hkgSoundCommon.lib;hkgSoundXAudio2.lib;hkInternal.lib;hkpCollide.lib;hkpConstraint.lib;hkpConstraintSolver.lib;hkpDynamics.lib;hkpInternal.lib;hkpUtilities.lib;hkpVehicle.lib;hkSceneData.lib;hkSerialize.lib;hkVisualize.lib;%(AdditionalDependencies) + OpenAL32.lib;opengl32.lib;glu32.lib;SOIL.lib;glew32.lib;glfw3.lib;hkBase.lib;hkVisualize.lib;hkInternal.lib;hkSerialize.lib;hkGeometryUtilities.lib;hkcdInternal.lib;hkcdCollide.lib;hkpCollide.lib;hkpConstraint.lib;hkpConstraintSolver.lib;hkpDynamics.lib;hkpInternal.lib;hkpUtilities.lib;hkSceneData.lib;hkpVehicle.lib;%(AdditionalDependencies) @@ -100,6 +100,7 @@ + @@ -134,6 +135,8 @@ + + @@ -141,6 +144,7 @@ + diff --git a/vs11/Returngeance/Returngeance.vcxproj.filters b/vs11/Returngeance/Returngeance.vcxproj.filters index 672e8dd..b8f30e6 100755 --- a/vs11/Returngeance/Returngeance.vcxproj.filters +++ b/vs11/Returngeance/Returngeance.vcxproj.filters @@ -50,6 +50,7 @@ + @@ -212,8 +213,19 @@ Audio - - + + + Physics\Components + + + Physics\Components + + + Physics\Components + + + Physics\Components +