diff --git a/.gitignore b/.gitignore index 4f30c2a..5982b10 100755 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,6 @@ ipch/ [Dd]ebug*/ [Rr]elease*/ Ankh.NoLoad +*.orig -assets/ !libs/*.lib \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..185a1f9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "assets"] + path = assets + url = returngeance@shard.imon.nu:Assets + branch = master diff --git a/assets b/assets new file mode 160000 index 0000000..672e8a2 --- /dev/null +++ b/assets @@ -0,0 +1 @@ +Subproject commit 672e8a2b11ecaafc95a5b0286b5ec310c62438ad 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/Camera.h b/src/Components/Camera.h index 91e55b5..fb3f7ef 100755 --- a/src/Components/Camera.h +++ b/src/Components/Camera.h @@ -8,8 +8,12 @@ namespace Components struct Camera : Component { - Camera() : FOV(glm::radians(45.f)), NearClip(0.1f), FarClip(100.f) { } + Camera() + : FOV(glm::radians(45.f)) + , NearClip(0.1f) + , FarClip(100.f) { } + std::string Viewport; float FOV; float NearClip; float FarClip; diff --git a/src/Components/Physics.h b/src/Components/Physics.h index 98a682f..35844b5 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; virtual Physics* Clone() const override { return new Physics(*this); } }; diff --git a/src/Components/Vehicle.h b/src/Components/Vehicle.h new file mode 100644 index 0000000..1a1219e --- /dev/null +++ b/src/Components/Vehicle.h @@ -0,0 +1,28 @@ +#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; + + Vehicle* Clone() const override { return new Vehicle(*this); } +}; + +} + +#endif // Components_Vehicle_h__ diff --git a/src/Components/Wheel.h b/src/Components/Wheel.h new file mode 100644 index 0000000..2c88490 --- /dev/null +++ b/src/Components/Wheel.h @@ -0,0 +1,42 @@ +#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; + + Wheel* Clone() const override { return new Wheel(*this); } +}; + +} +#endif // Components_Wheel_h__ diff --git a/src/Engine.h b/src/Engine.h index 4093d20..25337c4 100755 --- a/src/Engine.h +++ b/src/Engine.h @@ -1,7 +1,10 @@ #include #include +#include "EventBroker.h" #include "Renderer.h" +#include "InputManager.h" +#include "GUI/Frame.h" #include "GameWorld.h" class Engine @@ -9,10 +12,16 @@ class Engine public: Engine(int argc, char* argv[]) { + m_EventBroker = std::make_shared(); + m_Renderer = std::make_shared(); m_Renderer->Initialize(); - m_World = std::make_shared(m_Renderer); + m_InputManager = std::make_shared(m_Renderer->GetWindow(), m_EventBroker); + + m_UIParent = std::make_shared(m_EventBroker); + + m_World = std::make_shared(m_EventBroker, m_Renderer); m_World->Initialize(); m_LastTime = glfwGetTime(); @@ -26,6 +35,7 @@ public: double dt = currentTime - m_LastTime; m_LastTime = currentTime; + m_InputManager->Update(dt); m_World->Update(dt); m_Renderer->Draw(dt); @@ -33,7 +43,10 @@ public: } private: + std::shared_ptr m_EventBroker; std::shared_ptr m_Renderer; + std::shared_ptr m_InputManager; + std::shared_ptr m_UIParent; // TODO: This should ultimately live in GameFrame std::shared_ptr m_World; diff --git a/src/EventBroker.cpp b/src/EventBroker.cpp new file mode 100644 index 0000000..68354c9 --- /dev/null +++ b/src/EventBroker.cpp @@ -0,0 +1,29 @@ +#include "PrecompiledHeader.h" +#include "EventBroker.h" + +BaseEventRelay::~BaseEventRelay() +{ + if (m_Broker != nullptr) + { + m_Broker->Unsubscribe(*this); + } +} + +void EventBroker::Unsubscribe(BaseEventRelay &relay) // ? +{ + auto itpair = m_Subscribers.equal_range(relay.m_TypeName); + for (auto it = itpair.first; it != itpair.second; ++it) + { + if (it->second == &relay) + { + m_Subscribers.erase(it); + break; + } + } +} + +void EventBroker::Subscribe(BaseEventRelay &relay) +{ + relay.m_Broker = this; + m_Subscribers.insert(std::make_pair(relay.m_TypeName, &relay)); +} \ No newline at end of file diff --git a/src/EventBroker.h b/src/EventBroker.h new file mode 100644 index 0000000..f8877e8 --- /dev/null +++ b/src/EventBroker.h @@ -0,0 +1,96 @@ +#ifndef MessageRelay_h__ +#define MessageRelay_h__ + +#include +#include +#include +#include + +#define EVENT_SUBSCRIBE_MEMBER(relay, handler) \ + relay = decltype(relay)(std::bind(handler, this, std::placeholders::_1)); \ + EventBroker->Subscribe(relay); + +struct Event +{ +protected: + Event() { } +}; + +class EventBroker; + +class BaseEventRelay +{ +friend class EventBroker; + +protected: + BaseEventRelay(std::string typeName) + : m_TypeName(typeName), m_Broker(nullptr) { } + ~BaseEventRelay(); + +public: + virtual bool Receive(const Event &event) = 0; + +protected: + std::string m_TypeName; + EventBroker* m_Broker; +}; + +template +class EventRelay : public BaseEventRelay +{ +public: + typedef std::function CallbackType; + + EventRelay() + : m_Callback(nullptr) + , BaseEventRelay(typeid(EventType).name()) { } + EventRelay(CallbackType callback) + : m_Callback(callback) + , BaseEventRelay(typeid(EventType).name()) { } + +protected: + bool Receive(const Event &event) override; + +private: + CallbackType m_Callback; +}; + +template +bool EventRelay::Receive(const Event &event) +{ + if (m_Callback != nullptr) + { + return m_Callback(static_cast(event)); + } + else + { + return false; + } +} + +class EventBroker +{ +template friend class EventRelay; + +public: + template + void Publish(const EventType &event); + void Subscribe(BaseEventRelay &relay); + void Unsubscribe(BaseEventRelay &relay); + +private: + std::unordered_multimap m_Subscribers; +}; + + +template +void EventBroker::Publish(const EventType &event) +{ + auto itpair = m_Subscribers.equal_range(typeid(EventType).name()); + for (auto it = itpair.first; it != itpair.second; ++it) + { + it->second->Receive(event); + } +} + +#endif // MessageRelay_h__ diff --git a/src/Events/BindKey.h b/src/Events/BindKey.h new file mode 100644 index 0000000..a774942 --- /dev/null +++ b/src/Events/BindKey.h @@ -0,0 +1,17 @@ +#ifndef Events_BindKey_h__ +#define Events_BindKey_h__ + +#include "EventBroker.h" + +namespace Events +{ + +struct BindKey : Event +{ + int KeyCode; + std::string Command; +}; + +} + +#endif // Events_BindKey_h__ \ No newline at end of file diff --git a/src/Events/BindMouseButton.h b/src/Events/BindMouseButton.h new file mode 100644 index 0000000..1f46647 --- /dev/null +++ b/src/Events/BindMouseButton.h @@ -0,0 +1,17 @@ +#ifndef Events_BindMouseButton_h__ +#define Events_BindMouseButton_h__ + +#include "EventBroker.h" + +namespace Events +{ + +struct BindMouseButton : Event +{ + int Button; + std::string Command; +}; + +} + +#endif // Events_BindMouseButton_h__ \ No newline at end of file diff --git a/src/Events/InputCommand.h b/src/Events/InputCommand.h new file mode 100644 index 0000000..bd18f6a --- /dev/null +++ b/src/Events/InputCommand.h @@ -0,0 +1,20 @@ +#ifndef Events_InputCommand_h__ +#define Events_InputCommand_h__ + +#include + +#include "EventBroker.h" + +namespace Events +{ + +struct InputCommand : Event +{ + unsigned int PlayerID; + std::string Command; + boost::any Value; +}; + +} + +#endif // Events_InputCommand_h__ \ No newline at end of file diff --git a/src/Events/KeyDown.h b/src/Events/KeyDown.h new file mode 100644 index 0000000..0864862 --- /dev/null +++ b/src/Events/KeyDown.h @@ -0,0 +1,16 @@ +#ifndef Events_KeyDown_h__ +#define Events_KeyDown_h__ + +#include "EventBroker.h" + +namespace Events +{ + +struct KeyDown : Event +{ + int KeyCode; +}; + +} + +#endif // Events_KeyDown_h__ \ No newline at end of file diff --git a/src/Events/KeyUp.h b/src/Events/KeyUp.h new file mode 100644 index 0000000..9fcbf83 --- /dev/null +++ b/src/Events/KeyUp.h @@ -0,0 +1,16 @@ +#ifndef Events_KeyUp_h__ +#define Events_KeyUp_h__ + +#include "EventBroker.h" + +namespace Events +{ + +struct KeyUp : Event +{ + int KeyCode; +}; + +} + +#endif // Events_KeyUp_h__ \ No newline at end of file diff --git a/src/Events/MouseMove.h b/src/Events/MouseMove.h new file mode 100644 index 0000000..2d668a1 --- /dev/null +++ b/src/Events/MouseMove.h @@ -0,0 +1,17 @@ +#ifndef Events_MouseMove_h__ +#define Events_MouseMove_h__ + +#include "EventBroker.h" + +namespace Events +{ + +struct MouseMove : Event +{ + double X, Y; + double DeltaX, DeltaY; +}; + +} + +#endif // Events_MouseMove_h__ \ No newline at end of file diff --git a/src/Events/MousePress.h b/src/Events/MousePress.h new file mode 100644 index 0000000..3116edb --- /dev/null +++ b/src/Events/MousePress.h @@ -0,0 +1,16 @@ +#ifndef Events_MousePress_h__ +#define Events_MousePress_h__ + +#include "EventBroker.h" + +namespace Events +{ + +struct MousePress : Event +{ + int Button; +}; + +} + +#endif // Events_MousePress_h__ \ No newline at end of file diff --git a/src/Events/MouseRelease.h b/src/Events/MouseRelease.h new file mode 100644 index 0000000..7249dcd --- /dev/null +++ b/src/Events/MouseRelease.h @@ -0,0 +1,16 @@ +#ifndef Events_MouseRelease_h__ +#define Events_MouseRelease_h__ + +#include "EventBroker.h" + +namespace Events +{ + +struct MouseRelease : Event +{ + int Button; +}; + +} + +#endif // Events_MouseRelease_h__ \ No newline at end of file diff --git a/src/Events/PlaySound.h b/src/Events/PlaySound.h new file mode 100644 index 0000000..e00ef73 --- /dev/null +++ b/src/Events/PlaySound.h @@ -0,0 +1,17 @@ +#ifndef Event_PlaySound_h__ +#define Event_PlaySound_h__ + +#include "EventBroker.h" + +namespace Events +{ + +struct PlaySound : Event +{ + EntityID Emitter; + std::string Resource; +}; + +} + +#endif // Event_PlaySound_h__ diff --git a/src/GUI/Frame.h b/src/GUI/Frame.h new file mode 100644 index 0000000..19f534a --- /dev/null +++ b/src/GUI/Frame.h @@ -0,0 +1,49 @@ +#ifndef GUI_Frame_h__ +#define GUI_Frame_h__ + +#include + +#include "Util/Rectangle.h" +#include "EventBroker.h" + +namespace GUI +{ + +class Frame : public Rectangle +{ +public: + enum class Anchor + { + Left, + Right, + Top, + Bottom + }; + + // Set up a base frame with an event broker + Frame(std::shared_ptr<::EventBroker> eventBroker) + : EventBroker(eventBroker) + , Rectangle() + { Initialize(); } + // Create a frame as a child + Frame(std::shared_ptr parent) + : Rectangle(static_cast(*parent)) // Clone parent rectangle using copy constructor + { SetParent(parent); Initialize(); } + + virtual void Initialize() { } + std::shared_ptr Parent() const { return m_Parent; } + void SetParent(std::shared_ptr parent) + { + m_Parent = parent; + EventBroker = parent->EventBroker; + } + virtual void Update(double dt) { } + +protected: + std::shared_ptr<::EventBroker> EventBroker; + std::shared_ptr m_Parent; +}; + +} + +#endif // GUI_Frame_h__ diff --git a/src/GUI/Viewport.h b/src/GUI/Viewport.h new file mode 100644 index 0000000..b4568b5 --- /dev/null +++ b/src/GUI/Viewport.h @@ -0,0 +1,21 @@ +#ifndef GUI_Viewport_h__ +#define GUI_Viewport_h__ + +#include + +#include "GUI/Frame.h" + +namespace GUI +{ + +class Viewport : public Frame +{ +public: + // Create a frame as a child + Viewport(std::shared_ptr parent) + : Frame(parent) { } +}; + +} + +#endif // GUI_Viewport_h__ diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 0b19842..18ab5a2 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -8,6 +8,18 @@ void GameWorld::Initialize() m_ResourceManager.Preload("Model", "Models/Placeholders/PhysicsTest/Plane.obj"); m_ResourceManager.Preload("Model", "Models/Placeholders/PhysicsTest/ArrowCube.obj"); + BindKey(GLFW_KEY_W, "+forward"); + BindKey(GLFW_KEY_S, "+backward"); + BindKey(GLFW_KEY_A, "+left"); + BindKey(GLFW_KEY_D, "+right"); + BindKey(GLFW_KEY_SPACE, "+up"); + BindKey(GLFW_KEY_LEFT_CONTROL, "+down"); + BindKey(GLFW_KEY_LEFT_ALT, "+slow"); + BindKey(GLFW_KEY_LEFT_SHIFT, "+fast"); + BindMouseButton(GLFW_MOUSE_BUTTON_1, "+attack"); + BindMouseButton(GLFW_MOUSE_BUTTON_2, "+attack2"); + BindMouseButton(GLFW_MOUSE_BUTTON_3, "+attack3"); + RegisterComponents(); { @@ -15,111 +27,239 @@ void GameWorld::Initialize() 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)); + //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, 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 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"; - }*/ - - /*for(int i = 0; i < 2; 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 jeep = CreateEntity(); + auto transform = AddComponent(jeep, "Transform"); + transform->Position = glm::vec3(0, 2, 0); - 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 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"); - auto model = AddComponent(light, "Model"); - model->ModelFile = "Models/Placeholders/PhysicsTest/PointLight.obj"; - }*/ + AddComponent(jeep, "Input"); - /*for(int i = 0; i < 3; i++) + { + 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 = 50; + Wheel->Radius = 0.837f; + Wheel->Steering = true; + Wheel->SuspensionStrength = 40.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 = 50; + Wheel->Radius = 0.837f; + Wheel->Steering = true; + Wheel->SuspensionStrength = 40.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 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.05; - auto physics = AddComponent(ball, "Physics"); - physics->Mass = 1; - }*/ + 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); - }*/ - - { - for(int i = 0; i < 1 ; i++) - { - // Particle emitter - auto ent = CreateEntity(); - auto transform = AddComponent(ent, "Transform"); - transform->Orientation = glm::angleAxis(glm::pi()/2, glm::vec3(1,0,0)); - transform->Position = glm::vec3(i * 10, 20, 0); - - auto emitter = AddComponent(ent, "ParticleEmitter"); - emitter->LifeTime = 0.3; - emitter->SpawnCount = 1; - emitter->SpreadAngle = glm::pi()/4; - emitter->SpawnFrequency = 0.0008; - emitter->ScaleSpectrum.push_back(glm::vec3(0.05f)); - emitter->UseGoalVelocity = false; - emitter->GoalVelocity = glm::vec3(4, -4, 0); -// emitter->OrientationSpectrum.push_back(glm::vec3(0, 1, 0)); -// emitter->OrientationSpectrum.push_back(glm::vec3(0, -1, 0)); - emitter->AngularVelocitySpectrum.push_back(glm::pi() / 100); - auto model = AddComponent(ent, "Model"); - model->ModelFile = "Models/Placeholders/PhysicsTest/PointLight.obj"; - - auto particleEnt = CreateEntity(); - AddComponent(particleEnt, "Transform"); - auto spriteComponent = AddComponent(particleEnt, "Sprite"); - spriteComponent->SpriteFile = "Textures/Sprites/SeriousParticle.png"; - emitter->ParticleTemplate = particleEnt; - } + //GetSystem("SoundSystem")->PlaySound(emitter); + CommitEntity(entity); } } @@ -132,22 +272,21 @@ void GameWorld::RegisterComponents() { m_ComponentFactory.Register("Transform", []() { return new Components::Transform(); }); m_ComponentFactory.Register("Template", []() { return new Components::Template(); }); - m_ComponentFactory.Register("Sphere", []() { return new Components::Sphere(); }); - m_ComponentFactory.Register("Box", []() { return new Components::Box (); }); } void GameWorld::RegisterSystems() { - m_SystemFactory.Register("TransformSystem", [this]() { return new Systems::TransformSystem(this); }); + m_SystemFactory.Register("TransformSystem", [this]() { return new Systems::TransformSystem(this, m_EventBroker); }); //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("InputSystem", [this]() { return new Systems::InputSystem(this, m_EventBroker); }); + m_SystemFactory.Register("DebugSystem", [this]() { return new Systems::DebugSystem(this, m_EventBroker); }); //m_SystemFactory.Register("CollisionSystem", [this]() { return new Systems::CollisionSystem(this); }); - m_SystemFactory.Register("ParticleSystem", [this]() { return new Systems::ParticleSystem(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); }); + m_SystemFactory.Register("FreeSteeringSystem", [this]() { return new Systems::FreeSteeringSystem(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); }); } void GameWorld::AddSystems() @@ -155,11 +294,28 @@ void GameWorld::AddSystems() AddSystem("TransformSystem"); //AddSystem("LevelGenerationSystem"); AddSystem("InputSystem"); + AddSystem("DebugSystem"); //AddSystem("CollisionSystem"); - AddSystem("ParticleSystem"); + ////AddSystem("ParticleSystem"); //AddSystem("PlayerSystem"); AddSystem("FreeSteeringSystem"); AddSystem("SoundSystem"); AddSystem("PhysicsSystem"); AddSystem("RenderSystem"); -} \ No newline at end of file +} + +void GameWorld::BindKey(int keyCode, std::string command) +{ + Events::BindKey e; + e.KeyCode = keyCode; + e.Command = command; + m_EventBroker->Publish(e); +} + +void GameWorld::BindMouseButton(int button, std::string command) +{ + Events::BindMouseButton e; + e.Button = button; + e.Command = command; + m_EventBroker->Publish(e); +} diff --git a/src/GameWorld.h b/src/GameWorld.h index 4f74358..45d9f98 100755 --- a/src/GameWorld.h +++ b/src/GameWorld.h @@ -7,6 +7,7 @@ #include "Systems/TransformSystem.h" //#include "Systems/CollisionSystem.h" #include "Systems/InputSystem.h" +#include "Systems/DebugSystem.h" //#include "Systems/LevelGenerationSystem.h" #include "Systems/ParticleSystem.h" //#include "Systems/PlayerSystem.h" @@ -30,12 +31,14 @@ #include "Components/Physics.h" #include "Components/Sphere.h" #include "Components/Box.h" +#include "Components/Vehicle.h" +#include "Components/Wheel.h" class GameWorld : public World { public: - GameWorld(std::shared_ptr renderer) - : m_Renderer(renderer), World() { } + GameWorld(std::shared_ptr<::EventBroker> eventBroker, std::shared_ptr renderer) + : World(eventBroker), m_Renderer(renderer) { } void Initialize(); @@ -47,6 +50,9 @@ public: private: std::shared_ptr m_Renderer; + + void BindKey(int keyCode, std::string command); + void BindMouseButton(int button, std::string command); }; #endif // GameWorld_h__ diff --git a/src/InputController.h b/src/InputController.h new file mode 100644 index 0000000..7afd5d5 --- /dev/null +++ b/src/InputController.h @@ -0,0 +1,33 @@ +#ifndef InputController_h__ +#define InputController_h__ + +#include + +#include "EventBroker.h" +#include "Events/InputCommand.h" +#include "Events/MouseMove.h" + +class InputController +{ +public: + InputController(std::shared_ptr<::EventBroker> eventBroker) + : EventBroker(eventBroker) { Initialize(); } + + virtual void Initialize() + { + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &InputController::OnCommand); + EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &InputController::OnMouseMove); + } + + virtual bool OnCommand(const Events::InputCommand &event) { return false; } + virtual bool OnMouseMove(const Events::MouseMove &event) { return false; } + +protected: + std::shared_ptr<::EventBroker> EventBroker; + +private: + EventRelay m_EInputCommand; + EventRelay m_EMouseMove; +}; + +#endif // InputController_h__ diff --git a/src/InputManager.cpp b/src/InputManager.cpp new file mode 100644 index 0000000..9f09b1c --- /dev/null +++ b/src/InputManager.cpp @@ -0,0 +1,86 @@ +#include "PrecompiledHeader.h" +#include "InputManager.h" + +void InputManager::Update(double dt) +{ + m_LastKeyState = m_CurrentKeyState; + m_LastMouseState = m_CurrentMouseState; + m_LastMouseX = m_CurrentMouseX; + m_LastMouseY = m_CurrentMouseY; + + // Keyboard input + for (int i = 0; i <= GLFW_KEY_LAST; ++i) + { + m_CurrentKeyState[i] = glfwGetKey(m_GLFWWindow, i); + if (m_CurrentKeyState[i] != m_LastKeyState[i]) + { + // Publish key events + if (m_CurrentKeyState[i]) + { + Events::KeyDown e; + e.KeyCode = i; + m_EventBroker->Publish(e); + } + else + { + Events::KeyUp e; + e.KeyCode = i; + m_EventBroker->Publish(e); + } + } + } + + // Mouse buttons + for (int i = 0; i <= GLFW_MOUSE_BUTTON_LAST; ++i) + { + m_CurrentMouseState[i] = glfwGetMouseButton(m_GLFWWindow, i); + if (m_CurrentMouseState[i] != m_LastMouseState[i]) + { + // Publish mouse button events + if (m_CurrentMouseState[i]) + { + Events::MousePress e; + e.Button = i; + m_EventBroker->Publish(e); + } + else + { + Events::MouseRelease e; + e.Button = i; + m_EventBroker->Publish(e); + } + } + } + + // Cursor position + glfwGetCursorPos(m_GLFWWindow, &m_CurrentMouseX, &m_CurrentMouseY); + m_CurrentMouseDeltaX = m_CurrentMouseX - m_LastMouseX; + m_CurrentMouseDeltaY = m_CurrentMouseY - m_LastMouseY; + if (m_CurrentMouseDeltaX != 0 || m_CurrentMouseDeltaY != 0) + { + // Publish mouse move events + Events::MouseMove e; + e.X = m_CurrentMouseX; + e.Y = m_CurrentMouseY; + e.DeltaX = m_CurrentMouseDeltaX; + e.DeltaY = m_CurrentMouseDeltaY; + m_EventBroker->Publish(e); + } + + // // Lock mouse while holding LMB + // if (m_CurrentMouseState[GLFW_MOUSE_BUTTON_LEFT]) + // { + // m_LastMouseX = m_Renderer->Width() / 2.f; // xpos; + // m_LastMouseY = m_Renderer->Height() / 2.f; // ypos; + // glfwSetCursorPos(m_GLFWWindow, m_LastMouseX, m_LastMouseY); + // } + // // Hide/show cursor with LMB + // if (m_CurrentMouseState[GLFW_MOUSE_BUTTON_LEFT] && !m_LastMouseState[GLFW_MOUSE_BUTTON_LEFT]) + // { + // glfwSetInputMode(m_GLFWWindow, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + // } + // if (!m_CurrentMouseState[GLFW_MOUSE_BUTTON_LEFT] && m_LastMouseState[GLFW_MOUSE_BUTTON_LEFT]) + // { + // glfwSetInputMode(m_GLFWWindow, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + // } +} diff --git a/src/InputManager.h b/src/InputManager.h new file mode 100644 index 0000000..5acaaa2 --- /dev/null +++ b/src/InputManager.h @@ -0,0 +1,42 @@ +#ifndef InputManager_h__ +#define InputManager_h__ + +#include + +#include "EventBroker.h" +#include "Events/KeyDown.h" +#include "Events/KeyUp.h" +#include "Events/MousePress.h" +#include "Events/MouseRelease.h" +#include "Events/MouseMove.h" + +class InputManager +{ +public: + InputManager(GLFWwindow* window, std::shared_ptr eventBroker) + : m_GLFWWindow(window) + , m_EventBroker(eventBroker) + , m_CurrentKeyState() + , m_LastKeyState() + , m_CurrentMouseState() + , m_LastMouseState() + , m_CurrentMouseX(0), m_CurrentMouseY(0) + , m_LastMouseX(0), m_LastMouseY(0) + , m_CurrentMouseDeltaX(0), m_CurrentMouseDeltaY(0) { } + + void Update(double dt); + +private: + GLFWwindow* m_GLFWWindow; + std::shared_ptr m_EventBroker; + + std::array m_CurrentKeyState; + std::array m_LastKeyState; + std::array m_CurrentMouseState; + std::array m_LastMouseState; + double m_CurrentMouseX, m_CurrentMouseY; + double m_LastMouseX, m_LastMouseY; + double m_CurrentMouseDeltaX, m_CurrentMouseDeltaY; +}; + +#endif // InputManager_h__ diff --git a/src/Model.cpp b/src/Model.cpp index 5f10f29..547e940 100755 --- a/src/Model.cpp +++ b/src/Model.cpp @@ -17,11 +17,19 @@ Model::Model(OBJ &obj, ResourceManager* rm) if (face.Material != currentMaterial) { currentMaterial = face.Material; + // Load texture - auto texture = std::shared_ptr(rm->Load("Texture", currentMaterial->TextureFile)); + auto texture = std::shared_ptr(rm->Load("Texture", currentMaterial->DiffuseTexture.FileName)); + // TODO: Load normal map + std::shared_ptr normalMap = nullptr; + // Load specular map + std::shared_ptr specularMap = nullptr; + if (!currentMaterial->SpecularMap.FileName.empty()) + specularMap = std::shared_ptr(rm->Load("Texture", currentMaterial->SpecularMap.FileName)); + // TODO: Load material parameters // Create new texture group (start index of new group is upcoming index) - TextureGroup texGroup = { texture, index, index }; + TextureGroup texGroup = { texture, normalMap, specularMap, index, index }; TextureGroups.push_back(texGroup); currentTexGroup = &TextureGroups.back(); } diff --git a/src/Model.h b/src/Model.h index e1d7fa6..8d94a7d 100755 --- a/src/Model.h +++ b/src/Model.h @@ -21,7 +21,9 @@ public: struct TextureGroup { - std::shared_ptr Texture; + std::shared_ptr<::Texture> Texture; + std::shared_ptr<::Texture> NormalMap; + std::shared_ptr<::Texture> SpecularMap; unsigned int StartIndex; unsigned int EndIndex; }; diff --git a/src/OBJ.cpp b/src/OBJ.cpp index 683f9e2..a8b9f03 100755 --- a/src/OBJ.cpp +++ b/src/OBJ.cpp @@ -126,9 +126,11 @@ void OBJ::ParseMaterial() std::string currentMaterialName; MaterialInfo* currentMaterial = nullptr; + unsigned int currentLine = 0; std::string line; while (std::getline(file, line)) { + currentLine++; if (line.length() == 0) continue; @@ -140,19 +142,7 @@ void OBJ::ParseMaterial() // Create a new material definition if (prefix == "newmtl") { - MaterialInfo mat = - { - "", - std::make_tuple(0.2f, 0.2f, 0.2f), - std::make_tuple(0.8f, 0.8f, 0.8f), - std::make_tuple(1.0f, 1.0f, 1.0f), - std::make_tuple(1.0f, 1.0f, 1.0f), - 1.0f, - 1.0f, - 0.0f, - 0, - }; - + MaterialInfo mat; ss >> currentMaterialName; LOG_INFO("Parsing material %s", currentMaterialName.c_str()); Materials[currentMaterialName] = mat; @@ -243,14 +233,177 @@ void OBJ::ParseMaterial() currentMaterial->IlluminationModel = illum; continue; } - // Texture file - // TODO: - if (prefix == "map_Ka" || prefix == "map_Kd") + // Diffuse texture + if (prefix == "map_Kd") { - std::string textureFile; - ss >> textureFile; - currentMaterial->TextureFile = (m_MaterialPath.branch_path() / textureFile).string(); + MaterialInfo::ColorMap colorMap; + + std::string fileName; + std::string arg; + while (ss >> arg) + { + ParseColorMap(currentLine, ss, prefix, arg, colorMap); + } + + // HACK: Should we really have to specify the full path here? + colorMap.FileName = (m_MaterialPath.branch_path() / colorMap.FileName).string(); + currentMaterial->DiffuseTexture = colorMap; + continue; + } + // Specular map + if (prefix == "map_Ks") + { + MaterialInfo::ColorMap colorMap; + + std::string fileName; + std::string arg; + while (ss >> arg) + { + ParseColorMap(currentLine, ss, prefix, arg, colorMap); + } + + // HACK: Should we really have to specify the full path here? + colorMap.FileName = (m_MaterialPath.branch_path() / colorMap.FileName).string(); + currentMaterial->SpecularMap = colorMap; + continue; + } + // Normal map (bump map) + if (prefix == "bump") + { + MaterialInfo::BumpMap bumpMap; + + std::string fileName; + std::string arg; + while (ss >> arg) + { + ParseBumpMap(currentLine, ss, prefix, arg, bumpMap); + } + + // HACK: Should we really have to specify the full path here? + bumpMap.FileName = (m_MaterialPath.branch_path() / bumpMap.FileName).string(); + currentMaterial->NormalMap = bumpMap; continue; } } } + +void OBJ::ParseTextureMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::TextureMap &textureMap) +{ + if (arg == "-blendu") + { + std::string val; + ss >> val; + if (val == "off") + textureMap.blendu = false; + else if (val == "on") + textureMap.blendu = true; + else + LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line); + } + else if (arg == "-blendv") + { + std::string val; + ss >> val; + if (val == "off") + textureMap.blendv = false; + else if (val == "on") + textureMap.blendv = true; + else + LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line); + } + else if (arg == "-clamp") + { + std::string val; + ss >> val; + if (val == "off") + textureMap.clamp = false; + else if (val == "on") + textureMap.clamp = true; + else + LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line); + } + else if (arg == "-o") + { + float u, v, w; + if (ss >> u >> v >> w) + { + textureMap.o = std::make_tuple(u, v, w); + } + else + { + LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line); + } + } + else if (arg == "-s") + { + float u, v, w; + if (ss >> u >> v >> w) + { + textureMap.s = std::make_tuple(u, v, w); + } + else + { + LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line); + } + } + // Assume unrecognized options is part of the file name + else + { + if (!textureMap.FileName.empty()) + textureMap.FileName += " "; + textureMap.FileName += arg; + } +} + +void OBJ::ParseColorMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::ColorMap &colorMap) +{ + if (arg == "-cc") + { + if (prefix != "map_Kd" || prefix != "map_Ks") + { + LOG_ERROR("Invalid MTL argument \"%s\" to option \"%s\" on line %i", arg.c_str(), prefix.c_str(), line); + return; + } + + std::string val; + if (ss >> val) + { + if (val == "off") + colorMap.cc = false; + else if (val == "on") + colorMap.cc = true; + else + LOG_ERROR("Unrecognized MTL value \"%s\" to argument \"%s %s\" on line %i", val.c_str(), prefix.c_str(), arg.c_str(), line); + } + else + { + LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line); + } + } + else + { + ParseTextureMap(line, ss, prefix, arg, colorMap); + } +} + +void OBJ::ParseBumpMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::BumpMap &bumpMap) +{ + if (arg == "-bm") + { + if (prefix != "bump") + { + LOG_ERROR("Invalid MTL argument \"%s\" to option \"%s\" on line %i", arg.c_str(), prefix.c_str(), line); + return; + } + + float val; + if (ss >> val) + bumpMap.bm = val; + else + LOG_ERROR("Unrecognized MTL value to argument \"%s %s\" on line %i", prefix.c_str(), arg.c_str(), line); + } + else + { + ParseTextureMap(line, ss, prefix, arg, bumpMap); + } +} \ No newline at end of file diff --git a/src/OBJ.h b/src/OBJ.h index 62bce8d..2ef10e0 100755 --- a/src/OBJ.h +++ b/src/OBJ.h @@ -10,21 +10,78 @@ #include #include +#include class OBJ { public: struct MaterialInfo { - std::string TextureFile; - std::tuple AmbientColor; - std::tuple DiffuseColor; - std::tuple SpecularColor; - std::tuple TransmissionFilter; - float OpticalDensity; - float Alpha; - float Shininess; - int IlluminationModel; + struct TextureMap + { + TextureMap() + : blendu(true) + , blendv(true) + , clamp(false) + , o(std::make_tuple(0.f, 0.f, 0.f)) + , s(std::make_tuple(1.f, 1.f, 1.f)) { } + + std::string FileName; + + // http://paulbourke.net/dataformats/mtl/ + // "These options are described in detail in 'Options for texture map statements' on page 5-18." + + // Horizontal texture blending + bool blendu; // = true + // Vertical texture blending + bool blendv; // = true + // Clamping + bool clamp; // = false + // Offset + std::tuple o; // = (0, 0, 0) + // Scale + std::tuple s; // = (1, 1, 1) + }; + + struct ColorMap : public TextureMap + { + ColorMap() + : cc(false) { } + + // Color correction + bool cc; // = false + }; + + struct BumpMap : public TextureMap + { + BumpMap() + : bm(1.f) { } + + // Bump multiplier + float bm; // = 1? + }; + + MaterialInfo() + : AmbientColor(std::make_tuple(0.2f, 0.2f, 0.2f)) + , DiffuseColor(std::make_tuple(0.8f, 0.8f, 0.8f)) + , SpecularColor(std::make_tuple(1.0f, 1.0f, 1.0f)) + , TransmissionFilter(std::make_tuple(1.0f, 1.0f, 1.0f)) + , OpticalDensity(1.0f) + , Alpha(1.0f) + , Shininess(0.0f) + , IlluminationModel(0) { } + + ColorMap DiffuseTexture; + ColorMap SpecularMap; + BumpMap NormalMap; + std::tuple AmbientColor; // = (0.2, 0.2, 0.2) + std::tuple DiffuseColor; // = (0.8, 0.8, 0.8) + std::tuple SpecularColor; // = (1, 1, 1) + std::tuple TransmissionFilter; // = (1, 1, 1) + float OpticalDensity; // = 1 + float Alpha; // = 1 + float Shininess; // = 0 + int IlluminationModel; // = 0 }; struct FaceDefinition @@ -59,6 +116,9 @@ private: MaterialInfo* m_CurrentMaterial; void ParseMaterial(); + void ParseTextureMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::TextureMap &textureMap); + void ParseColorMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::ColorMap &textureMap); + void ParseBumpMap(unsigned int line, std::stringstream &ss, std::string prefix, std::string arg, MaterialInfo::BumpMap &textureMap); }; #endif // OBJ_h__ \ No newline at end of file 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..1070692 --- /dev/null +++ b/src/Physics/VehicleSetup.h @@ -0,0 +1,64 @@ +#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/RenderQueue.h b/src/RenderQueue.h new file mode 100644 index 0000000..7439de2 --- /dev/null +++ b/src/RenderQueue.h @@ -0,0 +1,62 @@ +#ifndef RenderQueue_h__ +#define RenderQueue_h__ + +#include +#include + +#include "ResourceManager.h" +#include "Texture.h" +#include "Model.h" + +class RenderQueue; + +struct RenderJob +{ + friend class RenderQueue; + + unsigned int ViewportID; + unsigned int TextureID; + + GLuint DiffuseTexture; + GLuint NormalTexture; + GLuint SpecularTexture; + GLuint VAO; + unsigned int StartIndex; + unsigned int EndIndex; + glm::mat4 ModelMatrix; + +protected: + uint64_t Hash; + + void CalculateHash() + { + Hash = ViewportID << 58 // 6 bits + | TextureID << 42; // 16 bits + } + + bool operator<(const RenderJob& rhs) + { + return this->Hash < rhs.Hash; + } +}; + +class RenderQueue +{ +public: + void Add(RenderJob &job) + { + job.CalculateHash(); + m_Jobs.push_front(job); + m_Jobs.sort(); + } + + void Clear() + { + m_Jobs.clear(); + } + +private: + std::forward_list m_Jobs; +}; + +#endif // RenderQueue_h__ diff --git a/src/Renderer.cpp b/src/Renderer.cpp index f7960d5..99f27a9 100755 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -31,11 +31,11 @@ void Renderer::Initialize() } // Create a window - WIDTH = 1280; - HEIGHT = 720; + m_Width = 1280; + m_Height = 720; // Antialiasing //glfwWindowHint(GLFW_SAMPLES, 16); - m_Window = glfwCreateWindow(WIDTH, HEIGHT, "OpenGL", nullptr, nullptr); + m_Window = glfwCreateWindow(m_Width, m_Height, "OpenGL", nullptr, nullptr); if (!m_Window) { LOG_ERROR("GLFW: Failed to create window"); @@ -63,7 +63,7 @@ void Renderer::Initialize() } // Create Camera - m_Camera = std::make_shared(45.f, (float)WIDTH / HEIGHT, 0.01f, 1000.f); + m_Camera = std::make_shared(45.f, (float)m_Width / m_Height, 0.01f, 1000.f); m_Camera->Position(glm::vec3(0.0f, 0.0f, 2.f)); glfwSwapInterval(m_VSync); @@ -187,11 +187,11 @@ void Renderer::Draw(double dt) void Renderer::DrawSkybox() { glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, WIDTH, HEIGHT); + glViewport(0, 0, m_Width, m_Height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_ShaderProgramSkybox.Bind(); - glm::mat4 cameraMatrix = m_Camera->ProjectionMatrix() * glm::toMat4(m_Camera->Orientation()); + glm::mat4 cameraMatrix = m_Camera->ProjectionMatrix() * glm::toMat4(glm::inverse(m_Camera->Orientation())); glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgramSkybox.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(cameraMatrix)); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); m_Skybox->Draw(); @@ -200,7 +200,7 @@ void Renderer::DrawSkybox() void Renderer::DrawScene() { glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, WIDTH, HEIGHT); + glViewport(0, 0, m_Width, m_Height); glClear(GL_DEPTH_BUFFER_BIT); //glClearColor(1.0f, 1.0f, 0.0f, 1.0f); diff --git a/src/Renderer.h b/src/Renderer.h index 17485aa..26891d6 100755 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -20,7 +20,9 @@ public: glm::mat4 viewMatrix; glm::mat4 projectionMatrix; - int HEIGHT, WIDTH; + + int Width() const { return m_Width; } + int Height() const { return m_Height; } std::list> ModelsToRender; std::list> TexturesToRender; @@ -67,9 +69,8 @@ public: void DrawBounds(bool val) { m_DrawBounds = val; } void DrawSkybox(); - - private: + int m_Width, m_Height; GLFWwindow* m_Window; GLint m_glVersion[2]; GLchar* m_glVendor; diff --git a/src/ResourceManager.cpp b/src/ResourceManager.cpp index 4b864d6..1361c11 100644 --- a/src/ResourceManager.cpp +++ b/src/ResourceManager.cpp @@ -9,10 +9,6 @@ Resource* ResourceManager::CreateResource(std::string resourceType, std::string LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": Type not registered", resourceName.c_str(), resourceType.c_str()); return nullptr; } - - auto resIt = m_ResourceCache.find(resourceName); - if (resIt != m_ResourceCache.end()) - return resIt->second; // Call the factory function Resource* resource = facIt->second(resourceName); @@ -32,7 +28,16 @@ void ResourceManager::RegisterType(std::string resourceType, std::function factoryFunction); // Loads a resource and caches it for future use void Preload(std::string resourceType, std::string resourceName); - + + // Checks if a resource is in cache + bool IsResourceLoaded(std::string resourceName); + template // Hot-loads a resource and caches it for future use T* Load(std::string resourceType, std::string resourceName); @@ -44,6 +47,8 @@ private: std::unordered_map m_ResourceTypeIDs; // Number of resources of a type. Doubles as local ID. std::unordered_map m_ResourceCount; + // Flag to suppress hot-load warnings when a preloading resource chain loads another resource + bool m_Preloading; unsigned int GetTypeID(std::string resourceType); unsigned int GetNewResourceID(unsigned int typeID); @@ -55,20 +60,34 @@ private: template T* ResourceManager::Load(std::string resourceType, std::string resourceName) { + auto it = m_ResourceCache.find(resourceName); + if (it != m_ResourceCache.end()) + return static_cast(it->second); + + if (m_Preloading) + { + LOG_INFO("Preloading resource \"%s\"", resourceName.c_str()); + } + else + { + LOG_WARNING("Hot-loading resource \"%s\"", resourceName.c_str()); + } + return static_cast(CreateResource(resourceType, resourceName)); } template T* ResourceManager::Fetch(std::string resourceName) const { - if (m_ResourceCache.find(resourceName) == m_ResourceCache.end()) + auto it = m_ResourceCache.find(resourceName); + if (it == m_ResourceCache.end()) { LOG_ERROR("Failed to fetch resource \"%s\": Resource not loaded!", resourceName.c_str()); return nullptr; } else { - return static_cast(m_ResourceCache.at(resourceName)); + return static_cast(it->second); } } 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/System.h b/src/System.h index 0cd3cc7..b40bdef 100755 --- a/src/System.h +++ b/src/System.h @@ -4,6 +4,7 @@ #include "Factory.h" #include "Entity.h" #include "Component.h" +#include "EventBroker.h" #include "ResourceManager.h" class World; @@ -11,7 +12,9 @@ class World; class System { public: - System(World* world) : m_World(world) { } + System(World* world, std::shared_ptr eventBroker) + : m_World(world) + , EventBroker(eventBroker) { } virtual ~System() { } virtual void RegisterComponents(ComponentFactory* cf) { } @@ -28,9 +31,12 @@ public: virtual void OnComponentCreated(std::string type, std::shared_ptr component) { } // Called when a component is removed virtual void OnComponentRemoved(std::string type, Component* component) { } + // Called when components are committed to an entity + virtual void OnEntityCommit(EntityID entity) { } protected: World* m_World; + std::shared_ptr EventBroker; }; class SystemFactory : public Factory { }; diff --git a/src/Systems/DebugSystem.cpp b/src/Systems/DebugSystem.cpp index 964aa9f..f076664 100644 --- a/src/Systems/DebugSystem.cpp +++ b/src/Systems/DebugSystem.cpp @@ -2,3 +2,30 @@ #include "DebugSystem.h" #include "World.h" + +void Systems::DebugSystem::Initialize() +{ + // Subscribe to events + m_EKeyDown = decltype(m_EKeyDown)(std::bind(&Systems::DebugSystem::OnKeyDown, this, std::placeholders::_1)); + EventBroker->Subscribe(m_EKeyDown); +} + +void Systems::DebugSystem::Update(double dt) +{ + +} + +bool Systems::DebugSystem::OnKeyDown(const Events::KeyDown &event) +{ + if (event.KeyCode == GLFW_KEY_ENTER) + { + Events::PlaySound e; + e.Emitter = 0; + e.Resource = "Sounds/korvring.wav"; + EventBroker->Publish(e); + + return true; + } + + return false; +} diff --git a/src/Systems/DebugSystem.h b/src/Systems/DebugSystem.h index accaa8c..9db4de6 100644 --- a/src/Systems/DebugSystem.h +++ b/src/Systems/DebugSystem.h @@ -3,6 +3,8 @@ #include "System.h" #include "Components/Transform.h" +#include "Events/KeyDown.h" +#include "Events/PlaySound.h" namespace Systems { @@ -10,10 +12,16 @@ namespace Systems class DebugSystem : public System { public: - DebugSystem(World* world) - : System(world) { } + DebugSystem(World* world, std::shared_ptr<::EventBroker> eventBroker) + : System(world, eventBroker) { } + + void Initialize() override; void Update(double dt) override; + + EventRelay m_EKeyDown; + bool OnKeyDown(const Events::KeyDown &event); + //void UpdateEntity(double dt, EntityID entity, EntityID parent) override; }; diff --git a/src/Systems/FreeSteeringSystem.cpp b/src/Systems/FreeSteeringSystem.cpp index 407200b..b382b23 100755 --- a/src/Systems/FreeSteeringSystem.cpp +++ b/src/Systems/FreeSteeringSystem.cpp @@ -7,65 +7,127 @@ void Systems::FreeSteeringSystem::RegisterComponents(ComponentFactory* cf) cf->Register("FreeSteering", []() { return new Components::FreeSteering(); }); } +void Systems::FreeSteeringSystem::Initialize() +{ + m_InputController = std::unique_ptr(new FreeSteeringInputController(EventBroker)); +} + void Systems::FreeSteeringSystem::Update(double dt) { - + } void Systems::FreeSteeringSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) { auto steering = m_World->GetComponent(entity, "FreeSteering"); - auto input = m_World->GetComponent(entity, "Input"); - if (steering && input) + if (steering) { auto transform = m_World->GetComponent(entity, "Transform"); - glm::vec3 Camera_Right = glm::vec3(glm::vec4(1, 0, 0, 0) * transform->Orientation); - glm::vec3 Camera_Forward = glm::vec3(glm::vec4(0, 0, 1, 0) * transform->Orientation); - - float speed = steering->Speed; - if (input->KeyState[GLFW_KEY_LEFT_SHIFT]) - { - speed *= 4.0f; - } - if (input->KeyState[GLFW_KEY_LEFT_ALT]) - { - speed /= 4.0f; - } - if (input->KeyState[GLFW_KEY_A]) - { - transform->Position -= Camera_Right * (float)dt * speed; - } - else if (input->KeyState[GLFW_KEY_D]) - { - transform->Position += Camera_Right * (float)dt * speed; - } - if (input->KeyState[GLFW_KEY_W]) - { - transform->Position -= Camera_Forward * (float)dt * speed; - } - if (input->KeyState[GLFW_KEY_S]) - { - transform->Position += Camera_Forward * (float)dt * speed; - } - if (input->KeyState[GLFW_KEY_SPACE]) - { - transform->Position += glm::vec3(0, 1, 0) * (float)dt * speed; - } - if (input->KeyState[GLFW_KEY_LEFT_CONTROL]) - { - transform->Position -= glm::vec3(0, 1, 0) * (float)dt * speed; - } - - if (input->MouseState[GLFW_MOUSE_BUTTON_LEFT]) - { - // TOUCHING THIS CODE MIGHT CAUSE THE UNIVERSE TO IMPLODE, ALSO DRAGONS // spelling tobias :3 - //--------------------------------------------------------------------- - transform->Orientation = glm::angleAxis(input->dY / 300.f, glm::vec3(1, 0, 0)) * transform->Orientation; - - transform->Orientation = transform->Orientation * glm::angleAxis(input->dX / 300.f, glm::vec3(0, 1, 0)); - //--------------------------------------------------------------------- - // TOUCHING THIS CODE MIGHT CAUSE THE UNIVERSE TO IMPLODE, ALSO DRAGONS - } + glm::vec3 cameraRight = glm::vec3(m_InputController->Orientation * glm::vec4(1, 0, 0, 0)); + glm::vec3 cameraForward = glm::vec3(m_InputController->Orientation * glm::vec4(0, 0, -1, 0)); + glm::vec3 movement; + movement += cameraRight * m_InputController->Movement.x; + movement.y += m_InputController->Movement.y; + movement += cameraForward * -m_InputController->Movement.z; + transform->Position += movement * steering->Speed * m_InputController->SpeedMultiplier * (float)dt; + transform->Orientation = m_InputController->Orientation; } } + +bool Systems::FreeSteeringSystem::FreeSteeringInputController::OnCommand(const Events::InputCommand &event) +{ + // Movement + if (event.Command == "+forward") + { + Movement.z += -1.f; + } + else if (event.Command == "-forward") + { + Movement.z -= -1.f; + } + else if (event.Command == "+backward") + { + Movement.z += 1.f; + } + else if (event.Command == "-backward") + { + Movement.z -= 1.f; + } + else if (event.Command == "+right") + { + Movement.x += 1.f; + } + else if (event.Command == "-right") + { + Movement.x -= 1.f; + } + else if (event.Command == "+left") + { + Movement.x += -1.f; + } + else if (event.Command == "-left") + { + Movement.x -= -1.f; + } + else if (event.Command == "+up") + { + Movement.y += 1.f; + } + else if (event.Command == "-up") + { + Movement.y -= 1.f; + } + else if (event.Command == "+down") + { + Movement.y += -1.f; + } + else if (event.Command == "-down") + { + Movement.y -= -1.f; + } + + // Speed + else if (event.Command == "+fast") + { + SpeedMultiplier *= 4.f; + } + else if (event.Command == "-fast") + { + SpeedMultiplier /= 4.f; + } + else if (event.Command == "+slow") + { + SpeedMultiplier /= 4.f; + } + else if (event.Command == "-slow") + { + SpeedMultiplier *= 4.f; + } + + // Mouse click + else if (event.Command == "+attack") + { + OrientationActive = true; + } + else if (event.Command == "-attack") + { + OrientationActive = false; + } + + return true; +} + +bool Systems::FreeSteeringSystem::FreeSteeringInputController::OnMouseMove(const Events::MouseMove &event) +{ + if (OrientationActive) + { + // TOUCHING THIS CODE MIGHT CAUSE THE UNIVERSE TO IMPLODE, ALSO DRAGONS + //--------------------------------------------------------------------- + Orientation = glm::angleAxis(event.DeltaX / 300.f, glm::vec3(0, -1, 0)) * Orientation * glm::angleAxis(event.DeltaY / 300.f, glm::vec3(-1, 0, 0)); + //--------------------------------------------------------------------- + // TOUCHING THIS CODE MIGHT CAUSE THE UNIVERSE TO IMPLODE, ALSO DRAGONS + } + + return true; +} diff --git a/src/Systems/FreeSteeringSystem.h b/src/Systems/FreeSteeringSystem.h index 11b86ae..4535cbb 100755 --- a/src/Systems/FreeSteeringSystem.h +++ b/src/Systems/FreeSteeringSystem.h @@ -2,19 +2,46 @@ #include "System.h" #include "Components/Transform.h" -#include "Components/Input.h" #include "Components/FreeSteering.h" +#include "InputController.h" namespace Systems { + class FreeSteeringSystem : public System { public: - FreeSteeringSystem(World* world) - : System(world) { } + FreeSteeringSystem(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 FreeSteeringInputController; + + std::unique_ptr m_InputController; }; + +class FreeSteeringSystem::FreeSteeringInputController : InputController +{ +public: + FreeSteeringInputController(std::shared_ptr<::EventBroker> eventBroker) + : InputController(eventBroker) + , SpeedMultiplier(1.f) + , OrientationActive(false) { } + + glm::vec3 Movement; + glm::quat Orientation; + float SpeedMultiplier; + bool OrientationActive; + +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/Systems/InputSystem.cpp b/src/Systems/InputSystem.cpp index b64bc03..3c9fdfd 100755 --- a/src/Systems/InputSystem.cpp +++ b/src/Systems/InputSystem.cpp @@ -7,80 +7,123 @@ void Systems::InputSystem::RegisterComponents(ComponentFactory* cf) cf->Register("Input", []() { return new Components::Input(); }); } +void Systems::InputSystem::Initialize() +{ + // Subscribe to events + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &Systems::InputSystem::OnKeyDown) + EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Systems::InputSystem::OnKeyUp) + EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &Systems::InputSystem::OnMousePress) + EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &Systems::InputSystem::OnMouseRelease) + EVENT_SUBSCRIBE_MEMBER(m_EBindKey, &Systems::InputSystem::OnBindKey) + EVENT_SUBSCRIBE_MEMBER(m_EBindMouseButton, &Systems::InputSystem::OnBindMouseButton) +} + void Systems::InputSystem::Update(double dt) { - m_LastKeyState = m_CurrentKeyState; - m_LastMouseState = m_CurrentMouseState; - - // Keyboard input - for (int i = 0; i <= GLFW_KEY_LAST; ++i) - { - m_CurrentKeyState[i] = glfwGetKey(m_Renderer->GetWindow(), i); - } - - // Mouse buttons - for (int i = 0; i <= GLFW_MOUSE_BUTTON_LAST; ++i) - { - m_CurrentMouseState[i] = glfwGetMouseButton(m_Renderer->GetWindow(), i); - } - - // Cursor position - double xpos, ypos; - glfwGetCursorPos(m_Renderer->GetWindow(), &xpos, &ypos); - m_CurrentMouseDeltaX = xpos - m_LastMouseX; - m_CurrentMouseDeltaY = ypos - m_LastMouseY; - m_LastMouseX = xpos; - m_LastMouseY = ypos; - - // Lock mouse while holding LMB - if (m_CurrentMouseState[GLFW_MOUSE_BUTTON_LEFT]) - { - m_LastMouseX = m_Renderer->WIDTH / 2.f; // xpos; - m_LastMouseY = m_Renderer->HEIGHT / 2.f; // ypos; - glfwSetCursorPos(m_Renderer->GetWindow(), m_LastMouseX, m_LastMouseY); - } - // Hide/show cursor with LMB - if (m_CurrentMouseState[GLFW_MOUSE_BUTTON_LEFT] && !m_LastMouseState[GLFW_MOUSE_BUTTON_LEFT]) - { - glfwSetInputMode(m_Renderer->GetWindow(), GLFW_CURSOR, GLFW_CURSOR_HIDDEN); - } - if (!m_CurrentMouseState[GLFW_MOUSE_BUTTON_LEFT] && m_LastMouseState[GLFW_MOUSE_BUTTON_LEFT]) - { - glfwSetInputMode(m_Renderer->GetWindow(), GLFW_CURSOR, GLFW_CURSOR_NORMAL); - } - -#ifdef DEBUG - // Wireframe - if (m_CurrentKeyState[GLFW_KEY_F1] && !m_LastKeyState[GLFW_KEY_F1]) - { - m_Renderer->DrawWireframe(!m_Renderer->DrawWireframe()); - } - // Normals - if (m_CurrentKeyState[GLFW_KEY_F2] && !m_LastKeyState[GLFW_KEY_F2]) - { - m_Renderer->DrawNormals(!m_Renderer->DrawNormals()); - } - // Bounds - if (m_CurrentKeyState[GLFW_KEY_F3] && !m_LastKeyState[GLFW_KEY_F3]) - { - m_Renderer->DrawBounds(!m_Renderer->DrawBounds()); - } -#endif +// #ifdef DEBUG +// // Wireframe +// if (m_CurrentKeyState[GLFW_KEY_F1] && !m_LastKeyState[GLFW_KEY_F1]) +// { +// m_Renderer->DrawWireframe(!m_Renderer->DrawWireframe()); +// } +// // Normals +// if (m_CurrentKeyState[GLFW_KEY_F2] && !m_LastKeyState[GLFW_KEY_F2]) +// { +// m_Renderer->DrawNormals(!m_Renderer->DrawNormals()); +// } +// // Bounds +// if (m_CurrentKeyState[GLFW_KEY_F3] && !m_LastKeyState[GLFW_KEY_F3]) +// { +// m_Renderer->DrawBounds(!m_Renderer->DrawBounds()); +// } +// #endif } -void Systems::InputSystem::UpdateEntity(double dt, EntityID entity, EntityID parent) +bool Systems::InputSystem::OnKeyDown(const Events::KeyDown &event) { - auto input = m_World->GetComponent(entity, "Input"); - if (input == nullptr) - return; + auto bindingIt = m_KeyBindings.find(event.KeyCode); + if (bindingIt != m_KeyBindings.end()) + { + PublishCommand(0, bindingIt->second, false); + } - input->KeyState = m_CurrentKeyState; - input->LastKeyState = m_LastKeyState; - input->MouseState = m_CurrentMouseState; - input->LastMouseState = m_LastMouseState; - input->dX = m_CurrentMouseDeltaX; - input->dY = m_CurrentMouseDeltaY; + return true; } -std::array Systems::InputSystem::m_CurrentKeyState; -std::array Systems::InputSystem::m_LastKeyState; +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); + } + + return true; +} + +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); + } + + return true; +} + +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); + } + + return true; +} + +bool Systems::InputSystem::OnBindKey(const Events::BindKey &event) +{ + if (event.Command.empty()) + { + m_KeyBindings.erase(event.KeyCode); + } + else + { + m_KeyBindings[event.KeyCode] = event.Command; + LOG_DEBUG("Input: Bound key %c to %s", (char)event.KeyCode, event.Command.c_str()); + } + + return true; +} + +bool Systems::InputSystem::OnBindMouseButton(const Events::BindMouseButton &event) +{ + if (event.Command.empty()) + { + m_MouseButtonBindings.erase(event.Button); + } + else + { + m_MouseButtonBindings[event.Button] = event.Command; + LOG_DEBUG("Input: Bound mouse button %i to %s", event.Button, event.Command.c_str()); + } + + return true; +} + +void Systems::InputSystem::PublishCommand(int playerID, std::string command, bool release /*= false*/) +{ + if (release && command.at(0) == '+') + { + command[0] = '-'; + } + + Events::InputCommand e; + e.PlayerID = playerID; + e.Command = command; + 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 abceb77..c56cccf 100755 --- a/src/Systems/InputSystem.h +++ b/src/Systems/InputSystem.h @@ -2,10 +2,17 @@ #define InputSystem_h__ #include +#include #include "System.h" -#include "Renderer.h" #include "Components/Input.h" +#include "Events/KeyUp.h" +#include "Events/KeyDown.h" +#include "Events/MousePress.h" +#include "Events/MouseRelease.h" +#include "Events/BindKey.h" +#include "Events/BindMouseButton.h" +#include "Events/InputCommand.h" namespace Systems { @@ -13,22 +20,35 @@ namespace Systems class InputSystem : public System { public: - InputSystem(World* world, std::shared_ptr renderer) - : System(world), m_Renderer(renderer) { } + InputSystem(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: - std::shared_ptr m_Renderer; - static std::array m_CurrentKeyState; - static std::array m_LastKeyState; - std::array m_CurrentMouseState; - std::array m_LastMouseState; - float m_CurrentMouseDeltaX, m_CurrentMouseDeltaY; - float m_LastMouseX, m_LastMouseY; + // Input binding tables + std::unordered_map m_KeyBindings; // GLFW_KEY... -> command string + std::unordered_map m_MouseButtonBindings; // GLFW_MOUSE_BUTTON... -> command string + // Input events + EventRelay m_EKeyDown; + bool OnKeyDown(const Events::KeyDown &event); + EventRelay m_EKeyUp; + bool OnKeyUp(const Events::KeyUp &event); + EventRelay m_EMousePress; + bool OnMousePress(const Events::MousePress &event); + EventRelay m_EMouseRelease; + bool OnMouseRelease(const Events::MouseRelease &event); + // Input binding events + EventRelay m_EBindKey; + bool OnBindKey(const Events::BindKey &event); + EventRelay m_EBindMouseButton; + bool OnBindMouseButton(const Events::BindMouseButton &event); + + void PublishCommand(int playerID, std::string command, bool release = false); }; } diff --git a/src/Systems/ParticleSystem.cpp b/src/Systems/ParticleSystem.cpp index 8e384c5..e77e9c9 100644 --- a/src/Systems/ParticleSystem.cpp +++ b/src/Systems/ParticleSystem.cpp @@ -4,11 +4,6 @@ #include "World.h" -Systems::ParticleSystem::ParticleSystem(World *m_World) : System(m_World) -{ - -} - void Systems::ParticleSystem::Update(double dt) { diff --git a/src/Systems/PhysicsSystem.cpp b/src/Systems/PhysicsSystem.cpp index 6ec3b45..dfb7a8b 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) +void Systems::PhysicsSystem::Initialize() { + 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,170 @@ 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 + 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()) + { + 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 +300,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 +340,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 +420,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.h b/src/Systems/PhysicsSystem.h index 626bbcd..c6ebe4a 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 { @@ -46,17 +43,19 @@ namespace Systems class PhysicsSystem : public System { public: - PhysicsSystem(World* world); + PhysicsSystem(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; 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 +69,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/RenderSystem.cpp b/src/Systems/RenderSystem.cpp index d2102d1..d451c8b 100755 --- a/src/Systems/RenderSystem.cpp +++ b/src/Systems/RenderSystem.cpp @@ -48,8 +48,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/src/Systems/RenderSystem.h b/src/Systems/RenderSystem.h index 4df8658..c3cd09a 100755 --- a/src/Systems/RenderSystem.h +++ b/src/Systems/RenderSystem.h @@ -24,8 +24,9 @@ namespace Systems class RenderSystem : public System { public: - RenderSystem(World* world, std::shared_ptr renderer) - : System(world), m_Renderer(renderer) { } + RenderSystem(World* world, std::shared_ptr<::EventBroker> eventBroker, std::shared_ptr renderer) + : System(world, eventBroker) + , m_Renderer(renderer) { } void RegisterComponents(ComponentFactory* cf) override; void RegisterResourceTypes(ResourceManager* rm) override; diff --git a/src/Systems/SoundSystem.cpp b/src/Systems/SoundSystem.cpp index ffb9b06..02a665e 100755 --- a/src/Systems/SoundSystem.cpp +++ b/src/Systems/SoundSystem.cpp @@ -2,8 +2,7 @@ #include "SoundSystem.h" #include "World.h" -Systems::SoundSystem::SoundSystem(World* world) - : System(world) +void Systems::SoundSystem::Initialize() { //initialize OpenAL ALCdevice* Device = alcOpenDevice(NULL); @@ -22,6 +21,10 @@ Systems::SoundSystem::SoundSystem(World* world) alSpeedOfSound(340.29f); // Speed of sound alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); + + // Subscribe to events + m_EPlaySound = decltype(m_EPlaySound)(std::bind(&Systems::SoundSystem::OnPlaySound, this, std::placeholders::_1)); + EventBroker->Subscribe(m_EPlaySound); } void Systems::SoundSystem::RegisterComponents(ComponentFactory* cf) @@ -143,3 +146,15 @@ ALuint Systems::SoundSystem::CreateSource() return source; } + +bool Systems::SoundSystem::OnPlaySound(const Events::PlaySound &event) +{ + LOG_DEBUG("Events::PlaySound.Resource = %s", event.Resource.c_str()); + + ALuint buffer = *m_World->GetResourceManager()->Load("Sound", event.Resource); + ALuint source = m_Sources.begin()->second; + alSourcei(source, AL_BUFFER, buffer); + alSourcePlay(source); + + return true; +} diff --git a/src/Systems/SoundSystem.h b/src/Systems/SoundSystem.h index 85ee4fa..7fbc5aa 100755 --- a/src/Systems/SoundSystem.h +++ b/src/Systems/SoundSystem.h @@ -7,6 +7,7 @@ #include "System.h" #include "Components/Transform.h" #include "Components/SoundEmitter.h" +#include "Events/PlaySound.h" #include "Sound.h" namespace Systems @@ -15,9 +16,12 @@ namespace Systems class SoundSystem : public System { public: - SoundSystem(World* world); + SoundSystem(World* world, std::shared_ptr<::EventBroker> eventBroker) + : System(world, eventBroker) { } + void RegisterComponents(ComponentFactory* cf) override; void RegisterResourceTypes(ResourceManager* rm) override; + void Initialize() override; void Update(double dt) override; void UpdateEntity(double dt, EntityID entity, EntityID parent) override; @@ -39,6 +43,10 @@ private: //short bytesPerSample, bitsPerSample; //unsigned long dataSize; + // Events + EventRelay m_EPlaySound; + bool OnPlaySound(const Events::PlaySound &event); + std::map m_Sources; std::map m_BufferCache; // string = fileName }; diff --git a/src/Systems/TransformSystem.cpp b/src/Systems/TransformSystem.cpp index 0d1767d..383c123 100755 --- a/src/Systems/TransformSystem.cpp +++ b/src/Systems/TransformSystem.cpp @@ -40,7 +40,7 @@ glm::quat Systems::TransformSystem::AbsoluteOrientation(EntityID entity) do { auto transform = m_World->GetComponent(entity, "Transform"); - absOrientation *= transform->Orientation; + absOrientation = transform->Orientation * absOrientation; entity = m_World->GetEntityParent(entity); } while (entity != 0); diff --git a/src/Systems/TransformSystem.h b/src/Systems/TransformSystem.h index 754a567..7852628 100755 --- a/src/Systems/TransformSystem.h +++ b/src/Systems/TransformSystem.h @@ -10,9 +10,8 @@ namespace Systems class TransformSystem : public System { public: - TransformSystem(World* world) - : System(world) { } - + TransformSystem(World* world, std::shared_ptr<::EventBroker> eventBroker) + : System(world, eventBroker) { } //void Update(double dt) override; //void UpdateEntity(double dt, EntityID entity, EntityID parent) override; diff --git a/src/Util/Rectangle.h b/src/Util/Rectangle.h new file mode 100644 index 0000000..0d0db32 --- /dev/null +++ b/src/Util/Rectangle.h @@ -0,0 +1,95 @@ +#ifndef Util_Rectangle_h__ +#define Util_Rectangle_h__ + +#include + +struct Rectangle +{ + Rectangle() + : X(0), Y(0), Width(0), Height(0) { } + + Rectangle(int x, int y, int width = 0, int height = 0) + : X(x), Y(y), Width(width), Height(height) { } + + /*Rectangle(const Rectangle &rect) + : X(rect.X), Y(rect.Y), Width(rect.Width), Height(rect.Height) { }*/ + + int X; + int Y; + int Width; + int Height; + + const int& GetLeft() const { return X; } + void SetLeft(int left) + { + Width += X - left; + X = left; + } + int GetRight() const { return X + Width; } + void SetRight(int right) + { + Width = right - X; + } + const int& GetTop() const { return Y; } + void SetTop(int top) + { + Height += Y - top; + Y = top; + } + int GetBottom() const { return Y + Height; } + int SetBottom(int bottom) + { + Height = bottom - Y; + } + + Rectangle& operator+=(const Rectangle &rhs) + { + SetLeft(std::min(GetLeft(), rhs.GetLeft())); + SetRight(std::max(GetRight(), rhs.GetRight())); + SetTop(std::min(GetTop(), rhs.GetTop())); + SetBottom(std::max(GetBottom(), rhs.GetBottom())); + } + + static bool Intersects(const Rectangle &r1, const Rectangle &r2) + { + return !(r2.GetLeft() > r1.GetRight() || r2.GetRight() < r1.GetLeft() || r2.GetTop() > r1.GetBottom() || r2.GetBottom() < r1.GetTop()); + } +}; + +inline bool operator==(const Rectangle &r1, const Rectangle &r2) +{ + return (r1.X == r2.X) && (r1.Y == r2.Y) && (r1.Width == r2.Width) && (r1.Height == r2.Height); +} + +inline bool operator!=(const Rectangle &lhs, const Rectangle &rhs) +{ + return !(lhs == rhs); +} + +inline bool operator<(const Rectangle &lhs, const Rectangle &rhs) +{ + return (lhs.Width < rhs.Width) && (lhs.Height < rhs.Height); +} + +inline bool operator>(const Rectangle &lhs, const Rectangle &rhs) +{ + return rhs < lhs; +} + +inline bool operator<=(const Rectangle &lhs, const Rectangle &rhs) +{ + return !(lhs > rhs); +} + +inline bool operator>=(const Rectangle &lhs, const Rectangle &rhs) +{ + return !(lhs < rhs); +} + +inline Rectangle operator+(Rectangle lhs, const Rectangle &rhs) +{ + lhs += rhs; + return lhs; +} + +#endif // Util_Rectangle_h__ diff --git a/src/World.cpp b/src/World.cpp index e6a10b8..01713ab 100755 --- a/src/World.cpp +++ b/src/World.cpp @@ -119,16 +119,6 @@ EntityID World::CreateEntity(EntityID parent /*= 0*/) return newEntity; } -World::~World() -{ - -} - -World::World() -{ - m_LastEntityID = 0; -} - void World::Initialize() { RegisterSystems(); @@ -147,6 +137,15 @@ std::shared_ptr World::AddComponent(EntityID entity, std::string comp return AddComponent(entity, componentType); } +void World::CommitEntity(EntityID entity) +{ + for (auto pair : m_Systems) + { + auto system = pair.second; + system->OnEntityCommit(entity); + } +} + void World::AddComponent(EntityID entity, std::string componentType, std::shared_ptr component) { component->Entity = entity; diff --git a/src/World.h b/src/World.h index c8c55c4..5f430b2 100755 --- a/src/World.h +++ b/src/World.h @@ -14,13 +14,16 @@ #include "Entity.h" #include "Component.h" #include "System.h" +#include "EventBroker.h" #include "ResourceManager.h" class World { public: - World(); - ~World(); + World(std::shared_ptr<::EventBroker> eventBroker) + : m_EventBroker(eventBroker) + , m_LastEntityID(0) { } + ~World() { } virtual void Initialize(); @@ -65,6 +68,8 @@ public: std::shared_ptr AddComponent(EntityID entity, std::string componentType); template T* GetComponent(EntityID entity, std::string componentType); + // Triggers commit events in systems + void CommitEntity(EntityID entity); /*std::vector GetEntityChildren(EntityID entity);*/ @@ -75,8 +80,10 @@ public: std::unordered_map* GetEntities() { return &m_EntityParents; } ResourceManager* GetResourceManager() { return &m_ResourceManager; } + std::shared_ptr<::EventBroker> EventBroker() { return m_EventBroker; } protected: + std::shared_ptr<::EventBroker> m_EventBroker; SystemFactory m_SystemFactory; ComponentFactory m_ComponentFactory; ResourceManager m_ResourceManager; diff --git a/vs11/Returngeance/Returngeance.vcxproj b/vs11/Returngeance/Returngeance.vcxproj index 3cfd619..cc117af 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,17 +89,20 @@ 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) + + + @@ -136,15 +139,33 @@ + + + + + + + + + + + + + + + + + + @@ -160,6 +181,7 @@ + diff --git a/vs11/Returngeance/Returngeance.vcxproj.filters b/vs11/Returngeance/Returngeance.vcxproj.filters index 2e7f203..45e0e9b 100755 --- a/vs11/Returngeance/Returngeance.vcxproj.filters +++ b/vs11/Returngeance/Returngeance.vcxproj.filters @@ -53,6 +53,11 @@ Particle System\Systems + + + + Input + @@ -115,6 +120,15 @@ {9f45f029-46c8-4c0d-b44c-dc9bffd3c6a6} + + {6e633434-4aed-453d-b2f9-8c51ca7f78db} + + + {85692f3a-5241-4780-a3ca-f4d8a2851392} + + + {ee125b77-b275-4841-abc9-374957a89916} + @@ -215,18 +229,74 @@ Audio + + + Physics\Components + + + Physics\Components + + + Physics\Components + + + Physics\Components + Particle System\Systems Particle System\Components - - Physics\Components - Physics\Components + + GUI + + + Util + + + + Audio\Events + + + Input\Events + + + Input\Events + + + Input + + + Input\Events + + + Input\Events + + + Input\Events + + + Input\Events + + + Input\Events + + + Input\Events + + + Input + + + Rendering + + + GUI +