diff --git a/assets b/assets index 672e8a2..8b6c48b 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 672e8a2b11ecaafc95a5b0286b5ec310c62438ad +Subproject commit 8b6c48b26b3bbc10f5e66c1f59fec6ca935f641b diff --git a/src/Components/Box.h b/src/Components/BoxShape.h similarity index 66% rename from src/Components/Box.h rename to src/Components/BoxShape.h index 3fe3687..a8aed66 100644 --- a/src/Components/Box.h +++ b/src/Components/BoxShape.h @@ -6,16 +6,16 @@ namespace Components { -struct Box : Component +struct BoxShape : Component { - Box() + BoxShape() : Width(1.f), Height(1.f), Depth(1.f){ } float Width; float Height; float Depth; - virtual Box* Clone() const override { return new Box(*this); } + virtual BoxShape* Clone() const override { return new BoxShape(*this); } }; } diff --git a/src/Components/ExtendedMeshShape.h b/src/Components/ExtendedMeshShape.h new file mode 100644 index 0000000..e69de29 diff --git a/src/Components/HingeConstraint.h b/src/Components/HingeConstraint.h new file mode 100644 index 0000000..367d73a --- /dev/null +++ b/src/Components/HingeConstraint.h @@ -0,0 +1,20 @@ +#ifndef Components_HingeConstraint_h__ +#define Components_HingeConstraint_h__ + +#include "Component.h" + +namespace Components +{ + + struct HingeConstraint : Component + { + EntityID LinkedEntity; + glm::vec3 Pivot; + glm::vec3 Axis; + + virtual HingeConstraint* Clone() const override { return new HingeConstraint(*this); } + }; + +} + +#endif // Components_HingeConstraint_h__ diff --git a/src/Components/MeshShape.h b/src/Components/MeshShape.h new file mode 100644 index 0000000..81ea9c0 --- /dev/null +++ b/src/Components/MeshShape.h @@ -0,0 +1,19 @@ +#ifndef Components_MeshShape_h__ +#define Components_MeshShape_h__ + +#include + +#include "Component.h" + +namespace Components +{ + +struct MeshShape : Component +{ + std::string ResourceName; + + virtual MeshShape* Clone() const override { return new MeshShape(*this); } +}; + +} +#endif // !Components_MeshShape_h__ \ No newline at end of file diff --git a/src/Components/Sphere.h b/src/Components/SphereShape.h similarity index 59% rename from src/Components/Sphere.h rename to src/Components/SphereShape.h index f92e418..20ab74d 100644 --- a/src/Components/Sphere.h +++ b/src/Components/SphereShape.h @@ -6,14 +6,14 @@ namespace Components { -struct Sphere : Component +struct SphereShape : Component { - Sphere() + SphereShape() : Radius(1.f){ } float Radius; - virtual Sphere* Clone() const override { return new Sphere(*this); } + virtual SphereShape* Clone() const override { return new SphereShape(*this); } }; } diff --git a/src/Components/TankSteering.h b/src/Components/TankSteering.h new file mode 100644 index 0000000..c9184b3 --- /dev/null +++ b/src/Components/TankSteering.h @@ -0,0 +1,14 @@ +#ifndef TankSteering_h__ +#define TankSteering_h__ + +#include "Component.h" + +namespace Components +{ + struct TankSteering : Component + { + TankSteering* Clone() const override { return new TankSteering(*this); } + }; +} + +#endif // TankSteering_h__ \ No newline at end of file diff --git a/src/Components/Vehicle.h b/src/Components/Vehicle.h index 1a1219e..69adce3 100644 --- a/src/Components/Vehicle.h +++ b/src/Components/Vehicle.h @@ -10,7 +10,8 @@ namespace Components struct Vehicle : Component { Vehicle() - : MaxTorque(500.0f), MinRPM(1000.0f), OptimalRPM(5500.0f), MaxRPM(7500.0f), MaxSteeringAngle(35), TopSpeed(50.0f) { } + : MaxTorque(1000.0f), MinRPM(1000.0f), OptimalRPM(3000.0f), MaxRPM(4000.0f), MaxSteeringAngle(35), TopSpeed(130.0f), + MaxSpeedFullSteeringAngle(40.0f){ } float MaxTorque; float MinRPM; @@ -18,8 +19,10 @@ struct Vehicle : Component float MaxRPM; // Degrees float MaxSteeringAngle; + //TopSpeed not working fully yet float TopSpeed; - + float MaxSpeedFullSteeringAngle; + Vehicle* Clone() const override { return new Vehicle(*this); } }; diff --git a/src/Components/Wheel.h b/src/Components/Wheel.h index 2c88490..be3638b 100644 --- a/src/Components/Wheel.h +++ b/src/Components/Wheel.h @@ -14,7 +14,7 @@ struct Wheel : Component 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) { } + MaxBreakingTorque(1500.0f), ConnectedToHandbrake(false), SuspensionStrength(50.0f), TorqueRatio(0.25f) { } // The Hardpoint MUST be positioned INSIDE the chassis. glm::vec3 Hardpoint; @@ -30,6 +30,8 @@ struct Wheel : Component float SlipAngle; float MaxBreakingTorque; bool ConnectedToHandbrake; + // The wheels total TorqueRatio must be equal to 1 + float TorqueRatio; private: int ID; diff --git a/src/Components/WheelPair.h b/src/Components/WheelPair.h new file mode 100644 index 0000000..4e74a82 --- /dev/null +++ b/src/Components/WheelPair.h @@ -0,0 +1,18 @@ +#ifndef Components_WheelPair_h__ +#define Components_WheelPair_h__ + +#include "Component.h" + +namespace Components +{ + + struct WheelPair : Component + { + // Flag for pair wheels + + virtual WheelPair* Clone() const override { return new WheelPair(*this); } + }; + +} + +#endif // Components_WheelPair_h__ diff --git a/src/Events/TankSteer.h b/src/Events/TankSteer.h new file mode 100644 index 0000000..3ee6dc9 --- /dev/null +++ b/src/Events/TankSteer.h @@ -0,0 +1,19 @@ +#ifndef Events_TankSteer_h__ +#define Events_TankSteer_h__ +#include "Entity.h" +#include "EventBroker.h" + +namespace Events +{ + +struct TankSteer : Event +{ + EntityID Entity; + float PositionX; + float PositionY; + bool Handbrake; +}; + +} + +#endif // Events_TankSteer_h__ \ No newline at end of file diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 18ab5a2..979376b 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -12,7 +12,9 @@ void GameWorld::Initialize() BindKey(GLFW_KEY_S, "+backward"); BindKey(GLFW_KEY_A, "+left"); BindKey(GLFW_KEY_D, "+right"); - BindKey(GLFW_KEY_SPACE, "+up"); + BindKey(GLFW_KEY_SPACE, "+handbrake"); + + BindKey(GLFW_KEY_Q, "+up"); BindKey(GLFW_KEY_LEFT_CONTROL, "+down"); BindKey(GLFW_KEY_LEFT_ALT, "+slow"); BindKey(GLFW_KEY_LEFT_SHIFT, "+fast"); @@ -20,6 +22,12 @@ void GameWorld::Initialize() BindMouseButton(GLFW_MOUSE_BUTTON_2, "+attack2"); BindMouseButton(GLFW_MOUSE_BUTTON_3, "+attack3"); + + BindKey(GLFW_KEY_UP, "+cam_forward"); + BindKey(GLFW_KEY_DOWN, "+cam_backward"); + BindKey(GLFW_KEY_LEFT, "+cam_right"); + BindKey(GLFW_KEY_RIGHT, "+cam_left"); + RegisterComponents(); { @@ -38,63 +46,107 @@ void GameWorld::Initialize() { 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->Position = glm::vec3(0, 0, 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; - + //model->ModelFile = "Models/TestScene/testScene.obj"; + model->ModelFile = "Models/Placeholders/Terrain/Terrain2.obj"; + auto physics = AddComponent(ground, "Physics"); physics->Mass = 10; physics->Static = true; + + auto groundshape = CreateEntity(ground); + auto transformshape = AddComponent(groundshape, "Transform"); + auto meshShape = AddComponent(groundshape, "MeshShape"); + meshShape->ResourceName = "Models/Placeholders/Terrain/Terrain2.obj"; + //meshShape->ResourceName = "Models/TestScene/testScene.obj"; + + + CommitEntity(groundshape); CommitEntity(ground); } - { + auto camera = CreateEntity(); + auto transform = AddComponent(camera, "Transform"); + transform->Position.z = 20.f; + transform->Position.y = 10.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 jeep = CreateEntity(); auto transform = AddComponent(jeep, "Transform"); - transform->Position = glm::vec3(0, 2, 0); - + transform->Position = glm::vec3(0, 5, 0); + transform->Orientation = glm::angleAxis(glm::pi()/2, glm::vec3(0, 1, 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; + physics->Mass = 1800; + physics->Static = false; auto vehicle = AddComponent(jeep, "Vehicle"); - AddComponent(jeep, "Input"); + { + auto shape = CreateEntity(jeep); + auto transform = AddComponent(shape, "Transform"); + auto meshShape = AddComponent(shape, "MeshShape"); + meshShape->ResourceName = "Models/Jeep/Chassi/ChassiCollision.obj"; + CommitEntity(shape); + + // auto box = AddComponent(jeep, "Box"); + // box->Width = 1.487f; + // box->Height = 0.727f; + // box->Depth = 2.594f; + + } + { auto chassis = CreateEntity(jeep); auto transform = AddComponent(chassis, "Transform"); - transform->Position = glm::vec3(0, -0.6577f, 0); + transform->Position = glm::vec3(0, 0, 0); // 0.6577f auto model = AddComponent(chassis, "Model"); - model->ModelFile = "Models/JeepV2/Chassi/chassi.OBJ"; - + model->ModelFile = "Models/Jeep/Chassi/chassi.obj"; } + { + auto lightentity = CreateEntity(jeep); + auto transform = AddComponent(lightentity, "Transform"); + transform->Position = glm::vec3(0, 15, 0); + auto light = AddComponent(lightentity, "PointLight"); + light->Diffuse = glm::vec3(128.f/255.f, 172.f/255.f, 242.f/255.f); + light->Specular = glm::vec3(1.f); + light->constantAttenuation = 0.3f; + light->linearAttenuation = 0.003f; + light->quadraticAttenuation = 0.002f; + } + + + //Create wheels + float wheelOffset = 0.4f; + float springLength = 0.3f; + float suspensionStrength = 35.f; { auto wheel = CreateEntity(jeep); auto transform = AddComponent(wheel, "Transform"); - transform->Position = glm::vec3(1.4f, 0.5546f - 0.6577f - 0.2, -0.9242f); + transform->Position = glm::vec3(1.9f, 0.5546f - wheelOffset, -0.9242f); transform->Scale = glm::vec3(1.0f); auto model = AddComponent(wheel, "Model"); - model->ModelFile = "Models/JeepV2/WheelFront/wheelFront.obj"; + model->ModelFile = "Models/Jeep/WheelFront/wheelFront.obj"; auto Wheel = AddComponent(wheel, "Wheel"); - Wheel->Hardpoint = transform->Position + glm::vec3(0.f, 1.f, 0.f); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, springLength, 0.f); Wheel->AxleID = 0; Wheel->Mass = 50; Wheel->Radius = 0.837f; Wheel->Steering = true; - Wheel->SuspensionStrength = 40.f; - Wheel->Friction = 4.0f; + Wheel->SuspensionStrength = suspensionStrength; + Wheel->Friction = 4.f; Wheel->ConnectedToHandbrake = true; CommitEntity(wheel); } @@ -102,19 +154,19 @@ void GameWorld::Initialize() { auto wheel = CreateEntity(jeep); auto transform = AddComponent(wheel, "Transform"); - transform->Position = glm::vec3(-1.4f, 0.5546f - 0.6577f - 0.2, -0.9242f); + transform->Position = glm::vec3(-1.9f, 0.5546f - wheelOffset, -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"; + model->ModelFile = "Models/Jeep/WheelFront/wheelFront.obj"; auto Wheel = AddComponent(wheel, "Wheel"); - Wheel->Hardpoint = transform->Position + glm::vec3(0.f, 1.f, 0.f); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, springLength, 0.f); Wheel->AxleID = 0; Wheel->Mass = 50; Wheel->Radius = 0.837f; Wheel->Steering = true; - Wheel->SuspensionStrength = 40.f; - Wheel->Friction = 4.0f; + Wheel->SuspensionStrength = suspensionStrength; + Wheel->Friction = 4.f; Wheel->ConnectedToHandbrake = true; CommitEntity(wheel); } @@ -122,145 +174,360 @@ void GameWorld::Initialize() { auto wheel = CreateEntity(jeep); auto transform = AddComponent(wheel, "Transform"); - transform->Position = glm::vec3(0.2726f, 0.2805f - 0.6577f, 1.9307f); + transform->Position = glm::vec3(0.2726f, 0.2805f - wheelOffset, 1.9307f); auto model = AddComponent(wheel, "Model"); - model->ModelFile = "Models/JeepV2/WheelBack/wheelBack.obj"; + model->ModelFile = "Models/Jeep/WheelBack/wheelBack.obj"; auto Wheel = AddComponent(wheel, "Wheel"); - Wheel->Hardpoint = transform->Position + glm::vec3(0.f, 1.f, 0.f); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, springLength, 0.f); Wheel->AxleID = 1; - Wheel->Mass = 10; + Wheel->Mass = 50; Wheel->Radius = 0.737f; Wheel->Steering = false; - Wheel->SuspensionStrength = 50.f; - Wheel->Friction = 4.0f; + Wheel->SuspensionStrength = suspensionStrength; + Wheel->Friction = 4.f; + 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); + transform->Position = glm::vec3(-0.2726f, 0.2805f - wheelOffset, 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"; + model->ModelFile = "Models/Jeep/WheelBack/wheelBack.obj"; auto Wheel = AddComponent(wheel, "Wheel"); - Wheel->Hardpoint = transform->Position + glm::vec3(0.f, 1.f, 0.f); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, springLength, 0.f); Wheel->AxleID = 1; - Wheel->Mass = 10; + Wheel->Mass = 50; Wheel->Radius = 0.737f; Wheel->Steering = false; - Wheel->SuspensionStrength = 50.f; - Wheel->Friction = 4.0f; + Wheel->SuspensionStrength = suspensionStrength; + Wheel->Friction = 4.f; + Wheel->ConnectedToHandbrake = true; CommitEntity(wheel); } + CommitEntity(jeep); + }*/ + + + { + auto tank = CreateEntity(); + auto transform = AddComponent(tank, "Transform"); + transform->Position = glm::vec3(0, 5, 0); + transform->Orientation = glm::angleAxis(glm::pi()/2, glm::vec3(0, 1, 0)); + auto physics = AddComponent(tank, "Physics"); + physics->Mass = 45000; + physics->Static = false; + auto vehicle = AddComponent(tank, "Vehicle"); + vehicle->MaxTorque = 5200.f; + AddComponent(tank, "TankSteering"); + AddComponent(tank, "Input"); + + { + auto shape = CreateEntity(tank); + auto transform = AddComponent(shape, "Transform"); + auto meshShape = AddComponent(shape, "MeshShape"); + meshShape->ResourceName = "Models/Tank/Fix/ChassiCollision.obj"; + CommitEntity(shape); + + // auto box = AddComponent(jeep, "Box"); + // box->Width = 1.487f; + // box->Height = 0.727f; + // box->Depth = 2.594f; + + } + + { + auto chassis = CreateEntity(tank); + auto transform = AddComponent(chassis, "Transform"); + transform->Position = glm::vec3(0, 0, 0); // 0.6577f + auto model = AddComponent(chassis, "Model"); + model->ModelFile = "Models/Tank/Fix/Chassi.obj"; + } + { + auto top = CreateEntity(tank); + auto transform = AddComponent(top, "Transform"); + transform->Position = glm::vec3(0, 1.2, 1.95); // 0.6577f + auto model = AddComponent(top, "Model"); + model->ModelFile = "Models/Tank/Fix/Top.obj"; + + { + auto top = CreateEntity(tank); + auto transform = AddComponent(top, "Transform"); + transform->Position = glm::vec3(0, 1, 0.5); // 0.6577f + auto model = AddComponent(top, "Model"); + model->ModelFile = "Models/Tank/Fix/Barrel.obj"; + } + } + + { + auto lightentity = CreateEntity(tank); + auto transform = AddComponent(lightentity, "Transform"); + transform->Position = glm::vec3(0, 15, 0); + auto light = AddComponent(lightentity, "PointLight"); + light->Diffuse = glm::vec3(128.f/255.f, 172.f/255.f, 242.f/255.f); + light->Specular = glm::vec3(1.f); + light->constantAttenuation = 0.3f; + light->linearAttenuation = 0.003f; + light->quadraticAttenuation = 0.002f; + } + +// auto wheelpair = CreateEntity(tank); +// SetProperty(wheelpair, "Name", "WheelPair"); +// AddComponent(wheelpair, "WheelPairThingy"); + + //Create wheels + float wheelOffset = 0.4f; + float springLength = 0.3f; + float suspensionStrength = 25.f; + + { + auto wheel = CreateEntity(tank); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(1.88f, -0.83f - wheelOffset, -2.6f); + transform->Orientation = glm::angleAxis(glm::pi(), glm::vec3(0, 1, 0)); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/Tank/Fix/WheelPhysics.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, springLength, 0.f); + Wheel->AxleID = 0; + Wheel->Mass = 2000; + Wheel->Radius = 0.6f; + Wheel->Steering = true; + Wheel->SuspensionStrength = suspensionStrength; + Wheel->Friction = 3.f; + Wheel->ConnectedToHandbrake = true; + Wheel->TorqueRatio = 0.125f; + CommitEntity(wheel); + } + { + auto wheel = CreateEntity(tank); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(1.88f, -0.83f - wheelOffset, -0.83f); + transform->Orientation = glm::angleAxis(glm::pi(), glm::vec3(0, 1, 0)); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/Tank/Fix/WheelPhysics.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, springLength, 0.f); + Wheel->AxleID = 0; + Wheel->Mass = 2000; + Wheel->Radius = 0.6f; + Wheel->Steering = false; + Wheel->SuspensionStrength = suspensionStrength; + Wheel->Friction = 3.f; + Wheel->ConnectedToHandbrake = true; + Wheel->TorqueRatio = 0.125f; + CommitEntity(wheel); + } + + { + auto wheel = CreateEntity(tank); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(-1.88f, -0.83f - wheelOffset, -2.6f); + transform->Orientation = glm::angleAxis(glm::pi(), glm::vec3(0, 1, 0)); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/Tank/Fix/WheelPhysics.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, springLength, 0.f); + Wheel->AxleID = 0; + Wheel->Mass = 2000; + Wheel->Radius = 0.6f; + Wheel->Steering = true; + Wheel->SuspensionStrength = suspensionStrength; + Wheel->Friction = 3.f; + Wheel->ConnectedToHandbrake = true; + Wheel->TorqueRatio = 0.125f; + CommitEntity(wheel); + } + { + auto wheel = CreateEntity(tank); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(-1.88f, -0.83f - wheelOffset, -0.83f); + transform->Orientation = glm::angleAxis(glm::pi(), glm::vec3(0, 1, 0)); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/Tank/Fix/WheelPhysics.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, springLength, 0.f); + Wheel->AxleID = 0; + Wheel->Mass = 2000; + Wheel->Radius = 0.6f; + Wheel->Steering = false; + Wheel->SuspensionStrength = suspensionStrength; + Wheel->Friction = 3.f; + Wheel->ConnectedToHandbrake = true; + Wheel->TorqueRatio = 0.125f; + CommitEntity(wheel); + } + + + //Back + { + auto wheel = CreateEntity(tank); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(1.88f, -0.83f - wheelOffset, 1.f); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/Tank/Fix/WheelPhysics.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, springLength, 0.f); + Wheel->AxleID = 1; + Wheel->Mass = 2000; + Wheel->Radius = 0.6f; + Wheel->Steering = false; + Wheel->SuspensionStrength = suspensionStrength; + Wheel->Friction = 3.f; + Wheel->ConnectedToHandbrake = true; + Wheel->TorqueRatio = 0.125f; + CommitEntity(wheel); + } + { + auto wheel = CreateEntity(tank); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(1.88f, -0.83f - wheelOffset, 2.95f); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/Tank/Fix/WheelPhysics.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, springLength, 0.f); + Wheel->AxleID = 1; + Wheel->Mass = 2000; + Wheel->Radius = 0.6f; + Wheel->Steering = false; + Wheel->SuspensionStrength = suspensionStrength; + Wheel->Friction = 3.f; + Wheel->ConnectedToHandbrake = true; + Wheel->TorqueRatio = 0.125f; + CommitEntity(wheel); + } + + { + auto wheel = CreateEntity(tank); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(-1.88f, -0.83f - wheelOffset, 1.f); + transform->Orientation = glm::angleAxis(glm::pi(), glm::vec3(0, 1, 0)); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/Tank/Fix/WheelPhysics.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, springLength, 0.f); + Wheel->AxleID = 1; + Wheel->Mass = 2000; + Wheel->Radius = 0.6f; + Wheel->Steering = false; + Wheel->SuspensionStrength = suspensionStrength; + Wheel->Friction = 3.f; + Wheel->ConnectedToHandbrake = true; + Wheel->TorqueRatio = 0.125f; + CommitEntity(wheel); + } + { + auto wheel = CreateEntity(tank); + auto transform = AddComponent(wheel, "Transform"); + transform->Position = glm::vec3(-1.88f, -0.83f - wheelOffset, 2.95f); + auto model = AddComponent(wheel, "Model"); + model->ModelFile = "Models/Tank/Fix/WheelPhysics.obj"; + auto Wheel = AddComponent(wheel, "Wheel"); + Wheel->Hardpoint = transform->Position + glm::vec3(0.f, springLength, 0.f); + Wheel->AxleID = 1; + Wheel->Mass = 2000; + Wheel->Radius = 0.6f; + Wheel->Steering = false; + Wheel->SuspensionStrength = suspensionStrength; + Wheel->Friction = 3.f; + Wheel->ConnectedToHandbrake = true; + Wheel->TorqueRatio = 0.125f; + CommitEntity(wheel); + } + + CommitEntity(tank); } -/* + /* + for(int i = 0; i < 10; i++) + { + auto entity = CreateEntity(); + auto transform = AddComponent(entity, "Transform"); + transform->Position = glm::vec3(30 + i*0.1f, 0 + i*0.1f, 10 + i*0.1f); + transform->Scale = glm::vec3(0); + transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); + + std::stringstream ss; + ss << "Models/Placeholders/ShatterTest/" << i+1 << ".obj"; - { - // 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); - } + auto model = AddComponent(entity, "Model"); + model->ModelFile = ss.str(); + + auto physics = AddComponent(entity, "Physics"); + physics->Mass = 100; + physics->Static = true; + auto meshShape = AddComponent(entity, "MeshShape"); + meshShape->ResourceName = ss.str(); + + CommitEntity(entity); + }*/ + + for(int i = 0; i < 1; i++) + { + for (int y = 0; y < 15; y++) + { + for (int x = -5; x < 5; x++) + { + auto brick = CreateEntity(); + auto transform = AddComponent(brick, "Transform"); + transform->Position = glm::vec3(x + 0.01f, y * 0.3f + 0.01f, -20); + transform->Position.x += (y % 2)*0.5f; + transform->Scale = glm::vec3(1, 0.3f, 0.4f); + transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); + auto model = AddComponent(brick, "Model"); + model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj"; + + auto physics = AddComponent(brick, "Physics"); + physics->Mass = 3; + + + + auto shape = CreateEntity(brick); + auto transformshape = AddComponent(shape, "Transform"); + auto box = AddComponent(shape, "BoxShape"); + box->Width = 0.5f; + box->Height = 0.15f; + box->Depth = 0.3f; + CommitEntity(shape); + CommitEntity(brick); + } + } + } + + /*for (int x = 0; x < 5; x++) + for (int y = 0; y < 5; y++) + { + auto cube = CreateEntity(); + auto transform = AddComponent(cube, "Transform"); + transform->Position = glm::vec3(3 * x + 0.1f + -20.f, 3 * y + 0.1f + 1.f, 0); + transform->Scale = glm::vec3(3); + 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, "BoxShape"); + box->Width = 1.5f; + box->Height = 1.5f; + box->Depth = 1.5f; + CommitEntity(cube); + } */ - 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); - } - - { + /*{ auto entity = CreateEntity(); AddComponent(entity, "Transform"); auto emitter = AddComponent(entity, "SoundEmitter"); emitter->Path = "Sounds/korvring.wav"; emitter->Loop = true; - //GetSystem("SoundSystem")->PlaySound(emitter); + GetSystem("SoundSystem")->PlaySound(emitter); CommitEntity(entity); - } + }*/ } void GameWorld::Update(double dt) @@ -284,6 +551,7 @@ void GameWorld::RegisterSystems() ////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_EventBroker); }); + m_SystemFactory.Register("TankSteeringSystem", [this]() { return new Systems::TankSteeringSystem(this, m_EventBroker); }); m_SystemFactory.Register("SoundSystem", [this]() { return new Systems::SoundSystem(this, m_EventBroker); }); m_SystemFactory.Register("PhysicsSystem", [this]() { return new Systems::PhysicsSystem(this, m_EventBroker); }); m_SystemFactory.Register("RenderSystem", [this]() { return new Systems::RenderSystem(this, m_EventBroker, m_Renderer); }); @@ -299,6 +567,7 @@ void GameWorld::AddSystems() ////AddSystem("ParticleSystem"); //AddSystem("PlayerSystem"); AddSystem("FreeSteeringSystem"); + AddSystem("TankSteeringSystem"); AddSystem("SoundSystem"); AddSystem("PhysicsSystem"); AddSystem("RenderSystem"); diff --git a/src/GameWorld.h b/src/GameWorld.h index 45d9f98..5bb3cbd 100755 --- a/src/GameWorld.h +++ b/src/GameWorld.h @@ -12,6 +12,7 @@ #include "Systems/ParticleSystem.h" //#include "Systems/PlayerSystem.h" #include "Systems/FreeSteeringSystem.h" +#include "Systems/TankSteeringSystem.h" #include "Systems/RenderSystem.h" #include "Systems/SoundSystem.h" #include "Systems/PhysicsSystem.h" @@ -29,10 +30,11 @@ #include "Components/Transform.h" #include "Components/Physics.h" -#include "Components/Sphere.h" -#include "Components/Box.h" +#include "Components/SphereShape.h" +#include "Components/BoxShape.h" #include "Components/Vehicle.h" #include "Components/Wheel.h" +#include "Components/HingeConstraint.h" class GameWorld : public World { diff --git a/src/Model.cpp b/src/Model.cpp index 547e940..753ec65 100755 --- a/src/Model.cpp +++ b/src/Model.cpp @@ -1,7 +1,7 @@ #include "PrecompiledHeader.h" #include "Model.h" -Model::Model(OBJ &obj, ResourceManager* rm) +Model::Model(ResourceManager* rm, OBJ &obj) { OBJ::MaterialInfo* currentMaterial = nullptr; TextureGroup* currentTexGroup = nullptr; diff --git a/src/Model.h b/src/Model.h index 8d94a7d..dcf41d9 100755 --- a/src/Model.h +++ b/src/Model.h @@ -17,7 +17,7 @@ class Model : public Resource { public: - Model(OBJ &obj, ResourceManager* rm); + Model(ResourceManager* rm, OBJ &obj); struct TextureGroup { diff --git a/src/OBJ.cpp b/src/OBJ.cpp index a8b9f03..d8f91bf 100755 --- a/src/OBJ.cpp +++ b/src/OBJ.cpp @@ -9,7 +9,7 @@ bool OBJ::LoadFromFile(std::string filename) std::ifstream file(m_Path.string()); if (!file.is_open()) { - LOG_ERROR("Failed to open .obj \"%s\"", m_Path.string().c_str()); + LOG_ERROR("Failed to open .obj \"%s\": %s", m_Path.string().c_str(), strerror(errno)); return false; } diff --git a/src/OBJ.h b/src/OBJ.h index 2ef10e0..8ae9a32 100755 --- a/src/OBJ.h +++ b/src/OBJ.h @@ -12,7 +12,9 @@ #include #include -class OBJ +#include "ResourceManager.h" + +class OBJ : public Resource { public: struct MaterialInfo diff --git a/src/Physics/VehicleSetup.cpp b/src/Physics/VehicleSetup.cpp index 1768b1e..1babfcb 100644 --- a/src/Physics/VehicleSetup.cpp +++ b/src/Physics/VehicleSetup.cpp @@ -48,7 +48,6 @@ void VehicleSetup::buildVehicle(World *world, const hkpWorld* physicsWorld, hkpV setupWheelCollide(physicsWorld, vehicle, *static_cast(vehicle.m_wheelCollide)); - // // Check that all components are present. // @@ -165,7 +164,7 @@ void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultS // [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???! + steering.m_maxSpeedFullSteeringAngle = vehicleComponent.MaxSpeedFullSteeringAngle; // * (1.605f / 3.6f); //MPH???! for (int i = 0; i < m_Wheels.size(); i++) { @@ -198,20 +197,21 @@ void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultT transmission.m_gearsRatio.setSize(numberOfGears); transmission.m_wheelsTorqueRatio.setSize(data.m_numWheels); - transmission.m_downshiftRPM = 3500.0f; - transmission.m_upshiftRPM = 6500.0f; + transmission.m_downshiftRPM = 3500.0f; //HACK: Should be in VehicleComponent + transmission.m_upshiftRPM = 7000.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_reverseGearRatio = 1.2f; + transmission.m_gearsRatio[0] = 3.0f; + transmission.m_gearsRatio[1] = 2.25f; + transmission.m_gearsRatio[2] = 1.5f; + transmission.m_gearsRatio[3] = 1.0f; + + for(int i = 0; i < m_Wheels.size(); i++) + { + // The wheels total TorqueRatio must be equal to 1 + transmission.m_wheelsTorqueRatio[i] = m_Wheels[i].WheelComponent->TorqueRatio; + } transmission.m_primaryTransmissionRatio = hkpVehicleDefaultTransmission::calculatePrimaryTransmissionRatio( vehicleComponent.TopSpeed, @@ -267,7 +267,7 @@ void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultA 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); + aerodynamics.m_extraGravityws.set(0.0f, -8.0f, 0.0f); // fuck this shit } void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultVelocityDamper& velocityDamper, Components::Vehicle vehicleComponent) @@ -285,7 +285,7 @@ void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultV // The threshold in m/s at which the algorithm switches from // using the normalSpinDamping to the collisionSpinDamping. - velocityDamper.m_collisionThreshold = 1.0f; + velocityDamper.m_collisionThreshold = 100.0f; } void VehicleSetup::setupWheelCollide(const hkpWorld* world, const hkpVehicleInstance& vehicle, hkpVehicleRayCastWheelCollide& wheelCollide) diff --git a/src/Physics/VehicleSetup.h b/src/Physics/VehicleSetup.h index 1070692..7f78204 100644 --- a/src/Physics/VehicleSetup.h +++ b/src/Physics/VehicleSetup.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,7 @@ public: Components::Transform* TransformComponent; }; - + std::vector m_Wheels; virtual void setupVehicleData(const hkpWorld* world, hkpVehicleData& data); @@ -59,6 +60,7 @@ public: 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/ResourceManager.cpp b/src/ResourceManager.cpp index 1361c11..b4ff9bd 100644 --- a/src/ResourceManager.cpp +++ b/src/ResourceManager.cpp @@ -16,7 +16,7 @@ Resource* ResourceManager::CreateResource(std::string resourceType, std::string resource->TypeID = GetTypeID(resourceType); resource->ResourceID = GetNewResourceID(resource->TypeID); // Cache - m_ResourceCache[resourceName] = resource; + m_ResourceCache[std::make_pair(resourceType, resourceName)] = resource; return resource; } @@ -28,7 +28,7 @@ void ResourceManager::RegisterType(std::string resourceType, std::function #include +#include "Util/UnorderedMapPair.h" #include "Factory.h" class Resource @@ -28,7 +29,7 @@ public: void Preload(std::string resourceType, std::string resourceName); // Checks if a resource is in cache - bool IsResourceLoaded(std::string resourceName); + bool IsResourceLoaded(std::string resourceType, std::string resourceName); template // Hot-loads a resource and caches it for future use @@ -40,7 +41,7 @@ public: private: std::unordered_map> m_FactoryFunctions; // type -> factory function - std::unordered_map m_ResourceCache; // name -> resource + std::unordered_map, Resource*> m_ResourceCache; // (type, name) -> resource // TODO: Getters for IDs unsigned int m_CurrentResourceTypeID; @@ -60,7 +61,7 @@ private: template T* ResourceManager::Load(std::string resourceType, std::string resourceName) { - auto it = m_ResourceCache.find(resourceName); + auto it = m_ResourceCache.find(std::make_pair(resourceType, resourceName)); if (it != m_ResourceCache.end()) return static_cast(it->second); @@ -79,7 +80,7 @@ T* ResourceManager::Load(std::string resourceType, std::string resourceName) template T* ResourceManager::Fetch(std::string resourceName) const { - auto it = m_ResourceCache.find(resourceName); + auto it = m_ResourceCache.find(std::make_pair(resourceType, resourceName)); if (it == m_ResourceCache.end()) { LOG_ERROR("Failed to fetch resource \"%s\": Resource not loaded!", resourceName.c_str()); diff --git a/src/Systems/FreeSteeringSystem.cpp b/src/Systems/FreeSteeringSystem.cpp index b382b23..8373c80 100755 --- a/src/Systems/FreeSteeringSystem.cpp +++ b/src/Systems/FreeSteeringSystem.cpp @@ -38,35 +38,35 @@ void Systems::FreeSteeringSystem::UpdateEntity(double dt, EntityID entity, Entit bool Systems::FreeSteeringSystem::FreeSteeringInputController::OnCommand(const Events::InputCommand &event) { // Movement - if (event.Command == "+forward") + if (event.Command == "+cam_forward") { Movement.z += -1.f; } - else if (event.Command == "-forward") + else if (event.Command == "-cam_forward") { Movement.z -= -1.f; } - else if (event.Command == "+backward") + else if (event.Command == "+cam_backward") { Movement.z += 1.f; } - else if (event.Command == "-backward") + else if (event.Command == "-cam_backward") { Movement.z -= 1.f; } - else if (event.Command == "+right") + else if (event.Command == "+cam_right") { Movement.x += 1.f; } - else if (event.Command == "-right") + else if (event.Command == "-cam_right") { Movement.x -= 1.f; } - else if (event.Command == "+left") + else if (event.Command == "+cam_left") { Movement.x += -1.f; } - else if (event.Command == "-left") + else if (event.Command == "-cam_left") { Movement.x -= -1.f; } diff --git a/src/Systems/InputSystem.cpp b/src/Systems/InputSystem.cpp index 3c9fdfd..18a21aa 100755 --- a/src/Systems/InputSystem.cpp +++ b/src/Systems/InputSystem.cpp @@ -44,7 +44,7 @@ bool Systems::InputSystem::OnKeyDown(const Events::KeyDown &event) auto bindingIt = m_KeyBindings.find(event.KeyCode); if (bindingIt != m_KeyBindings.end()) { - PublishCommand(0, bindingIt->second, false); + PublishCommand(0, bindingIt->second, 1.f, false); } return true; @@ -55,7 +55,7 @@ bool Systems::InputSystem::OnKeyUp(const Events::KeyUp &event) auto bindingIt = m_KeyBindings.find(event.KeyCode); if (bindingIt != m_KeyBindings.end()) { - PublishCommand(0, bindingIt->second, true); + PublishCommand(0, bindingIt->second, 1.f, true); } return true; @@ -66,7 +66,7 @@ bool Systems::InputSystem::OnMousePress(const Events::MousePress &event) auto bindingIt = m_MouseButtonBindings.find(event.Button); if (bindingIt != m_MouseButtonBindings.end()) { - PublishCommand(0, bindingIt->second, false); + PublishCommand(0, bindingIt->second, 1.f, false); } return true; @@ -77,7 +77,7 @@ bool Systems::InputSystem::OnMouseRelease(const Events::MouseRelease &event) auto bindingIt = m_MouseButtonBindings.find(event.Button); if (bindingIt != m_MouseButtonBindings.end()) { - PublishCommand(0, bindingIt->second, true); + PublishCommand(0, bindingIt->second, 1.f, true); } return true; @@ -113,7 +113,7 @@ bool Systems::InputSystem::OnBindMouseButton(const Events::BindMouseButton &even return true; } -void Systems::InputSystem::PublishCommand(int playerID, std::string command, bool release /*= false*/) +void Systems::InputSystem::PublishCommand(int playerID, std::string command, float value, bool release /*= false*/) { if (release && command.at(0) == '+') { @@ -123,6 +123,7 @@ void Systems::InputSystem::PublishCommand(int playerID, std::string command, boo Events::InputCommand e; e.PlayerID = playerID; e.Command = command; + e.Value = value; EventBroker->Publish(e); LOG_DEBUG("Input: Published command %s for player %i", e.Command.c_str(), playerID); diff --git a/src/Systems/InputSystem.h b/src/Systems/InputSystem.h index c56cccf..f912de0 100755 --- a/src/Systems/InputSystem.h +++ b/src/Systems/InputSystem.h @@ -48,7 +48,7 @@ private: EventRelay m_EBindMouseButton; bool OnBindMouseButton(const Events::BindMouseButton &event); - void PublishCommand(int playerID, std::string command, bool release = false); + void PublishCommand(int playerID, std::string command, float value, bool release = false); }; } diff --git a/src/Systems/ParticleSystem.h b/src/Systems/ParticleSystem.h index 082c957..d976105 100644 --- a/src/Systems/ParticleSystem.h +++ b/src/Systems/ParticleSystem.h @@ -6,8 +6,6 @@ #include "Components/ParticleEmitter.h" #include "Components/Particle.h" #include "Components/Model.h" -#include "Components/Physics.h" -#include "Components/Box.h" #include "Components/PointLight.h" #include "Color.h" #include diff --git a/src/Systems/PhysicsSystem.cpp b/src/Systems/PhysicsSystem.cpp index dfb7a8b..5fad34c 100644 --- a/src/Systems/PhysicsSystem.cpp +++ b/src/Systems/PhysicsSystem.cpp @@ -28,45 +28,94 @@ void Systems::PhysicsSystem::Initialize() { m_Accumulator = 0; + + // Events + EVENT_SUBSCRIBE_MEMBER(m_ETankSteer, &Systems::PhysicsSystem::OnTankSteer); + + hkMemorySystem::FrameInfo finfo(6000 * 1024); // Allocate 6MB of Physics solver buffer + hkMemoryRouter* memoryRouter = hkMemoryInitUtil::initDefault(hkMallocAllocator::m_defaultMallocAllocator, finfo); + hkBaseSystem::init(memoryRouter, HavokErrorReport); + + + // Get the number of physical threads available on the system + hkHardwareInfo hwInfo; + hkGetHardwareInfo(hwInfo); + m_TotalNumThreadsUsed = hwInfo.m_numThreads; + + // We use one less than this for our thread pool, because we must also use this thread for our simulation + hkCpuJobThreadPoolCinfo threadPoolCinfo; + threadPoolCinfo.m_numThreads = m_TotalNumThreadsUsed - 1; + + // This line enables timers collection, by allocating 200 Kb per thread. If you leave this at its default (0), + // timer collection will not be enabled. + threadPoolCinfo.m_timerBufferPerThreadAllocation = 200000; + m_ThreadPool = new hkCpuJobThreadPool(threadPoolCinfo); + + hkJobQueueCinfo info; + info.m_jobQueueHwSetup.m_numCpuThreads = m_TotalNumThreadsUsed; + m_JobQueue = new hkJobQueue(info); + + // + // Enable monitors for this thread. + // + + // Monitors have been enabled for thread pool threads already (see above comment). + hkMonitorStream::getInstance().resize(200000); + { - 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; + + // Set the simulation type of the world to multi-threaded. + worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED; + worldInfo.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM); - worldInfo.m_gravity = hkVector4(0.0f, -9.8f, 0.0f); + worldInfo.m_gravity = hkVector4(0.0f, -9.82f, 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(1000.0f); m_PhysicsWorld = new hkpWorld(worldInfo); - } - // Register all collision agents, even though only box - box will be used in this particular example. - // It's important to register collision agents before adding any entities to the world. - hkpAgentRegisterUtil::registerAllAgents(m_PhysicsWorld->getCollisionDispatcher()); - - // - // 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); + // When the simulation type is SIMULATION_TYPE_MULTITHREADED, in the debug build, the sdk performs checks + // to make sure only one thread is modifying the world at once to prevent multithreaded bugs. Each thread + // must call markForRead / markForWrite before it modifies the world to enable these checks. + m_PhysicsWorld->markForWrite(); + + // 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()); + + // We need to register all modules we will be running multi-threaded with the job queue + m_PhysicsWorld->registerWithJobQueue(m_JobQueue); + + + // + // 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. + // + m_Context = new hkpPhysicsContext; + hkpPhysicsContext::registerAllPhysicsProcesses(); // all the physics viewers + m_Context->addWorld(m_PhysicsWorld); // add the physics world so the viewers can see it + + SetupVisualDebugger(m_Context); + + m_PhysicsWorld->unmarkForWrite(); + } + } 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("BoxShape", []() { return new Components::BoxShape(); }); + cf->Register("SphereShape", []() { return new Components::SphereShape(); }); cf->Register("Vehicle", []() { return new Components::Vehicle(); }); cf->Register("Wheel", []() { return new Components::Wheel(); }); + cf->Register("MeshShape", []() { return new Components::MeshShape(); }); + cf->Register("HingeConstraint", []() { return new Components::HingeConstraint(); }); + cf->Register("WheelPair", []() { return new Components::WheelPair(); }); + } void Systems::PhysicsSystem::Update(double dt) @@ -74,6 +123,7 @@ void Systems::PhysicsSystem::Update(double dt) for (auto pair : *m_World->GetEntities()) { EntityID entity = pair.first; + EntityID parent = pair.second; if (m_RigidBodies.find(entity) == m_RigidBodies.end()) continue; @@ -82,29 +132,50 @@ void Systems::PhysicsSystem::Update(double dt) 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); + hkVector4 position; + hkQuaternion rotation; + + if (parent) + { + auto absoluteTransform = m_World->GetSystem("TransformSystem")->AbsoluteTransform(entity); + position = ConvertPosition(absoluteTransform.Position); + rotation = ConvertRotation(absoluteTransform.Orientation); + } + else + { + position = ConvertPosition(transformComponent->Position); + rotation = ConvertRotation(transformComponent->Orientation); + } + m_PhysicsWorld->markForWrite(); m_RigidBodies[entity]->setPositionAndRotation(position, rotation); + m_PhysicsWorld->unmarkForWrite(); + } } - - - - static const double timestep = 1 / 30.0; + static const double timestep = 1 / 60.0; m_Accumulator += dt; while (m_Accumulator >= timestep) { - m_PhysicsWorld->stepDeltaTime(timestep); - m_Accumulator -= timestep; - } + m_PhysicsWorld->stepMultithreaded(m_JobQueue, m_ThreadPool, timestep); + //m_PhysicsWorld->stepDeltaTime(timestep); - // Step the visual debugger - StepVisualDebugger(); + m_Accumulator -= timestep; + + m_Context->syncTimers(m_ThreadPool); + // Step the visual debugger + StepVisualDebugger(); + + // Clear accumulated timer data in this thread and all slave threads + hkMonitorStream::getInstance().reset(); + m_ThreadPool->clearTimerData(); + } + + + } void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) @@ -119,6 +190,7 @@ void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID p EntityID car = m_World->GetEntityParent(entity); if(m_Vehicles.find(car) != m_Vehicles.end()) { + m_PhysicsWorld->markForWrite(); m_Vehicles[car]->getChassis()->activate(); hkVector4 hardPoint = m_Vehicles[car]->m_suspension->m_wheelParams[wheelComponent->ID].m_hardpointChassisSpace; @@ -129,40 +201,28 @@ void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID p 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)); + glm::quat orientation = ConvertRotation(steeringOrientation) * glm::angleAxis(spinAngle, glm::vec3(1, 0, 0)); transformComponent->Orientation = orientation * wheelComponent->OriginalOrientation; + m_PhysicsWorld->unmarkForWrite(); } } - else 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)); - - } else if(m_RigidBodies.find(entity) != m_RigidBodies.end()) { - if(m_RigidBodies[entity]->isActive()) + auto transformComponentParent = m_World->GetComponent(parent, "Transform"); + + transformComponent->Position = ConvertPosition(m_RigidBodies[entity]->getPosition()); + transformComponent->Orientation = ConvertRotation(m_RigidBodies[entity]->getRotation()); + // TODO: No support for Scale, MIGHT be possible + + if (transformComponentParent) { - 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)); + transformComponent->Position -= transformComponentParent->Position; + transformComponent->Position = transformComponent->Position * transformComponentParent->Orientation; + transformComponent->Orientation = transformComponent->Orientation * glm::inverse(transformComponentParent->Orientation); } } - - // 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 ) @@ -171,7 +231,6 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) if (!transformComponent) return; - auto wheelComponent = m_World->GetComponent(entity, "Wheel"); if (wheelComponent) { @@ -180,201 +239,250 @@ void Systems::PhysicsSystem::OnEntityCommit( EntityID entity ) m_Wheels.push_back(entity); } + EntityID entityParent = m_World->GetEntityBaseParent(entity); + + auto sphereComponent = m_World->GetComponent(entity, "SphereShape"); + auto boxComponent = m_World->GetComponent(entity, "BoxShape"); + auto meshShapeComponent = m_World->GetComponent(entity, "MeshShape"); + + if(entityParent == entity && (sphereComponent || boxComponent || meshShapeComponent)) + { + LOG_ERROR("Entity: %i , Only the children can have a shapeComponent", entity); + 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) + if (physicsComponent) { - shape = new hkpSphereShape(sphereComponent->Radius); - rigidBodyInfo.m_shape = shape; - - if (physicsComponent->Static) + hkpShape* shape; + if(entityParent != entity) { - rigidBodyInfo.m_motionType = hkpMotion::MOTION_FIXED; - } - else - { - rigidBodyInfo.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA; + LOG_ERROR("Entity: %i , Only the baseparent can have a PhysicsComponent", entity); + return; } - 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) + if(! physicsComponent->Static) // Not 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) + hkArray shapeArray; + for (auto &shapeData : m_Shapes[entity]) { - m_Wheels.erase(m_Wheels.begin() + i); - i--; + shapeArray.pushBack(shapeData.Shape); + } + + + // Create a hkpListShape* of all the childEntities collected in m_ShapeArrays + hkpListShape* listShape = new hkpListShape(shapeArray.begin(), shapeArray.getSize(), hkpShapeContainer::REFERENCE_POLICY_INCREMENT); + // Save the listShape for further use + m_ListShapes[entity] = listShape; + shape = listShape; + + ////////////////////////////////// + //******************************// + // Add a hkpBvShape // + //******************************// + ////////////////////////////////// + + // Clean up for less memory usage + m_Shapes.erase(entity); + + hkMassProperties massProperties; + hkpInertiaTensorComputer::computeShapeVolumeMassProperties(shape, physicsComponent->Mass, massProperties); + + hkpRigidBodyCinfo rigidBodyInfo; + { + rigidBodyInfo.m_shape = shape; + rigidBodyInfo.m_motionType = hkpMotion::MOTION_DYNAMIC; + auto absoluteTransform = m_World->GetSystem("TransformSystem")->AbsoluteTransform(entity); + hkVector4 position = ConvertPosition(absoluteTransform.Position); + hkQuaternion rotation = ConvertRotation(absoluteTransform.Orientation); + rigidBodyInfo.m_position.set(position(0), position(1), position(2), position(3)); + rigidBodyInfo.m_rotation.set(rotation(0), rotation(1), rotation(2), rotation(3)); + + rigidBodyInfo.m_inertiaTensor = massProperties.m_inertiaTensor; + //rigidBodyInfo.m_centerOfMass = massProperties.m_centerOfMass; //HACK: CENTER OF MASS ALWAYS IN THE CENTER + 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); + m_PhysicsWorld->markForWrite(); + 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_PhysicsWorld->unmarkForWrite(); + + //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->markForWrite(); + m_PhysicsWorld->addEntity(rigidBody); + m_RigidBodies[entity] = rigidBody; + m_PhysicsWorld->unmarkForWrite(); + + shape->removeReference(); + rigidBody->removeReference(); } } - 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) + else // 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 the hkpStaticCompoundShape and add the instances. + // "meshShape" should not be modified by the user in any way after adding it as an instance. + hkpStaticCompoundShape* staticCompoundShape = new hkpStaticCompoundShape(); - // Create RigidBody - hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo); - + for (auto &shapeData : m_Shapes[entity]) + { + + auto childTransformComponent = m_World->GetComponent(shapeData.Entity, "Transform"); - auto vehicleComponent = m_World->GetComponent(entity, "Vehicle"); - if (vehicleComponent && m_Vehicles.find(entity) == m_Vehicles.end()) - { - VehicleSetup vehicleSetup; + hkVector4 position = ConvertPosition(childTransformComponent->Position); + hkQuaternion rotation = ConvertRotation(childTransformComponent->Orientation); + hkVector4 scale = ConvertScale(childTransformComponent->Scale); + hkQsTransform transform(position, rotation, scale); - // 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; + staticCompoundShape->addInstance(shapeData.Shape, transform); + } - // The vehicle is an action - m_PhysicsWorld->addAction(m_Vehicles[entity]); + // This must be called after adding the instances and before using the shape. + staticCompoundShape->bake(); + shape = staticCompoundShape; + m_Shapes.erase(entity); + hkMassProperties massProperties; + hkpInertiaTensorComputer::computeShapeVolumeMassProperties(shape, physicsComponent->Mass, massProperties); - //m_Vehicles[entity]->m_rpm = 0.0f; // Not sure why this one should be here + hkpRigidBodyCinfo rigidBodyInfo; + { + rigidBodyInfo.m_shape = shape; + rigidBodyInfo.m_motionType = hkpMotion::MOTION_FIXED; + auto absoluteTransform = m_World->GetSystem("TransformSystem")->AbsoluteTransform(entity); + hkVector4 position = ConvertPosition(absoluteTransform.Position); + hkQuaternion rotation = ConvertRotation(absoluteTransform.Orientation); + rigidBodyInfo.m_position.set(position(0), position(1), position(2), position(3)); + rigidBodyInfo.m_rotation.set(rotation(0), rotation(1), rotation(2), rotation(3)); + + rigidBodyInfo.m_inertiaTensor = massProperties.m_inertiaTensor; + //rigidBodyInfo.m_centerOfMass = massProperties.m_centerOfMass; //HACK: CENTER OF MASS ALWAYS IN THE CENTER + rigidBodyInfo.m_mass = massProperties.m_mass; + } + // Create RigidBody + hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo); + + m_PhysicsWorld->markForWrite(); + m_PhysicsWorld->addEntity(rigidBody); + m_RigidBodies[entity] = rigidBody; + m_PhysicsWorld->unmarkForWrite(); shape->removeReference(); rigidBody->removeReference(); + + + } + } else { - m_PhysicsWorld->addEntity(rigidBody); - m_RigidBodies[entity] = rigidBody; - shape->removeReference(); - rigidBody->removeReference(); + + //TODO: COMMENT THIS SECTION + if(sphereComponent) + { + hkpSphereShape* sphereShape = new hkpSphereShape(sphereComponent->Radius); + + hkQsTransform transform( ConvertPosition(transformComponent->Position), ConvertRotation(transformComponent->Orientation), ConvertScale(transformComponent->Scale)); + hkpConvexTransformShape* transformedSphereShape = new hkpConvexTransformShape( sphereShape, transform ); + + m_Shapes[entityParent].push_back(ShapeArrayData(entity, transformedSphereShape)); + + sphereShape->removeReference(); + } + //TODO: COMMENT THIS SECTION + else if(boxComponent) + { + hkReal thickness = 0.05; + hkpBoxShape* boxShape = new hkpBoxShape(hkVector4(boxComponent->Width- thickness, boxComponent->Height -thickness, boxComponent->Depth - thickness), thickness); + + hkQsTransform transform( ConvertPosition(transformComponent->Position), ConvertRotation(transformComponent->Orientation), ConvertScale(transformComponent->Scale)); + hkpConvexTransformShape* transformedBoxShape = new hkpConvexTransformShape( boxShape, transform ); + m_Shapes[entityParent].push_back(ShapeArrayData(entity, transformedBoxShape)); + boxShape->removeReference(); + } + else if(meshShapeComponent) + { + std::vector* vertices = new std::vector; + std::vector* vertexIndices = new std::vector; + auto meshShape = m_World->GetResourceManager()->Load("OBJ", meshShapeComponent->ResourceName); + + for (auto &vertex : meshShape->Vertices) + { + hkReal x, y, z; + std::tie(x, y, z) = vertex; + vertices->push_back(x); + vertices->push_back(y); + vertices->push_back(z); + } + + int i = 0; + for (auto &face : meshShape->Faces) + { + for (auto &faceDef : face.Definitions) + { + vertexIndices->push_back(faceDef.VertexIndex - 1); + } + } + + hkpExtendedMeshShape* mesh = new hkpExtendedMeshShape(); + hkReal thickness = 0.05f; // HACK: Convex radius should be 0 for static shapes and 0.05 for dynamic shapes. + mesh->setRadius(thickness); + { + hkpExtendedMeshShape::TrianglesSubpart part; + part.m_numTriangleShapes = meshShape->Faces.size(); + part.m_indexBase = vertexIndices->data(); + part.m_indexStriding = sizeof(hkUint16) * 3; + + part.m_numVertices = vertices->size() / 3; + part.m_vertexBase = vertices->data(); + part.m_vertexStriding = sizeof(hkReal) * 3; + + part.m_stridingType = hkpExtendedMeshShape::INDICES_INT16; + + mesh->addTrianglesSubpart(part); + } + hkpMoppCompilerInput mci; + hkpMoppCode* code = hkpMoppUtility::buildCode( mesh, mci ); + hkpMoppBvTreeShape* moppShape = new hkpMoppBvTreeShape(mesh, code); + + m_ExtendedMeshShapes[entity].Code = code; + m_ExtendedMeshShapes[entity].MoppShape = moppShape; + m_Shapes[entityParent].push_back(ShapeArrayData(entity, moppShape)); //HACK: Should maybe have transform, not sure yet + } } + + + } -*/ - - - void Systems::PhysicsSystem::TearDownPhysicsState(EntityID entity, EntityID parent) { @@ -396,8 +504,9 @@ void Systems::PhysicsSystem::SetupVisualDebugger(hkpPhysicsContext* worlds) { // Setup the visual debugger hkArray contexts; + contexts.pushBack(worlds); - + m_VisualDebugger = new hkVisualDebugger(contexts); m_VisualDebugger->serve(); @@ -423,3 +532,51 @@ void HK_CALL Systems::PhysicsSystem::HavokErrorReport(const char* msg, void*) LOG_INFO("%s", msg); } + +glm::vec3 Systems::PhysicsSystem::ConvertPosition(const hkVector4 &hkPosition) +{ + return glm::vec3(hkPosition(0), hkPosition(1), hkPosition(2)); +} + +const hkVector4& Systems::PhysicsSystem::ConvertPosition(glm::vec3 glmPosition) +{ + return hkVector4( glmPosition.x, glmPosition.y, glmPosition.z); +} + +glm::quat Systems::PhysicsSystem::ConvertRotation(const hkQuaternion &hkRotation) +{ + return glm::quat(hkRotation(3), hkRotation(0), hkRotation(1), hkRotation(2)); +} + +const hkQuaternion& Systems::PhysicsSystem::ConvertRotation(glm::quat glmRotation) +{ + return hkQuaternion(glmRotation.x, glmRotation.y, glmRotation.z, glmRotation.w); +} + +glm::vec3 Systems::PhysicsSystem::ConvertScale(const hkVector4 &hkScale) +{ + return glm::vec3(hkScale(0), hkScale(1), hkScale(2)); +} + +const hkVector4& Systems::PhysicsSystem::ConvertScale(glm::vec3 glmScale) +{ + return hkVector4(glmScale.x, glmScale.y, glmScale.z); +} + +bool Systems::PhysicsSystem::OnTankSteer(const Events::TankSteer &event) +{ + auto vehicleComponent = m_World->GetComponent(event.Entity, "Vehicle"); + auto inputComponent = m_World->GetComponent(event.Entity, "Input"); + if (vehicleComponent && inputComponent && m_Vehicles.find(event.Entity) != m_Vehicles.end() && m_RigidBodies.find(event.Entity) != m_RigidBodies.end()) + { + m_PhysicsWorld->markForWrite(); + hkpVehicleDriverInputAnalogStatus* deviceStatus = (hkpVehicleDriverInputAnalogStatus*)m_Vehicles[event.Entity]->m_deviceStatus; + deviceStatus->m_positionX = event.PositionX; + deviceStatus->m_positionY = event.PositionY; + deviceStatus->m_handbrakeButtonPressed = event.Handbrake; + m_PhysicsWorld->unmarkForWrite(); + } + + return true; +} + diff --git a/src/Systems/PhysicsSystem.h b/src/Systems/PhysicsSystem.h index c6ebe4a..b8fc262 100644 --- a/src/Systems/PhysicsSystem.h +++ b/src/Systems/PhysicsSystem.h @@ -2,12 +2,18 @@ #define PhysicsSystem_h__ #include "System.h" +#include "Systems/TransformSystem.h" #include "Components/Transform.h" #include "Components/Physics.h" -#include "Components/Sphere.h" -#include "Components/Box.h" +#include "Components/BoxShape.h" +#include "Components/SphereShape.h" #include "Components/Vehicle.h" #include "Components/Input.h" +#include "Components/MeshShape.h" +#include "Components/HingeConstraint.h" +#include "Components/WheelPair.h" +#include "Events/TankSteer.h" +#include "OBJ.h" // Math and base include #include @@ -34,6 +40,21 @@ #include #include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + #include "Physics/VehicleSetup.h" #include @@ -59,6 +80,10 @@ private: double m_Accumulator; hkpWorld* m_PhysicsWorld; + // Events + EventRelay m_ETankSteer; + bool OnTankSteer(const Events::TankSteer &event); + void SetUpPhysicsState(EntityID entity, EntityID parent); void TearDownPhysicsState(EntityID entity, EntityID parent); @@ -67,12 +92,54 @@ private: void StepVisualDebugger(); static void HK_CALL HavokErrorReport(const char* msg, void*); void SetupPhysics(hkpWorld* physicsWorld); + + // Converterfunctions + glm::vec3 ConvertPosition(const hkVector4 &hkPosition); + const hkVector4& ConvertPosition(glm::vec3 glmPosition); + + glm::quat ConvertRotation(const hkQuaternion &hkRotation); + const hkQuaternion& ConvertRotation(glm::quat glmRotation); + + glm::vec3 ConvertScale(const hkVector4 &hkScale); + const hkVector4&ConvertScale(glm::vec3 glmScale); std::unordered_map m_RigidBodies; + + hkJobThreadPool* m_ThreadPool; + hkJobQueue* m_JobQueue; + int m_TotalNumThreadsUsed; + hkpPhysicsContext* m_Context; + std::unordered_map m_Vehicles; std::vector m_Wheels; hkpVehicleInstance* Systems::PhysicsSystem::createVehicle(VehicleSetup& vehicleSetup, hkpRigidBody* chassis); + + + struct ShapeArrayData + { + ShapeArrayData(EntityID entity, hkpShape* shape) + { + Entity = entity; + Shape = shape; + } + EntityID Entity; + hkpShape* Shape; + }; + std::unordered_map> m_Shapes; + std::unordered_map m_ListShapes; + + + + struct ExtendedShapeData + { + hkpExtendedMeshShape* ExtendedMeshShape; + std::vector* Vertices; + std::vector* VertexIndices; + hkpMoppCode* Code; + hkpMoppBvTreeShape* MoppShape; + }; + std::unordered_map m_ExtendedMeshShapes; }; } diff --git a/src/Systems/RenderSystem.cpp b/src/Systems/RenderSystem.cpp index d451c8b..35a57d8 100755 --- a/src/Systems/RenderSystem.cpp +++ b/src/Systems/RenderSystem.cpp @@ -84,7 +84,8 @@ void Systems::RenderSystem::RegisterComponents(ComponentFactory* cf) void Systems::RenderSystem::RegisterResourceTypes(ResourceManager* rm) { - rm->RegisterType("Model", [rm](std::string resourceName) { return new Model(OBJ(resourceName), rm); }); + rm->RegisterType("Model", [rm](std::string resourceName) { return new Model(rm, *rm->Load("OBJ", resourceName)); }); + rm->RegisterType("OBJ", [](std::string resourceName) { return new OBJ(resourceName); }); rm->RegisterType("Texture", [](std::string resourceName) { return new Texture(resourceName); }); } diff --git a/src/Systems/TankSteeringSystem.cpp b/src/Systems/TankSteeringSystem.cpp new file mode 100644 index 0000000..f0a4e30 --- /dev/null +++ b/src/Systems/TankSteeringSystem.cpp @@ -0,0 +1,87 @@ +#include "PrecompiledHeader.h" +#include "TankSteeringSystem.h" +#include "World.h" + +void Systems::TankSteeringSystem::RegisterComponents( ComponentFactory* cf ) +{ + cf->Register("TankSteering", []() { return new Components::TankSteering(); }); +} + +void Systems::TankSteeringSystem::Initialize() +{ + m_InputController = std::unique_ptr(new TankSteeringInputController(EventBroker)); + m_InputController->PositionX = 0; + m_InputController->PositionY = 0; + m_InputController->Handbrake = false; +} + +void Systems::TankSteeringSystem::Update(double dt) +{ + +} + +void Systems::TankSteeringSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) +{ + auto tankSteeringComponent = m_World->GetComponent(entity, "TankSteering"); + if(tankSteeringComponent) + { + Events::TankSteer e; + e.Entity = entity; + e.PositionX = m_InputController->PositionX; + e.PositionY = m_InputController->PositionY; + e.Handbrake = m_InputController->Handbrake; + EventBroker->Publish(e); + } +} + +bool Systems::TankSteeringSystem::TankSteeringInputController::OnCommand(const Events::InputCommand &event) +{ + float val = boost::any_cast(event.Value); + if (event.Command == "+right") + { + PositionX += val; + } + else if (event.Command == "-right") + { + PositionX -= val; + } + else if (event.Command == "+left") + { + PositionX += -val; + } + else if (event.Command == "-left") + { + PositionX -= -val; + } + else if (event.Command == "+forward") + { + PositionY += -val; + } + else if (event.Command == "-forward") + { + PositionY -= -val; + } + else if (event.Command == "+backward") + { + PositionY += val; + } + else if (event.Command == "-backward") + { + PositionY -= val; + } + + else if (event.Command == "+handbrake") + { + Handbrake = true; + } + else if (event.Command == "-handbrake") + { + Handbrake = false; + } + return true; +} + +bool Systems::TankSteeringSystem::TankSteeringInputController::OnMouseMove( const Events::MouseMove &event ) +{ + return false; +} diff --git a/src/Systems/TankSteeringSystem.h b/src/Systems/TankSteeringSystem.h new file mode 100644 index 0000000..5c7a02e --- /dev/null +++ b/src/Systems/TankSteeringSystem.h @@ -0,0 +1,45 @@ +#include + +#include "System.h" +#include "Events/TankSteer.h" +#include "Components/Transform.h" +#include "Components/TankSteering.h" +#include "Components/Vehicle.h" +#include "InputController.h" + +namespace Systems +{ + + class TankSteeringSystem : public System + { + public: + TankSteeringSystem(World* world, std::shared_ptr<::EventBroker> eventBroker) + : System(world, eventBroker) { } + + void RegisterComponents(ComponentFactory* cf) override; + void Initialize() override; + + void Update(double dt) override; + void UpdateEntity(double dt, EntityID entity, EntityID parent) override; + + private: + class TankSteeringInputController; + std::unique_ptr m_InputController; + }; + + class TankSteeringSystem::TankSteeringInputController : InputController + { + public: + TankSteeringInputController(std::shared_ptr<::EventBroker> eventBroker) + : InputController(eventBroker) { } + + float PositionY; + float PositionX; + bool Handbrake; + + protected: + virtual bool OnCommand(const Events::InputCommand &event); + virtual bool OnMouseMove(const Events::MouseMove &event); + }; + +} \ No newline at end of file diff --git a/src/Texture.cpp b/src/Texture.cpp index 49256da..373db0d 100755 --- a/src/Texture.cpp +++ b/src/Texture.cpp @@ -15,6 +15,9 @@ void Texture::Load(std::string path) } m_Texture = m_TextureCache[path]; + glBindTexture(GL_TEXTURE_2D, m_Texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } void Texture::Bind() diff --git a/src/Util/UnorderedMapPair.h b/src/Util/UnorderedMapPair.h new file mode 100644 index 0000000..68d2355 --- /dev/null +++ b/src/Util/UnorderedMapPair.h @@ -0,0 +1,20 @@ +#ifndef Util_UnorderedMapPair_h__ +#define Util_UnorderedMapPair_h__ + +#include + +namespace std +{ + template struct hash> + { + inline size_t operator()(const pair & v) const + { + size_t seed = 0; + boost::hash_combine(seed, v.first); + boost::hash_combine(seed, v.second); + return seed; + } + }; +} + +#endif // Util_UnorderedMapPair_h__ \ No newline at end of file diff --git a/vs11/Returngeance/Returngeance.vcxproj b/vs11/Returngeance/Returngeance.vcxproj index cc117af..63c4d5a 100755 --- a/vs11/Returngeance/Returngeance.vcxproj +++ b/vs11/Returngeance/Returngeance.vcxproj @@ -53,15 +53,15 @@ Level3 - Disabled - true _WINDOWS;WIN32;_WIN32;_DEBUG;HK_DEBUG;HK_DEBUG_SLOW;_XT_STATICLINK;_CONSOLE;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;HK_CONFIG_SIMD=1;DEBUG;_CRT_SECURE_NO_WARNINGS;_MBCS;%(PreprocessorDefinitions) Create PrecompiledHeader.h - true MultiThreadedDebugDLL - StreamingSIMDExtensions2 false + Default + ProgramDatabase + MaxSpeed + true true @@ -80,7 +80,7 @@ true true true - _CRT_SECURE_NO_WARNINGS;_MBCS;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_MBCS;HK_CONFIG_SIMD=1;%(PreprocessorDefinitions) Create PrecompiledHeader.h StreamingSIMDExtensions2 @@ -116,6 +116,7 @@ + @@ -124,23 +125,28 @@ - + + + + - + + + @@ -153,6 +159,7 @@ + @@ -178,11 +185,13 @@ + + diff --git a/vs11/Returngeance/Returngeance.vcxproj.filters b/vs11/Returngeance/Returngeance.vcxproj.filters index 45e0e9b..4128eef 100755 --- a/vs11/Returngeance/Returngeance.vcxproj.filters +++ b/vs11/Returngeance/Returngeance.vcxproj.filters @@ -54,10 +54,15 @@ Particle System\Systems - + + Physics + Input + + Physics\Systems + @@ -129,6 +134,9 @@ {ee125b77-b275-4841-abc9-374957a89916} + + {42ae084f-ade8-402c-87ba-f03f6b846bc8} + @@ -229,19 +237,36 @@ Audio - - - Physics\Components - - - Physics\Components - Physics\Components Physics\Components + + Physics + + + Physics\Components + + + Physics\Components + + + Physics\Components + + + Util + + + Physics\Components + + + Physics\Components + + + Physics\Components + Particle System\Systems @@ -297,6 +322,18 @@ GUI + + Physics + + + Physics\Components + + + Physics\Events + + + Physics\Systems +