Merge branch 'Rendering' into TextRendering
# Conflicts: # include/Engine/Rendering/RenderQueue.h # include/Engine/Rendering/RenderQueueFactory.h # include/Engine/Rendering/Renderer.h # include/Engine/Rendering/ShaderProgram.h # include/Game/Game.h # resources/Schema/Components.xsd # resources/Schema/Entities/Test.xml # resources/Schema/Types/Entity.xsd # src/Engine/Rendering/RenderQueueFactory.cpp # src/Engine/Rendering/Renderer.cpp # src/Game/Game.cpp
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
Libraries bundled along with binaries for Windows (MSVC14), available as a submodule in the *deps* directory of the source tree.
|
Libraries bundled along with binaries for Windows (MSVC14), available as a submodule in the *deps* directory of the source tree.
|
||||||
|
|
||||||
| Project | Version | License |
|
| Project | Version | License |
|
||||||
| ------------------------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ---------------------------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| **[GLFW](http://www.glfw.org)** | 3.1.2 | [zlib/libpng License](http://www.glfw.org/license.html) |
|
| **[GLFW](http://www.glfw.org)** | 3.1.2 | [zlib/libpng License](http://www.glfw.org/license.html) |
|
||||||
| **[GLM](http://glm.g-truc.net/0.9.5/index.html)** | 0.9.7.1 | [MIT License](http://glm.g-truc.net/copying.txt) |
|
| **[GLM](http://glm.g-truc.net/0.9.5/index.html)** | 0.9.7.1 | [MIT License](http://glm.g-truc.net/copying.txt) |
|
||||||
| **[GLEW](http://glew.sourceforge.net)** | 1.13.0 | [Modified BSD License](http://glew.sourceforge.net/glew.txt), [Mesa 3-D License](http://glew.sourceforge.net/mesa.txt), [Khronos License](http://glew.sourceforge.net/khronos.txt) |
|
| **[GLEW](http://glew.sourceforge.net)** | 1.13.0 | [Modified BSD License](http://glew.sourceforge.net/glew.txt), [Mesa 3-D License](http://glew.sourceforge.net/mesa.txt), [Khronos License](http://glew.sourceforge.net/khronos.txt) |
|
||||||
@@ -10,10 +10,12 @@ Libraries bundled along with binaries for Windows (MSVC14), available as a submo
|
|||||||
| **[zlib](http://www.zlib.net)** | 1.28 | [zlib License](http://www.zlib.net/zlib_license.html) |
|
| **[zlib](http://www.zlib.net)** | 1.28 | [zlib License](http://www.zlib.net/zlib_license.html) |
|
||||||
| **[libpng](http://www.libpng.org/pub/png/libpng.html)** | 1.6.19 | [libpng License](http://www.libpng.org/pub/png/src/libpng-LICENSE.txt) |
|
| **[libpng](http://www.libpng.org/pub/png/libpng.html)** | 1.6.19 | [libpng License](http://www.libpng.org/pub/png/src/libpng-LICENSE.txt) |
|
||||||
| **[Xerces-C++](https://xerces.apache.org/xerces-c)** | 3.1.2 | [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
|
| **[Xerces-C++](https://xerces.apache.org/xerces-c)** | 3.1.2 | [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) |
|
||||||
|
| **[ImGui](https://github.com/ocornut/imgui)** | 2015-12-12 | [MIT License](https://github.com/ocornut/imgui/blob/de3a154f3801de22c8e0bd2aeabf663a70c05972/LICENSE) |
|
||||||
|
| **[nativefiledialog](https://github.com/mlabbe/nativefiledialog) | 2016-01-08 | https://github.com/mlabbe/nativefiledialog/blob/master/LICENSE |
|
||||||
|
|
||||||
#### External libraries
|
#### External libraries
|
||||||
Libraries that are too big to be bundled with the project.
|
Libraries that are too big to be bundled with the project.
|
||||||
|
|
||||||
| Project | Version | License | Root folder environment variable (Windows) |
|
| Project | Version | License | Root folder environment variable (Windows) |
|
||||||
| ---------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | ------------------------------------------ |
|
| ---------------------------------------------------------- | ----------- | --------------------------------------------------------------------------- | ------------------------------------------ |
|
||||||
| **[Boost](http://www.boost.org)** | 1.59.0+ | [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt) | BOOST_ROOT |
|
| **[Boost](http://www.boost.org)** | 1.60.0+ | [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt) | BOOST_ROOT |
|
||||||
|
|||||||
+1
-1
Submodule assets updated: fa95bf4383...6cbf2365d4
+1
-1
Submodule deps updated: 75149166e1...bf83f099ba
@@ -0,0 +1,59 @@
|
|||||||
|
#ifndef Collision_h__
|
||||||
|
#define Collision_h__
|
||||||
|
|
||||||
|
//NOTE: Collision.h needs to be #included before <GLFW/glfw3.h>,
|
||||||
|
//because Collision #includes "RawModel.h", which has "Texture.h", which has "OpenGL.h" which must be #included first
|
||||||
|
//or you will get "fatal error C1189: #error: gl.h included before glew.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Core/Ray.h"
|
||||||
|
#include "Core/AABB.h"
|
||||||
|
#include "Engine/Rendering/RawModel.h"
|
||||||
|
#include "Core/Entity.h"
|
||||||
|
|
||||||
|
class World;
|
||||||
|
struct ComponentWrapper;
|
||||||
|
|
||||||
|
namespace Collision
|
||||||
|
{
|
||||||
|
//Return true if the ray hits the box.
|
||||||
|
bool RayAABBIntr(const Ray& ray, const AABB& box);
|
||||||
|
bool RayVsAABB(const Ray& ray, const AABB& box);
|
||||||
|
//Return true if the ray hits the box, also outputs distance from ray origin to intersection point in [outDistance].
|
||||||
|
bool RayVsAABB(const Ray& ray, const AABB& box, float& outDistance);
|
||||||
|
|
||||||
|
//Return true if the ray hits any of the triangles in the model. Stops checking when a hit is detected.
|
||||||
|
bool RayVsModel(const Ray& ray,
|
||||||
|
const std::vector<RawModel::Vertex>& modelVertices,
|
||||||
|
const std::vector<unsigned int>& modelIndices);
|
||||||
|
//Return true if the ray hits any of the triangles in the model.
|
||||||
|
//Also returns the position of the intersection point. Will loop through all the whole model indices.
|
||||||
|
bool RayVsModel(const Ray& ray,
|
||||||
|
const std::vector<RawModel::Vertex>& modelVertices,
|
||||||
|
const std::vector<unsigned int>& modelIndices,
|
||||||
|
glm::vec3& outHitPosition);
|
||||||
|
//Return true if the ray hits any of the triangles in the model.
|
||||||
|
//Also returns the distance from the ray origin to the closest
|
||||||
|
//intersection point, and the barycentric u,v-coordinates. Will loop through all the whole model indices.
|
||||||
|
bool RayVsModel(const Ray& ray,
|
||||||
|
const std::vector<RawModel::Vertex>& modelVertices,
|
||||||
|
const std::vector<unsigned int>& modelIndices,
|
||||||
|
float& outDistance,
|
||||||
|
float& outUCoord,
|
||||||
|
float& outVCoord);
|
||||||
|
|
||||||
|
//Return true if the boxes are intersecting.
|
||||||
|
bool AABBVsAABB(const AABB& a, const AABB& b);
|
||||||
|
//Return true if the boxes are intersecting.
|
||||||
|
//Also outputs the minimum translation that box [a] would need in order to resolve collision.
|
||||||
|
bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation);
|
||||||
|
bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon = 0.0001f);
|
||||||
|
|
||||||
|
//Returns true if the entity has a boundingbox. Outputs the aabb in [outBox].
|
||||||
|
bool GetEntityBox(World* world, EntityID entity, AABB& outBox, bool forceBoxFromModel = false);
|
||||||
|
bool GetEntityBox(World* world, ComponentWrapper& AABBComponent, AABB& outBox);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef CollisionSystem_h__
|
||||||
|
#define CollisionSystem_h__
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/common.hpp>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
#include "Core/EventBroker.h"
|
||||||
|
#include "Core/EKeyUp.h"
|
||||||
|
|
||||||
|
class CollisionSystem : public PureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CollisionSystem(EventBroker* eventBroker)
|
||||||
|
: PureSystem(eventBroker, "AABB")
|
||||||
|
, zPress(false)
|
||||||
|
{
|
||||||
|
//TODO: Debug stuff, remove later.
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &CollisionSystem::OnKeyUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void UpdateComponent(World* world, ComponentWrapper& cAABB, double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool zPress;
|
||||||
|
EventRelay<CollisionSystem, Events::KeyUp> m_EKeyUp;
|
||||||
|
bool OnKeyUp(const Events::KeyUp &event);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef Events_TriggerEnter_h__
|
||||||
|
#define Events_TriggerEnter_h__
|
||||||
|
|
||||||
|
#include "../Core/EventBroker.h"
|
||||||
|
#include "../Core/Entity.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Thrown once, when an entity is only touching a trigger. */
|
||||||
|
struct TriggerTouch : Event
|
||||||
|
{
|
||||||
|
/** The id of the entity that touches the trigger. */
|
||||||
|
EntityID Entity;
|
||||||
|
/** The id of the trigger entity. */
|
||||||
|
EntityID Trigger;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Thrown once, when an entity has completely left a trigger. */
|
||||||
|
struct TriggerLeave : Event
|
||||||
|
{
|
||||||
|
/** The id of the entity that left the trigger. */
|
||||||
|
EntityID Entity;
|
||||||
|
/** The id of the trigger entity. */
|
||||||
|
EntityID Trigger;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Thrown once, when an entity is completely contained inside a trigger. */
|
||||||
|
struct TriggerEnter : Event
|
||||||
|
{
|
||||||
|
/** The id of the entity that entered the trigger. */
|
||||||
|
EntityID Entity;
|
||||||
|
/** The id of the trigger entity. */
|
||||||
|
EntityID Trigger;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef TriggerSystem_h__
|
||||||
|
#define TriggerSystem_h__
|
||||||
|
|
||||||
|
#include <glm/common.hpp>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
#include "Core/System.h"
|
||||||
|
#include "Core/EventBroker.h"
|
||||||
|
#include "ETrigger.h"
|
||||||
|
|
||||||
|
class AABB;
|
||||||
|
|
||||||
|
class TriggerSystem : public PureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TriggerSystem(EventBroker* eventBroker)
|
||||||
|
: PureSystem(eventBroker, "Trigger")
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual void UpdateComponent(World* world, ComponentWrapper& collision, double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesTouchingTrigger;
|
||||||
|
std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesCompletelyInTrigger;
|
||||||
|
|
||||||
|
//True if leave event was thrown.
|
||||||
|
bool throwLeaveIfWasInTrigger(std::unordered_set<EntityID>& triggerSet, EntityID pId, EntityID tId);
|
||||||
|
template<typename Event>
|
||||||
|
void publish(EntityID pId, EntityID tId)
|
||||||
|
{
|
||||||
|
Event e;
|
||||||
|
e.Trigger = tId;
|
||||||
|
e.Entity = pId;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -5,3 +5,4 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "Core/Util/Logging.h"
|
#include "Core/Util/Logging.h"
|
||||||
|
#include "Core/Util/IfDebug.h"
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef AABB_h__
|
||||||
|
#define AABB_h__
|
||||||
|
|
||||||
|
#include "../GLM.h"
|
||||||
|
|
||||||
|
class AABB
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AABB() = default;
|
||||||
|
//No checks are made. Values in minPos must be less than values in maxPos, i.e. min.x < max.x, etc.
|
||||||
|
AABB(const glm::vec3& minPos, const glm::vec3& maxPos);
|
||||||
|
AABB(const glm::vec4& minPos, const glm::vec4& maxPos);
|
||||||
|
//No checks are made. Size must consist of non-negative numbers.
|
||||||
|
virtual void CreateFromCenter(const glm::vec3& center, const glm::vec3& size);
|
||||||
|
virtual ~AABB();
|
||||||
|
|
||||||
|
const glm::vec3& MinCorner() const { return m_MinCorner; }
|
||||||
|
const glm::vec3& MaxCorner() const { return m_MaxCorner; }
|
||||||
|
const glm::vec3& Center() const { return m_Center; }
|
||||||
|
const glm::vec3 Size() const { return 2.0f * m_HalfSize; }
|
||||||
|
const glm::vec3& HalfSize() const { return m_HalfSize; }
|
||||||
|
private:
|
||||||
|
glm::vec3 m_MinCorner;
|
||||||
|
glm::vec3 m_MaxCorner;
|
||||||
|
glm::vec3 m_Center;
|
||||||
|
glm::vec3 m_HalfSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -12,9 +12,16 @@ struct ComponentInfo
|
|||||||
unsigned int Stride = 0;
|
unsigned int Stride = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Field_t
|
||||||
|
{
|
||||||
|
std::string Type;
|
||||||
|
unsigned int Offset;
|
||||||
|
unsigned int Stride;
|
||||||
|
};
|
||||||
|
|
||||||
std::string Name;
|
std::string Name;
|
||||||
std::unordered_map<std::string, std::string> FieldTypes;
|
std::unordered_map<std::string, Field_t> Fields;
|
||||||
std::unordered_map<std::string, unsigned int> FieldOffsets;
|
std::vector<const Field_t*> FieldsInOrder;
|
||||||
Meta_t Meta;
|
Meta_t Meta;
|
||||||
std::shared_ptr<char> Defaults = nullptr;
|
std::shared_ptr<char> Defaults = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public:
|
|||||||
~ComponentPoolForwardIterator() = default;
|
~ComponentPoolForwardIterator() = default;
|
||||||
ComponentPoolForwardIterator& operator=(const ComponentPoolForwardIterator& other) = default;
|
ComponentPoolForwardIterator& operator=(const ComponentPoolForwardIterator& other) = default;
|
||||||
ComponentPoolForwardIterator& operator++();
|
ComponentPoolForwardIterator& operator++();
|
||||||
ComponentPoolForwardIterator& operator++(int);
|
ComponentPoolForwardIterator operator++(int);
|
||||||
bool operator!=(const ComponentPoolForwardIterator& other) const;
|
bool operator!=(const ComponentPoolForwardIterator& other) const;
|
||||||
bool operator==(const ComponentPoolForwardIterator& other) const;
|
bool operator==(const ComponentPoolForwardIterator& other) const;
|
||||||
ComponentWrapper operator*() const;
|
ComponentWrapper operator*() const;
|
||||||
@@ -54,6 +54,8 @@ public:
|
|||||||
ComponentWrapper Allocate(EntityID entity);
|
ComponentWrapper Allocate(EntityID entity);
|
||||||
// Get the component belonging to a specific entity
|
// Get the component belonging to a specific entity
|
||||||
ComponentWrapper GetByEntity(EntityID ent);
|
ComponentWrapper GetByEntity(EntityID ent);
|
||||||
|
// Returns true if the pool contains a component for the specified entity
|
||||||
|
bool KnowsEntity(EntityID ent);
|
||||||
// Delete a component and free its memory
|
// Delete a component and free its memory
|
||||||
void Delete(ComponentWrapper& wrapper);
|
void Delete(ComponentWrapper& wrapper);
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ struct ComponentWrapper
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
T& Property(std::string name)
|
T& Property(std::string name)
|
||||||
{
|
{
|
||||||
unsigned int offset = Info.FieldOffsets.at(name);
|
unsigned int offset = Info.Fields.at(name).Offset;
|
||||||
return *reinterpret_cast<T*>(&Data[offset]);
|
return *reinterpret_cast<T*>(&Data[offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,8 +78,9 @@ public:
|
|||||||
void AddProperty(std::string fieldName, T defaultValue)
|
void AddProperty(std::string fieldName, T defaultValue)
|
||||||
{
|
{
|
||||||
m_DefaultValues.push_back(defaultValue);
|
m_DefaultValues.push_back(defaultValue);
|
||||||
m_ComponentInfo.FieldTypes[fieldName] = typeid(T).name();
|
m_ComponentInfo.Fields[fieldName].Name = typeid(T).name();
|
||||||
m_ComponentInfo.FieldOffsets[fieldName] = m_ComponentInfo.Meta.Stride;
|
m_ComponentInfo.Fields[fieldName].Offset = m_ComponentInfo.Meta.Stride;
|
||||||
|
m_ComponentInfo.Fields[fieldName].Stride = sizeof(T);
|
||||||
m_ComponentInfo.Meta.Stride += sizeof(T);
|
m_ComponentInfo.Meta.Stride += sizeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
#include <boost/property_tree/ini_parser.hpp>
|
#include <boost/property_tree/ini_parser.hpp>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "ResourceManager.h"
|
#include "ResourceManager.h"
|
||||||
@@ -20,6 +21,8 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
T Get(std::string key, T defaultValue);
|
T Get(std::string key, T defaultValue);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
std::vector<std::pair<std::string, T>> GetAll(std::string key);
|
||||||
|
template <typename T>
|
||||||
void Set(std::string key, T value);
|
void Set(std::string key, T value);
|
||||||
|
|
||||||
void SaveToDisk();
|
void SaveToDisk();
|
||||||
@@ -37,6 +40,21 @@ T ConfigFile::Get(std::string key, T defaultValue)
|
|||||||
return m_PTreeMerged.get<T>(key, defaultValue);
|
return m_PTreeMerged.get<T>(key, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::vector<std::pair<std::string, T>> ConfigFile::GetAll(std::string key)
|
||||||
|
{
|
||||||
|
std::vector<std::pair<std::string, T>> out;
|
||||||
|
auto parent = m_PTreeMerged.find(key);
|
||||||
|
if (parent == m_PTreeMerged.not_found()) {
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
for (auto& child : parent->second) {
|
||||||
|
T value = boost::lexical_cast<T>(child.second.data());
|
||||||
|
out.push_back(std::make_pair(child.first, value));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ConfigFile::Set(std::string key, T value)
|
void ConfigFile::Set(std::string key, T value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef EFileDropped_h__
|
||||||
|
#define EFileDropped_h__
|
||||||
|
|
||||||
|
#include "EventBroker.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct FileDropped : Event
|
||||||
|
{
|
||||||
|
std::string Path;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef Events_KeyboardChar_h__
|
||||||
|
#define Events_KeyboardChar_h__
|
||||||
|
|
||||||
|
#include "EventBroker.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct KeyboardChar : Event
|
||||||
|
{
|
||||||
|
double Timestamp = 0.f;
|
||||||
|
unsigned int Char = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef Events_MouseScroll_h__
|
||||||
|
#define Events_MouseScroll_h__
|
||||||
|
|
||||||
|
#include "EventBroker.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct MouseScroll : Event
|
||||||
|
{
|
||||||
|
double DeltaX;
|
||||||
|
double DeltaY;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef EPlayerDamage_h__
|
||||||
|
#define EPlayerDamage_h__
|
||||||
|
|
||||||
|
#include "EventBroker.h"
|
||||||
|
#include "../Core/Entity.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct PlayerDamage : Event
|
||||||
|
{
|
||||||
|
double DamageAmount;
|
||||||
|
EntityID PlayerDamagedID;
|
||||||
|
//optional TypeOfDamage
|
||||||
|
std::string TypeOfDamage;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef EPlayerDeath_h__
|
||||||
|
#define EPlayerDeath_h__
|
||||||
|
|
||||||
|
#include "EventBroker.h"
|
||||||
|
#include "../Core/Entity.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct PlayerDeath : Event
|
||||||
|
{
|
||||||
|
//KilledBy,KilledByWhat is optional for now. It might be used later in the playerlog-system
|
||||||
|
EntityID KilledBy;
|
||||||
|
EntityID PlayerID;
|
||||||
|
std::string KilledByWhat;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef EPlayerHealthPickup_h__
|
||||||
|
#define EPlayerHealthPickup_h__
|
||||||
|
|
||||||
|
#include "EventBroker.h"
|
||||||
|
#include "../Core/Entity.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct PlayerHealthPickup : Event
|
||||||
|
{
|
||||||
|
double HealthAmount;
|
||||||
|
EntityID PlayerHealedID;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -2,5 +2,6 @@
|
|||||||
#define Entity_h__
|
#define Entity_h__
|
||||||
|
|
||||||
typedef unsigned int EntityID;
|
typedef unsigned int EntityID;
|
||||||
|
const static unsigned int EntityID_Invalid = -1;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,293 @@
|
|||||||
|
#ifndef EntityFile_h__
|
||||||
|
#define EntityFile_h__
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <xercesc/util/XercesDefs.hpp>
|
||||||
|
#include <xercesc/util/PlatformUtils.hpp>
|
||||||
|
#include <xercesc/sax2/SAX2XMLReader.hpp>
|
||||||
|
#include <xercesc/sax2/XMLReaderFactory.hpp>
|
||||||
|
#include <xercesc/sax2/DefaultHandler.hpp>
|
||||||
|
#include <xercesc/sax2/Attributes.hpp>
|
||||||
|
#include <xercesc/util/XMLString.hpp>
|
||||||
|
#include <xercesc/util/XMLChar.hpp>
|
||||||
|
#include <xercesc/sax2/DefaultHandler.hpp>
|
||||||
|
#include <xercesc/framework/XMLDocumentHandler.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSParticle.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSModelGroup.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSAnnotation.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSValue.hpp>
|
||||||
|
#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
|
||||||
|
#include <xercesc/dom/DOM.hpp>
|
||||||
|
#include <xercesc/dom/DOMLSInput.hpp>
|
||||||
|
#include <xercesc/dom/DOMElement.hpp>
|
||||||
|
|
||||||
|
#include "../GLM.h"
|
||||||
|
#include "Util/XercesString.h"
|
||||||
|
#include "ResourceManager.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "ComponentInfo.h"
|
||||||
|
|
||||||
|
class EntityFileHandler
|
||||||
|
{
|
||||||
|
friend class EntityFileSAXHandler;
|
||||||
|
public:
|
||||||
|
// @param EntityID The entity found
|
||||||
|
// @param EntityID The parent of the entity
|
||||||
|
typedef std::function<void(EntityID, EntityID, const std::string&)> OnStartEntityCallback;
|
||||||
|
void SetStartEntityCallback(OnStartEntityCallback c) { m_OnStartEntityCallback = c; }
|
||||||
|
// @param EntityID The entity the component corresponds to
|
||||||
|
// @param std::string Type name of the component
|
||||||
|
typedef std::function<void(EntityID, const std::string&)> OnStartComponentCallback;
|
||||||
|
void SetStartComponentCallback(OnStartComponentCallback c) { m_OnStartComponentCallback = c; }
|
||||||
|
// @param EntityID Entity
|
||||||
|
// @param std::string Component name
|
||||||
|
// @param std::string Field name
|
||||||
|
// @param std::map<std::string, std::string> Field attribute names and values
|
||||||
|
typedef std::function<void(EntityID, const std::string&, const std::string&, const std::map<std::string, std::string>&)> OnStartFieldCallback;
|
||||||
|
void SetStartFieldCallback(OnStartFieldCallback c) { m_OnStartFieldCallback = c; }
|
||||||
|
// @param EntityID Entity
|
||||||
|
// @param std::string Component name
|
||||||
|
// @param std::string Field name
|
||||||
|
// @param char* Field data
|
||||||
|
typedef std::function<void(EntityID, const std::string&, const std::string&, const char*)> OnStartFieldDataCallback;
|
||||||
|
void SetStartFieldDataCallback(OnStartFieldDataCallback c) { m_OnStartFieldDataCallback = c; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
OnStartEntityCallback m_OnStartEntityCallback = nullptr;
|
||||||
|
OnStartComponentCallback m_OnStartComponentCallback = nullptr;
|
||||||
|
OnStartFieldCallback m_OnStartFieldCallback = nullptr;
|
||||||
|
OnStartFieldDataCallback m_OnStartFieldDataCallback = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EntityFileSAXHandler : public xercesc::DefaultHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class State
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
Entity,
|
||||||
|
Component,
|
||||||
|
ComponentField
|
||||||
|
};
|
||||||
|
|
||||||
|
EntityFileSAXHandler(const EntityFileHandler* handler, xercesc::SAX2XMLReader* reader)
|
||||||
|
: m_Handler(handler)
|
||||||
|
, m_Reader(reader)
|
||||||
|
{
|
||||||
|
// 0 is imaginary world entity
|
||||||
|
m_EntityStack.push(0);
|
||||||
|
m_StateStack.push(State::Unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
void startElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname, const xercesc::Attributes& attrs) override
|
||||||
|
{
|
||||||
|
std::string name = XS::ToString(_localName);
|
||||||
|
|
||||||
|
if (m_StateStack.top() == State::Unknown || m_StateStack.top() == State::Entity) {
|
||||||
|
if (name == "Entity") {
|
||||||
|
m_StateStack.push(State::Entity);
|
||||||
|
onStartEntity(attrs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (name == "EntityRef") {
|
||||||
|
onStartEntityRef(attrs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string uri = XS::ToString(_uri);
|
||||||
|
if (m_StateStack.top() == State::Entity) {
|
||||||
|
if (uri == "components") {
|
||||||
|
m_StateStack.push(State::Component);
|
||||||
|
onStartComponent(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_StateStack.top() == State::Component) {
|
||||||
|
m_StateStack.push(State::ComponentField);
|
||||||
|
onStartComponentField(name, attrs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void characters(const XMLCh* const chars, const XMLSize_t length) override
|
||||||
|
{
|
||||||
|
if (m_StateStack.top() == State::ComponentField) {
|
||||||
|
char* transcoded = xercesc::XMLString::transcode(chars);
|
||||||
|
onFieldData(transcoded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void endElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname) override
|
||||||
|
{
|
||||||
|
std::string name = XS::ToString(_localName);
|
||||||
|
if (m_StateStack.top() == State::Entity) {
|
||||||
|
if (name == "Entity") {
|
||||||
|
m_StateStack.pop();
|
||||||
|
onEndEntity();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string uri = XS::ToString(_uri);
|
||||||
|
if (m_StateStack.top() == State::Component) {
|
||||||
|
//if (uri == "components") {
|
||||||
|
m_StateStack.pop();
|
||||||
|
onEndComponent(name);
|
||||||
|
return;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_StateStack.top() == State::ComponentField) {
|
||||||
|
m_StateStack.pop();
|
||||||
|
onEndComponentField(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fatalError(const xercesc::SAXParseException& e)
|
||||||
|
{
|
||||||
|
XS::ToString s(e.getMessage());
|
||||||
|
LOG_ERROR("SAXParseException: %s", ((std::string)s).c_str());
|
||||||
|
//throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const EntityFileHandler* m_Handler;
|
||||||
|
xercesc::XMLGrammarPool* m_GrammarPool;
|
||||||
|
xercesc::SAX2XMLReader* m_Reader;
|
||||||
|
//State m_CurrentScope = State::Unknown;
|
||||||
|
std::stack<State> m_StateStack;
|
||||||
|
unsigned int m_NextEntityID = 0;
|
||||||
|
std::stack<EntityID> m_EntityStack;
|
||||||
|
std::string m_CurrentComponent;
|
||||||
|
std::string m_CurrentField;
|
||||||
|
std::map<std::string, std::string> m_CurrentAttributes;
|
||||||
|
|
||||||
|
void onStartEntity(const xercesc::Attributes& attrs)
|
||||||
|
{
|
||||||
|
EntityID parent = m_EntityStack.top();
|
||||||
|
|
||||||
|
if (m_Handler->m_OnStartEntityCallback) {
|
||||||
|
std::string name;
|
||||||
|
auto xName = attrs.getValue(XS::ToXMLCh("name"));
|
||||||
|
if (xName != nullptr) {
|
||||||
|
name = XS::ToString(xName);
|
||||||
|
}
|
||||||
|
m_Handler->m_OnStartEntityCallback(m_NextEntityID, parent, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_EntityStack.push(m_NextEntityID);
|
||||||
|
m_NextEntityID++;
|
||||||
|
}
|
||||||
|
void onEndEntity()
|
||||||
|
{
|
||||||
|
m_EntityStack.pop();
|
||||||
|
}
|
||||||
|
void onStartEntityRef(const xercesc::Attributes& attrs)
|
||||||
|
{
|
||||||
|
std::string path = XS::ToString(attrs.getValue(XS::ToXMLCh("file")));
|
||||||
|
|
||||||
|
xercesc::SAX2XMLReader* parser = xercesc::XMLReaderFactory::createXMLReader();
|
||||||
|
parser->setContentHandler(this);
|
||||||
|
parser->setErrorHandler(this);
|
||||||
|
parser->parse(path.c_str());
|
||||||
|
delete parser;
|
||||||
|
}
|
||||||
|
void onStartComponent(const std::string& name)
|
||||||
|
{
|
||||||
|
//LOG_DEBUG(" Component: %s", name.c_str());
|
||||||
|
m_CurrentComponent = name;
|
||||||
|
if (m_Handler->m_OnStartComponentCallback) {
|
||||||
|
m_Handler->m_OnStartComponentCallback(m_EntityStack.top(), name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void onEndComponent(const std::string& name) { }
|
||||||
|
void onStartComponentField(const std::string& field, const xercesc::Attributes& attrs)
|
||||||
|
{
|
||||||
|
//LOG_DEBUG(" Field: %s", field.c_str());
|
||||||
|
m_CurrentField = field;
|
||||||
|
m_CurrentAttributes.clear();
|
||||||
|
for (int i = 0; i < attrs.getLength(); i++) {
|
||||||
|
auto name = attrs.getQName(i);
|
||||||
|
auto value = attrs.getValue(name);
|
||||||
|
//LOG_DEBUG(" %s = %s", (char*)XS::ToString(name), (char*)XS::ToString(value));
|
||||||
|
m_CurrentAttributes[XS::ToString(name).operator std::string()] = XS::ToString(value).operator std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_Handler->m_OnStartFieldCallback) {
|
||||||
|
m_Handler->m_OnStartFieldCallback(m_EntityStack.top(), m_CurrentComponent, field, m_CurrentAttributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void onEndComponentField(const std::string& field) { }
|
||||||
|
|
||||||
|
void onFieldData(char* data)
|
||||||
|
{
|
||||||
|
//LOG_DEBUG(" Data: %s", data);
|
||||||
|
|
||||||
|
if (m_Handler->m_OnStartFieldDataCallback) {
|
||||||
|
m_Handler->m_OnStartFieldDataCallback(m_EntityStack.top(), m_CurrentComponent, m_CurrentField, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
xercesc::XMLString::release(&data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class EntityFileXMLErrorHandler : public xercesc::ErrorHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void warning(const xercesc::SAXParseException& e) override
|
||||||
|
{
|
||||||
|
reportParseException("Warning", e);
|
||||||
|
}
|
||||||
|
void error(const xercesc::SAXParseException& e) override
|
||||||
|
{
|
||||||
|
reportParseException("Error", e);
|
||||||
|
}
|
||||||
|
void fatalError(const xercesc::SAXParseException& e) override
|
||||||
|
{
|
||||||
|
reportParseException("FATAL ERROR", e);
|
||||||
|
}
|
||||||
|
void resetErrors() override { }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void reportParseException(std::string type, const xercesc::SAXParseException& e)
|
||||||
|
{
|
||||||
|
char* message = xercesc::XMLString::transcode(e.getMessage());
|
||||||
|
char* systemID = xercesc::XMLString::transcode(e.getSystemId());
|
||||||
|
std::cerr << systemID << ":" << e.getLineNumber() << ":" << e.getColumnNumber() << std::endl;
|
||||||
|
std::cerr << type << ": " << message << std::endl;
|
||||||
|
xercesc::XMLString::release(&systemID);
|
||||||
|
xercesc::XMLString::release(&message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class EntityFile : public Resource
|
||||||
|
{
|
||||||
|
friend class ResourceManager;
|
||||||
|
private:
|
||||||
|
EntityFile(boost::filesystem::path path);
|
||||||
|
~EntityFile();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::size_t GetTypeStride(std::string typeName);
|
||||||
|
static void WriteAttributeData(char* outData, const ComponentInfo::Field_t& field, const std::map<std::string, std::string>& attributes);
|
||||||
|
static void WriteValueData(char* outData, const ComponentInfo::Field_t& field, const char* valueData);
|
||||||
|
|
||||||
|
xercesc::XMLGrammarPool* GrammarPool() const { return m_GrammarPool; }
|
||||||
|
|
||||||
|
void Parse(const EntityFileHandler* handler) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::filesystem::path m_FilePath;
|
||||||
|
xercesc::XMLGrammarPool* m_GrammarPool;
|
||||||
|
xercesc::SAX2XMLReader* m_SAX2XMLReader;
|
||||||
|
//std::map<std::string, ::ComponentInfo> m_ComponentInfo;
|
||||||
|
//std::vector<std::string> m_EntityReferences;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef EntityFileParser_h__
|
||||||
|
#define EntityFileParser_h__
|
||||||
|
|
||||||
|
#include "EntityFile.h"
|
||||||
|
#include "World.h"
|
||||||
|
|
||||||
|
class EntityFileParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EntityFileParser(const EntityFile* entityFile);
|
||||||
|
|
||||||
|
void MergeEntities(World* world);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const EntityFile* m_EntityFile;
|
||||||
|
EntityFileHandler m_Handler;
|
||||||
|
World* m_World = nullptr;
|
||||||
|
// Maps EntityIDs local to the file to real IDs in the world after they've been
|
||||||
|
// created in order to resolve parent-child relationships.
|
||||||
|
std::map<EntityID, EntityID> m_EntityIDMapper;
|
||||||
|
|
||||||
|
void onStartEntity(EntityID entity, EntityID parent, const std::string& name);
|
||||||
|
void onStartComponent(EntityID entity, const std::string& component);
|
||||||
|
void onStartComponentField(EntityID entity, const std::string& componentType, const std::string& fieldName, const std::map<std::string, std::string>& attributes);
|
||||||
|
void onFieldData(EntityID entity, const std::string& componentType, const std::string& fieldName, const char* fieldData);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef EntityFilePreprocessor_h__
|
||||||
|
#define EntityFilePreprocessor_h__
|
||||||
|
|
||||||
|
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSParticle.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSModelGroup.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSAnnotation.hpp>
|
||||||
|
#include <xercesc/framework/psvi/XSValue.hpp>
|
||||||
|
#include <xercesc/framework/MemBufFormatTarget.hpp>
|
||||||
|
#include <xercesc/framework/MemBufInputSource.hpp>
|
||||||
|
#include <xercesc/parsers/XercesDOMParser.hpp>
|
||||||
|
|
||||||
|
#include "Util/XercesString.h"
|
||||||
|
#include "ResourceManager.h"
|
||||||
|
#include "World.h"
|
||||||
|
#include "EntityFile.h"
|
||||||
|
|
||||||
|
class EntityFilePreprocessor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EntityFilePreprocessor(const EntityFile* entityFile);
|
||||||
|
|
||||||
|
void RegisterComponents(World* world);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const EntityFile* m_EntityFile;
|
||||||
|
std::map<std::string, unsigned int> m_ComponentCounts;
|
||||||
|
std::map<std::string, ComponentInfo> m_ComponentInfo;
|
||||||
|
|
||||||
|
void onStartComponent(EntityID entity, std::string type);
|
||||||
|
void parseComponentInfo();
|
||||||
|
void parseDefaults();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef EntityFileWriter_h__
|
||||||
|
#define EntityFileWriter_h__
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <xercesc/dom/DOM.hpp>
|
||||||
|
#include <xercesc/util/XMLString.hpp>
|
||||||
|
#include <xercesc/util/PlatformUtils.hpp>
|
||||||
|
#include <xercesc/framework/LocalFileFormatTarget.hpp>
|
||||||
|
|
||||||
|
#include "Util/XercesString.h"
|
||||||
|
#include "EntityFile.h"
|
||||||
|
#include "World.h"
|
||||||
|
|
||||||
|
class EntityFileWriter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EntityFileWriter(boost::filesystem::path file)
|
||||||
|
: m_FilePath(file)
|
||||||
|
{
|
||||||
|
using namespace xercesc;
|
||||||
|
m_DOMImplementation = DOMImplementationRegistry::getDOMImplementation(XS::ToXMLCh("LS"));
|
||||||
|
m_DOMLSSerializer = static_cast<DOMImplementationLS*>(m_DOMImplementation)->createLSSerializer();
|
||||||
|
m_DOMLSSerializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTDiscardDefaultContent, true);
|
||||||
|
m_DOMLSSerializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteWorld(World* world);
|
||||||
|
void WriteEntity(World* world, EntityID entity);
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::filesystem::path m_FilePath;
|
||||||
|
xercesc::DOMImplementation* m_DOMImplementation;
|
||||||
|
xercesc::DOMLSSerializer* m_DOMLSSerializer;
|
||||||
|
|
||||||
|
void appendEntityChildren(xercesc::DOMElement* parentElement, const World* world, EntityID entity);
|
||||||
|
void appentEntityComponents(xercesc::DOMElement* parentElemetn, const World* world, EntityID entity);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
#ifndef EntityXMLFile_h__
|
|
||||||
#define EntityXMLFile_h__
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include "../Common.h"
|
|
||||||
#include "../GLM.h"
|
|
||||||
#include <xercesc/dom/DOM.hpp>
|
|
||||||
#include <xercesc/dom/DOMLSInput.hpp>
|
|
||||||
#include <xercesc/dom/DOMElement.hpp>
|
|
||||||
#include <xercesc/framework/Wrapper4InputSource.hpp>
|
|
||||||
#include <xercesc/framework/LocalFileInputSource.hpp>
|
|
||||||
#include <xercesc/framework/LocalFileFormatTarget.hpp>
|
|
||||||
#include <xercesc/framework/MemBufFormatTarget.hpp>
|
|
||||||
#include <xercesc/framework/MemBufInputSource.hpp>
|
|
||||||
#include <xercesc/sax/HandlerBase.hpp>
|
|
||||||
#include <xercesc/util/PlatformUtils.hpp>
|
|
||||||
#include <xercesc/util/XMLFloat.hpp>
|
|
||||||
#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
|
|
||||||
#include <xercesc/parsers/XercesDOMParser.hpp>
|
|
||||||
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
|
|
||||||
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
|
|
||||||
#include <xercesc/framework/psvi/XSParticle.hpp>
|
|
||||||
#include <xercesc/framework/psvi/XSModelGroup.hpp>
|
|
||||||
#include <xercesc/framework/psvi/XSAnnotation.hpp>
|
|
||||||
#include <xercesc/framework/psvi/XSValue.hpp>
|
|
||||||
#include <xercesc/framework/XMLValidator.hpp>
|
|
||||||
|
|
||||||
#include "ResourceManager.h"
|
|
||||||
#include "Entity.h"
|
|
||||||
#include "ComponentInfo.h"
|
|
||||||
class World;
|
|
||||||
|
|
||||||
class EntityPreprocessorXMLErrorHandler : public xercesc::DOMErrorHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool handleError(const xercesc::DOMError &e) override
|
|
||||||
{
|
|
||||||
char* message = xercesc::XMLString::transcode(e.getMessage());
|
|
||||||
std::cerr << "Preprocessor DOMError: " << message << std::endl;
|
|
||||||
xercesc::XMLString::release(&message);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class EntityParserXMLErrorHandler : public xercesc::ErrorHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void warning(const xercesc::SAXParseException& e) override
|
|
||||||
{
|
|
||||||
reportParseException("Warning", e);
|
|
||||||
}
|
|
||||||
void error(const xercesc::SAXParseException& e) override
|
|
||||||
{
|
|
||||||
reportParseException("Error", e);
|
|
||||||
}
|
|
||||||
void fatalError(const xercesc::SAXParseException& e) override
|
|
||||||
{
|
|
||||||
reportParseException("FATAL ERROR", e);
|
|
||||||
}
|
|
||||||
void resetErrors() override { }
|
|
||||||
|
|
||||||
private:
|
|
||||||
void reportParseException(std::string type, const xercesc::SAXParseException& e)
|
|
||||||
{
|
|
||||||
char* message = xercesc::XMLString::transcode(e.getMessage());
|
|
||||||
char* systemID = xercesc::XMLString::transcode(e.getSystemId());
|
|
||||||
std::cerr << systemID << ":" << e.getLineNumber() << ":" << e.getColumnNumber() << std::endl;
|
|
||||||
std::cerr << type << ": " << message << std::endl;
|
|
||||||
xercesc::XMLString::release(&systemID);
|
|
||||||
xercesc::XMLString::release(&message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class XSTR
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
XSTR(const XMLCh* const xmlString)
|
|
||||||
{
|
|
||||||
m_AsChar = xercesc::XMLString::transcode(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
XSTR(const char* normalString)
|
|
||||||
{
|
|
||||||
m_AsXMLCh = xercesc::XMLString::transcode(normalString);
|
|
||||||
}
|
|
||||||
|
|
||||||
~XSTR()
|
|
||||||
{
|
|
||||||
if (m_AsChar != nullptr) {
|
|
||||||
xercesc::XMLString::release(&m_AsChar);
|
|
||||||
}
|
|
||||||
if (m_AsXMLCh != nullptr) {
|
|
||||||
xercesc::XMLString::release(&m_AsXMLCh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
operator const char*() const { return m_AsChar; }
|
|
||||||
operator const XMLCh*() const { return m_AsXMLCh; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
char* m_AsChar = nullptr;
|
|
||||||
XMLCh* m_AsXMLCh = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
class EntityXMLFile : public Resource
|
|
||||||
{
|
|
||||||
friend class ResourceManager;
|
|
||||||
|
|
||||||
private:
|
|
||||||
EntityXMLFile(std::string path);
|
|
||||||
|
|
||||||
public:
|
|
||||||
~EntityXMLFile();
|
|
||||||
|
|
||||||
void PopulateWorld(World* world);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static unsigned int InstanceCount;
|
|
||||||
|
|
||||||
std::string m_EntityFile;
|
|
||||||
xercesc::XMLGrammarPool* m_GrammarPool = nullptr;
|
|
||||||
EntityParserXMLErrorHandler* m_ErrorHandler = nullptr;
|
|
||||||
xercesc::XercesDOMParser* m_DOMParser = nullptr;
|
|
||||||
xercesc::DOMDocument* m_DOMDocument = nullptr;
|
|
||||||
std::map<std::string, ComponentInfo> m_ComponentInfo;
|
|
||||||
|
|
||||||
// Preprocesses the entity file to insert include-by-copy child entities
|
|
||||||
// TODO: Make this work in memory instead of saving to file
|
|
||||||
void preprocess(std::string inPath, std::string outPath);
|
|
||||||
|
|
||||||
void parseComponentInfo();
|
|
||||||
void parseDefaults();
|
|
||||||
void predictComponentAllocation();
|
|
||||||
void parseEntityGraph(World* world, xercesc::DOMElement* parent, EntityID parentEntity);
|
|
||||||
std::size_t getTypeStride(std::string typeName);
|
|
||||||
float getFloatAttribute(const xercesc::DOMElement* element, const char* attribute) const;
|
|
||||||
void writeData(const xercesc::DOMElement* element, std::string typeName, char* outData);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -13,6 +13,8 @@
|
|||||||
relay = decltype(relay)(std::bind(handler, this, std::placeholders::_1)); \
|
relay = decltype(relay)(std::bind(handler, this, std::placeholders::_1)); \
|
||||||
m_EventBroker->Subscribe(relay);
|
m_EventBroker->Subscribe(relay);
|
||||||
|
|
||||||
|
typedef unsigned int EventID;
|
||||||
|
|
||||||
class EventBroker;
|
class EventBroker;
|
||||||
|
|
||||||
class BaseEventRelay
|
class BaseEventRelay
|
||||||
@@ -31,6 +33,7 @@ public:
|
|||||||
virtual bool Receive(const std::shared_ptr<Event> event) = 0;
|
virtual bool Receive(const std::shared_ptr<Event> event) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
EventID m_EventID;
|
||||||
std::string m_ContextTypeName;
|
std::string m_ContextTypeName;
|
||||||
std::string m_EventTypeName;
|
std::string m_EventTypeName;
|
||||||
EventBroker* m_Broker;
|
EventBroker* m_Broker;
|
||||||
@@ -95,6 +98,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_IsProcessing = false;
|
bool m_IsProcessing = false;
|
||||||
|
EventID m_NextEventID = 0;
|
||||||
|
|
||||||
typedef std::string ContextTypeName_t; // typeid(ContextType).name()
|
typedef std::string ContextTypeName_t; // typeid(ContextType).name()
|
||||||
typedef std::string EventTypeName_t; // typeid(EventType).name()
|
typedef std::string EventTypeName_t; // typeid(EventType).name()
|
||||||
@@ -103,14 +107,14 @@ private:
|
|||||||
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
|
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
|
||||||
ContextRelays_t m_ContextRelays;
|
ContextRelays_t m_ContextRelays;
|
||||||
std::vector<BaseEventRelay*> m_RelaysToSubscribe;
|
std::vector<BaseEventRelay*> m_RelaysToSubscribe;
|
||||||
std::vector<BaseEventRelay*> m_RelaysToUnsubscribe;
|
std::vector<std::tuple<EventID, ContextTypeName_t, EventTypeName_t>> m_RelaysToUnsubscribe;
|
||||||
|
|
||||||
typedef std::list<std::pair<EventTypeName_t, std::shared_ptr<Event>>> EventQueue_t;
|
typedef std::list<std::pair<EventTypeName_t, std::shared_ptr<Event>>> EventQueue_t;
|
||||||
std::shared_ptr<EventQueue_t> m_EventQueueRead;
|
std::shared_ptr<EventQueue_t> m_EventQueueRead;
|
||||||
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
|
std::shared_ptr<EventQueue_t> m_EventQueueWrite;
|
||||||
|
|
||||||
void subscribeImmediate(BaseEventRelay& relay);
|
void subscribeImmediate(BaseEventRelay& relay);
|
||||||
void unsubscribeImmediate(BaseEventRelay& relay);
|
void unsubscribeImmediate(std::tuple<EventID, ContextTypeName_t, EventTypeName_t> identifier);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename EventType>
|
template <typename EventType>
|
||||||
|
|||||||
@@ -11,25 +11,22 @@ template <typename EventContext>
|
|||||||
class InputController
|
class InputController
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InputController(std::shared_ptr<dd::EventBroker> eventBroker)
|
InputController(EventBroker* eventBroker)
|
||||||
: EventBroker(eventBroker)
|
: m_EventBroker(eventBroker)
|
||||||
{ Initialize(); }
|
{ Initialize(); }
|
||||||
|
|
||||||
virtual void Initialize()
|
virtual void Initialize()
|
||||||
{
|
{
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &InputController::OnCommand);
|
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 OnCommand(const Events::InputCommand& e) { return false; }
|
||||||
virtual bool OnMouseMove(const Events::MouseMove &event) { return false; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<dd::EventBroker> EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventRelay<EventContext, Events::InputCommand> m_EInputCommand;
|
EventRelay<EventContext, Events::InputCommand> m_EInputCommand;
|
||||||
EventRelay<EventContext, Events::MouseMove> m_EMouseMove;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,12 +8,15 @@
|
|||||||
#include "EventBroker.h"
|
#include "EventBroker.h"
|
||||||
#include "EKeyDown.h"
|
#include "EKeyDown.h"
|
||||||
#include "EKeyUp.h"
|
#include "EKeyUp.h"
|
||||||
|
#include "EKeyboardChar.h"
|
||||||
#include "EMousePress.h"
|
#include "EMousePress.h"
|
||||||
#include "EMouseRelease.h"
|
#include "EMouseRelease.h"
|
||||||
#include "EMouseMove.h"
|
#include "EMouseMove.h"
|
||||||
|
#include "EMouseScroll.h"
|
||||||
#include "ELockMouse.h"
|
#include "ELockMouse.h"
|
||||||
#include "EGamepadAxis.h"
|
#include "EGamepadAxis.h"
|
||||||
#include "EGamepadButton.h"
|
#include "EGamepadButton.h"
|
||||||
|
#include "EFileDropped.h"
|
||||||
|
|
||||||
class InputManager
|
class InputManager
|
||||||
{
|
{
|
||||||
@@ -64,6 +67,13 @@ private:
|
|||||||
|
|
||||||
void PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis);
|
void PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis);
|
||||||
void PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button);
|
void PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button);
|
||||||
|
|
||||||
|
static std::vector<unsigned int> GLFWCharCallbackQueue;
|
||||||
|
static void GLFWCharCallback(GLFWwindow* window, unsigned int c);
|
||||||
|
static std::vector<std::pair<double, double>> GLFWScrollCallbackQueue;
|
||||||
|
static void GLFWScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
|
||||||
|
static std::vector<std::string> GLFWDropCallbackQueue;
|
||||||
|
static void GLFWDropCallback(GLFWwindow* window, int count, const char* paths[]);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Postfix increment i.e. iter++. Prefer pre-increment (++iter) for efficiency.
|
//Postfix increment i.e. iter++. Prefer pre-increment (++iter) for efficiency.
|
||||||
MemoryPoolForwardIterator& operator++(int)
|
MemoryPoolForwardIterator operator++(int)
|
||||||
{
|
{
|
||||||
MemoryPoolForwardIterator<T> copyIter(*this);
|
MemoryPoolForwardIterator<T> copyIter(*this);
|
||||||
operator++();
|
operator++();
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
#ifndef OctTree_h__
|
||||||
|
#define OctTree_h__
|
||||||
|
|
||||||
|
#include "Core/AABB.h"
|
||||||
|
|
||||||
|
class Ray;
|
||||||
|
|
||||||
|
class OctTree
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Output
|
||||||
|
{
|
||||||
|
float CollideDistance;
|
||||||
|
};
|
||||||
|
|
||||||
|
OctTree();
|
||||||
|
~OctTree();
|
||||||
|
//For the root OctTree, [octTreeBounds] should be a box containing the entire level.
|
||||||
|
OctTree(const AABB& octTreeBounds, int subDivisions);
|
||||||
|
|
||||||
|
//We cannot copy the OctTree as of now, because of the recursive dynamic allocation.
|
||||||
|
//Define these if the OctTree suddenly needs to be copied, think of the children OctChild* ptrs.
|
||||||
|
OctTree(const OctTree& other) = delete;
|
||||||
|
OctTree(const OctTree&& other) = delete;
|
||||||
|
OctTree& operator= (const OctTree& other) = delete;
|
||||||
|
//Add a dynamic object (one that moves around) into the tree.
|
||||||
|
void AddDynamicObject(const AABB& box);
|
||||||
|
//Add a static object (that does not move) into the tree.
|
||||||
|
void AddStaticObject(const AABB& box);
|
||||||
|
//Get the boxes that are in the same area as the input [box], the boxes are put in [outBoxes].
|
||||||
|
void BoxesInSameRegion(const AABB& box, std::vector<AABB>& outBoxes);
|
||||||
|
//Empty the tree of all objects, static and dynamic.
|
||||||
|
void ClearObjects();
|
||||||
|
//Empty the tree of all dynamic objects. Static objects remain in the tree.
|
||||||
|
void ClearDynamicObjects();
|
||||||
|
|
||||||
|
//Returns true if the ray collides with something in the tree. Result is written to [data].
|
||||||
|
bool RayCollides(const Ray& ray, Output& data);
|
||||||
|
//Returns true if the box collides with something in the tree.
|
||||||
|
//On collision with a box, that box is written to [outBoxIntersected].
|
||||||
|
//Note: More efficient than calling BoxesInSameRegion from outside and testing there.
|
||||||
|
bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct OctChild; //Fwd declaration;
|
||||||
|
struct ContainedObject
|
||||||
|
{
|
||||||
|
ContainedObject()
|
||||||
|
: Box(AABB())
|
||||||
|
, Checked(false)
|
||||||
|
{}
|
||||||
|
ContainedObject(AABB box)
|
||||||
|
: Box(box)
|
||||||
|
, Checked(false)
|
||||||
|
{}
|
||||||
|
AABB Box;
|
||||||
|
bool Checked;
|
||||||
|
};
|
||||||
|
OctChild* m_Root;
|
||||||
|
std::vector<ContainedObject> m_StaticObjects;
|
||||||
|
std::vector<ContainedObject> m_DynamicObjects;
|
||||||
|
|
||||||
|
bool m_UpdatedOnce;
|
||||||
|
unsigned int m_BoxID;
|
||||||
|
glm::vec3 m_PrevPos;
|
||||||
|
glm::quat m_PrevOri;
|
||||||
|
|
||||||
|
void falsifyObjectChecks();
|
||||||
|
|
||||||
|
struct OctChild
|
||||||
|
{
|
||||||
|
~OctChild();
|
||||||
|
OctChild(const AABB& octTreeBounds,
|
||||||
|
int subDivisions,
|
||||||
|
std::vector<OctTree::ContainedObject>& staticObjects,
|
||||||
|
std::vector<OctTree::ContainedObject>& dynamicObjects);
|
||||||
|
OctChild(const OctChild& other) = delete;
|
||||||
|
OctChild(const OctChild&& other) = delete;
|
||||||
|
OctChild& operator= (const OctChild& other) = delete;
|
||||||
|
void AddDynamicObject(const AABB& box);
|
||||||
|
void AddStaticObject(const AABB& box);
|
||||||
|
void BoxesInSameRegion(const AABB& box, std::vector<AABB>& outBoxes) const;
|
||||||
|
void ClearObjects();
|
||||||
|
void ClearDynamicObjects();
|
||||||
|
bool RayCollides(const Ray& ray, Output& data) const;
|
||||||
|
bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) const;
|
||||||
|
|
||||||
|
OctChild* m_Children[8];
|
||||||
|
//Indices into the lists in OctTree.
|
||||||
|
std::vector<int> m_StaticObjIndices;
|
||||||
|
std::vector<int> m_DynamicObjIndices;
|
||||||
|
AABB m_Box;
|
||||||
|
//Reference to the lists in OctTree.
|
||||||
|
std::vector<OctTree::ContainedObject>& m_StaticObjectsRef;
|
||||||
|
std::vector<OctTree::ContainedObject>& m_DynamicObjectsRef;
|
||||||
|
|
||||||
|
inline bool hasChildren() const;
|
||||||
|
int childIndexContainingPoint(const glm::vec3& point) const;
|
||||||
|
std::vector<int> childIndicesContainingBox(const AABB& box) const;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef Ray_h__
|
||||||
|
#define Ray_h__
|
||||||
|
|
||||||
|
#include "../GLM.h"
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
class Ray
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Ray(const glm::vec3& origin, const glm::vec3& dir)
|
||||||
|
: m_Origin(origin)
|
||||||
|
, m_Direction(glm::normalize(dir))
|
||||||
|
{
|
||||||
|
DEBUG_IF(true) {
|
||||||
|
if (glm::any(glm::isnan(m_Direction))) {
|
||||||
|
LOG_WARNING("Ray Direction was set to the zero-vector, expect unknown side effects and/or crashes.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const glm::vec3& Origin() const { return m_Origin; }
|
||||||
|
const glm::vec3& Direction() const { return m_Direction; }
|
||||||
|
//Sets the ray origin at parameter.
|
||||||
|
void SetOrigin(const glm::vec3& origin) { m_Origin = origin; }
|
||||||
|
//Normalizes the parameter and sets direction to it.
|
||||||
|
void SetDirection(const glm::vec3& direction) { m_Direction = glm::normalize(direction); }
|
||||||
|
private:
|
||||||
|
glm::vec3 m_Origin;
|
||||||
|
glm::vec3 m_Direction;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // Ray_h__
|
||||||
@@ -9,17 +9,42 @@ class System
|
|||||||
{
|
{
|
||||||
friend class SystemPipeline;
|
friend class SystemPipeline;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
System(const EventBroker* eventBroker, std::string componentType)
|
System(EventBroker* eventBroker)
|
||||||
: m_EventBroker(eventBroker)
|
: m_EventBroker(eventBroker)
|
||||||
|
{ }
|
||||||
|
virtual ~System() = default;
|
||||||
|
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PureSystem : public System
|
||||||
|
{
|
||||||
|
friend class SystemPipeline;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PureSystem(EventBroker* eventBroker, std::string componentType)
|
||||||
|
: System(eventBroker)
|
||||||
, m_ComponentType(componentType)
|
, m_ComponentType(componentType)
|
||||||
{ }
|
{ }
|
||||||
|
virtual ~PureSystem() = default;
|
||||||
|
|
||||||
virtual void Update(World* world, ComponentWrapper& component, double dt) = 0;
|
const std::string m_ComponentType;
|
||||||
|
|
||||||
private:
|
virtual void UpdateComponent(World* world, ComponentWrapper& component, double dt) = 0;
|
||||||
const EventBroker* m_EventBroker;
|
};
|
||||||
std::string m_ComponentType;
|
|
||||||
|
class ImpureSystem : public System
|
||||||
|
{
|
||||||
|
friend class SystemPipeline;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ImpureSystem(EventBroker* eventBroker)
|
||||||
|
: System(eventBroker)
|
||||||
|
{ }
|
||||||
|
virtual ~ImpureSystem() = default;
|
||||||
|
|
||||||
|
virtual void Update(World* world, double dt) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -9,33 +9,54 @@
|
|||||||
class SystemPipeline
|
class SystemPipeline
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SystemPipeline(const EventBroker* eventBroker)
|
SystemPipeline(EventBroker* eventBroker)
|
||||||
: m_EventBroker(eventBroker)
|
: m_EventBroker(eventBroker)
|
||||||
{ }
|
{ }
|
||||||
~SystemPipeline()
|
~SystemPipeline()
|
||||||
{
|
{
|
||||||
for (auto& pair : m_Systems) {
|
for (UnorderedSystems& group : m_OrderedSystemGroups) {
|
||||||
for (auto& system : pair.second) {
|
for (auto& pair : group.Systems) {
|
||||||
delete system;
|
delete pair.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename... Arguments>
|
template <typename T, typename... Arguments>
|
||||||
void AddSystem(Arguments... args)
|
//All systems with orderlevel 0 will be updated first, then 1, 2, etc.
|
||||||
|
void AddSystem(int updateOrderLevel, Arguments... args)
|
||||||
{
|
{
|
||||||
|
if (updateOrderLevel + 1 > m_OrderedSystemGroups.size()) {
|
||||||
|
m_OrderedSystemGroups.resize(updateOrderLevel + 1);
|
||||||
|
}
|
||||||
|
UnorderedSystems& group = m_OrderedSystemGroups[updateOrderLevel];
|
||||||
System* system = new T(m_EventBroker, args...);
|
System* system = new T(m_EventBroker, args...);
|
||||||
if (!system->m_ComponentType.empty()) {
|
group.Systems[typeid(T).name()] = system;
|
||||||
m_Systems[system->m_ComponentType].push_back(system);
|
|
||||||
|
if (std::is_base_of<PureSystem, T>::value) {
|
||||||
|
PureSystem* pureSystem = static_cast<PureSystem*>(system);
|
||||||
|
if (!pureSystem->m_ComponentType.empty()) {
|
||||||
|
group.PureSystems[pureSystem->m_ComponentType].push_back(pureSystem);
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Failed to add system \"%s\": Missing component type!", typeid(T).name());
|
LOG_ERROR("Failed to add pure system \"%s\": Missing component type!", typeid(T).name());
|
||||||
delete system;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::is_base_of<ImpureSystem, T>::value) {
|
||||||
|
ImpureSystem* impureSystem = static_cast<ImpureSystem*>(system);
|
||||||
|
group.ImpureSystems.push_back(impureSystem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update(World* world, double dt)
|
void Update(World* world, double dt)
|
||||||
{
|
{
|
||||||
for (auto& pair : m_Systems) {
|
for (UnorderedSystems& group : m_OrderedSystemGroups) {
|
||||||
|
// Process events
|
||||||
|
for (auto& pair : group.Systems) {
|
||||||
|
m_EventBroker->Process(pair.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update
|
||||||
|
for (auto& pair : group.PureSystems) {
|
||||||
const std::string& componentName = pair.first;
|
const std::string& componentName = pair.first;
|
||||||
auto& systems = pair.second;
|
auto& systems = pair.second;
|
||||||
const ComponentPool* pool = world->GetComponents(componentName);
|
const ComponentPool* pool = world->GetComponents(componentName);
|
||||||
@@ -44,15 +65,25 @@ public:
|
|||||||
}
|
}
|
||||||
for (auto& component : *pool) {
|
for (auto& component : *pool) {
|
||||||
for (auto& system : systems) {
|
for (auto& system : systems) {
|
||||||
system->Update(world, component, dt);
|
system->UpdateComponent(world, component, dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (auto& system : group.ImpureSystems) {
|
||||||
|
system->Update(world, dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const EventBroker* m_EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
std::unordered_map<std::string, std::vector<System*>> m_Systems;
|
struct UnorderedSystems
|
||||||
|
{
|
||||||
|
std::map<std::string, System*> Systems;
|
||||||
|
std::map<std::string, std::vector<PureSystem*>> PureSystems;
|
||||||
|
std::vector<ImpureSystem*> ImpureSystems;
|
||||||
|
};
|
||||||
|
std::vector<UnorderedSystems> m_OrderedSystemGroups;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#ifndef Transform_h__
|
||||||
|
#define Transform_h__
|
||||||
|
|
||||||
|
#include "../GLM.h"
|
||||||
|
#include "World.h"
|
||||||
|
|
||||||
|
static class Transform
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static glm::vec3 AbsolutePosition(World* world, EntityID entity)
|
||||||
|
{
|
||||||
|
glm::vec3 position;
|
||||||
|
|
||||||
|
while (entity != EntityID_Invalid) {
|
||||||
|
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
||||||
|
EntityID parent = world->GetParent(entity);
|
||||||
|
position += AbsoluteOrientation(world, parent) * (glm::vec3)transform["Position"];
|
||||||
|
entity = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return position;
|
||||||
|
};
|
||||||
|
|
||||||
|
static glm::quat AbsoluteOrientation(World* world, EntityID entity)
|
||||||
|
{
|
||||||
|
glm::quat orientation;
|
||||||
|
|
||||||
|
while (entity != EntityID_Invalid) {
|
||||||
|
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
||||||
|
orientation = glm::quat((glm::vec3)transform["Orientation"]) * orientation;
|
||||||
|
entity = world->GetParent(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return orientation;
|
||||||
|
};
|
||||||
|
|
||||||
|
static glm::vec3 AbsoluteScale(World* world, EntityID entity)
|
||||||
|
{
|
||||||
|
glm::vec3 scale(1.f);
|
||||||
|
|
||||||
|
while (entity != EntityID_Invalid) {
|
||||||
|
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
||||||
|
scale *= (glm::vec3)transform["Scale"];
|
||||||
|
entity = world->GetParent(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
static glm::mat4 ModelMatrix(EntityID entity, World* world)
|
||||||
|
{
|
||||||
|
glm::vec3 position = Transform::AbsolutePosition(world, entity);
|
||||||
|
glm::quat orientation = Transform::AbsoluteOrientation(world, entity);
|
||||||
|
glm::vec3 scale = Transform::AbsoluteScale(world, entity);
|
||||||
|
|
||||||
|
glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(orientation) * glm::scale(scale);
|
||||||
|
return modelMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// Example:
|
||||||
|
// DEBUG_IF(condition) {
|
||||||
|
// // This code is executed only in debug mode and if condition is true.
|
||||||
|
// }
|
||||||
|
// NOTE: condition statement is not executed at all in release mode.
|
||||||
|
#ifndef DEBUG_IF
|
||||||
|
#ifndef DEBUG
|
||||||
|
#define DEBUG_IF(c) if(c)
|
||||||
|
#else
|
||||||
|
#define DEBUG_IF(c) if(false)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef Util_XercesString_h__
|
||||||
|
#define Util_XercesString_h__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <xercesc/util/XercesDefs.hpp>
|
||||||
|
#include <xercesc/util/XMLString.hpp>
|
||||||
|
|
||||||
|
namespace XS
|
||||||
|
{
|
||||||
|
|
||||||
|
class ToString
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ToString(const XMLCh* const str) { m_AsChar = xercesc::XMLString::transcode(str); }
|
||||||
|
~ToString()
|
||||||
|
{
|
||||||
|
if (m_AsChar != nullptr) {
|
||||||
|
xercesc::XMLString::release(&m_AsChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator std::string() const { return std::string(m_AsChar); }
|
||||||
|
private:
|
||||||
|
char* m_AsChar = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ToXMLCh
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ToXMLCh(const std::string str) { m_Transcoded = xercesc::XMLString::transcode(str.c_str()); }
|
||||||
|
ToXMLCh(const char* str) { m_Transcoded = xercesc::XMLString::transcode(str); }
|
||||||
|
~ToXMLCh()
|
||||||
|
{
|
||||||
|
if (m_Transcoded != nullptr) {
|
||||||
|
xercesc::XMLString::release(&m_Transcoded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator const XMLCh*() const { return m_Transcoded; }
|
||||||
|
private:
|
||||||
|
XMLCh* m_Transcoded = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -14,24 +14,43 @@ public:
|
|||||||
|
|
||||||
// Create empty entity
|
// Create empty entity
|
||||||
EntityID CreateEntity(EntityID parent = 0);
|
EntityID CreateEntity(EntityID parent = 0);
|
||||||
|
// Delete entity and all components within
|
||||||
|
void DeleteEntity(EntityID entity);
|
||||||
|
// Check if an entity exists
|
||||||
|
bool ValidEntity(EntityID entity) const;
|
||||||
// Register a component type and allocate space for it
|
// Register a component type and allocate space for it
|
||||||
void RegisterComponent(ComponentInfo& ci);
|
void RegisterComponent(ComponentInfo& ci);
|
||||||
// Attach a component to an entity and fill it with default values
|
// Attach a component to an entity and fill it with default values
|
||||||
ComponentWrapper AttachComponent(EntityID entity, std::string componentType);
|
ComponentWrapper AttachComponent(EntityID entity, std::string componentType);
|
||||||
|
// Check if an entity has a component
|
||||||
|
bool HasComponent(EntityID entity, std::string componentType) const;
|
||||||
// Get a component of an entity
|
// Get a component of an entity
|
||||||
ComponentWrapper GetComponent(EntityID entity, std::string componentType);
|
ComponentWrapper GetComponent(EntityID entity, std::string componentType);
|
||||||
|
// Delete a component off an entity
|
||||||
|
void DeleteComponent(EntityID entity, std::string componentType);
|
||||||
// Get all components of the specified type
|
// Get all components of the specified type
|
||||||
const ComponentPool* GetComponents(std::string componentType);
|
const ComponentPool* GetComponents(std::string componentType);
|
||||||
// Get entity parent
|
// Get entity parent
|
||||||
EntityID GetParent(EntityID entity);
|
EntityID GetParent(EntityID entity);
|
||||||
|
// Change the parent of an entity
|
||||||
|
void SetParent(EntityID entity, EntityID parent);
|
||||||
|
// Get all component pools
|
||||||
|
const std::unordered_map<std::string, ComponentPool*>& GetComponentPools() const { return m_ComponentPools; }
|
||||||
|
// Get the entity children map
|
||||||
|
const std::unordered_multimap<EntityID, EntityID>& GetEntityChildren() const { return m_EntityChildren; }
|
||||||
|
// Set the textual name of an entity
|
||||||
|
void SetName(EntityID entity, const std::string& name);
|
||||||
|
// Get the textual name of an entity
|
||||||
|
std::string GetName(EntityID entity) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EntityID m_CurrentEntityID = 1;
|
EntityID m_CurrentEntityID = 0;
|
||||||
|
|
||||||
std::unordered_map<EntityID, EntityID> m_EntityParents;
|
std::unordered_map<EntityID, EntityID> m_EntityParents;
|
||||||
|
// TODO: This should be a more effective structure
|
||||||
std::unordered_multimap<EntityID, EntityID> m_EntityChildren;
|
std::unordered_multimap<EntityID, EntityID> m_EntityChildren;
|
||||||
std::unordered_map<std::string, ComponentPool*> m_ComponentPools;
|
std::unordered_map<std::string, ComponentPool*> m_ComponentPools;
|
||||||
|
std::unordered_map<EntityID, std::string> m_EntityNames;
|
||||||
|
|
||||||
EntityID generateEntityID();
|
EntityID generateEntityID();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
#include <imgui/imgui.h>
|
||||||
|
#include <glm/gtx/common.hpp>
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
#include <nativefiledialog/nfd.h>
|
||||||
|
#include "../Core/System.h"
|
||||||
|
#include "../Core/EMousePress.h"
|
||||||
|
#include "../Core/EMouseRelease.h"
|
||||||
|
#include "../Core/EMouseMove.h"
|
||||||
|
#include "../Core/ConfigFile.h"
|
||||||
|
#include "../Input/EInputCommand.h"
|
||||||
|
#include "../Rendering/IRenderer.h"
|
||||||
|
#include "../Core/Transform.h"
|
||||||
|
#include "../Core/EFileDropped.h"
|
||||||
|
#include "../Core/EntityFilePreprocessor.h"
|
||||||
|
#include "../Core/EntityFileParser.h"
|
||||||
|
#include "../Core/EntityFileWriter.h"
|
||||||
|
|
||||||
|
class EditorSystem : public ImpureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EditorSystem(EventBroker* eventBroker, IRenderer* renderer);
|
||||||
|
|
||||||
|
virtual void Update(World* world, double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
IRenderer* m_Renderer;
|
||||||
|
World* m_World = nullptr;
|
||||||
|
Camera* m_Camera = nullptr;
|
||||||
|
|
||||||
|
bool m_Enabled;
|
||||||
|
bool m_Visible;
|
||||||
|
boost::filesystem::path m_DefaultEntityDir;
|
||||||
|
boost::filesystem::path m_CurrentFile;
|
||||||
|
std::vector<glm::vec2> m_PickingQueue;
|
||||||
|
|
||||||
|
enum class WidgetMode
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Translate,
|
||||||
|
Rotate,
|
||||||
|
Scale
|
||||||
|
} m_WidgetMode = WidgetMode::None;
|
||||||
|
|
||||||
|
enum class WidgetSpace
|
||||||
|
{
|
||||||
|
Local,
|
||||||
|
Global
|
||||||
|
} m_WidgetSpace = WidgetSpace::Global;
|
||||||
|
|
||||||
|
EntityID m_Widget = EntityID_Invalid;
|
||||||
|
EntityID m_WidgetX = EntityID_Invalid;
|
||||||
|
EntityID m_WidgetPlaneX = EntityID_Invalid;
|
||||||
|
EntityID m_WidgetY = EntityID_Invalid;
|
||||||
|
EntityID m_WidgetPlaneY = EntityID_Invalid;
|
||||||
|
EntityID m_WidgetZ = EntityID_Invalid;
|
||||||
|
EntityID m_WidgetPlaneZ = EntityID_Invalid;
|
||||||
|
EntityID m_WidgetOrigin = EntityID_Invalid;
|
||||||
|
glm::vec3 m_WidgetCurrentAxis;
|
||||||
|
float m_WidgetPickingDepth = 0.f;
|
||||||
|
glm::vec3 m_WidgetPickingPosition = glm::vec3(0);
|
||||||
|
|
||||||
|
EntityID m_Selection = EntityID_Invalid;
|
||||||
|
EntityID m_LastSelection = EntityID_Invalid;
|
||||||
|
EntityID m_UIDraggingEntity = EntityID_Invalid;
|
||||||
|
glm::vec3 m_Position;
|
||||||
|
std::string m_LastDroppedFile;
|
||||||
|
|
||||||
|
static boost::filesystem::path openDialog(boost::filesystem::path defaultPath);
|
||||||
|
static boost::filesystem::path saveDialog(boost::filesystem::path defaultPath);
|
||||||
|
|
||||||
|
EventRelay<EditorSystem, Events::InputCommand> m_EInputCommand;
|
||||||
|
bool OnInputCommand(const Events::InputCommand& e);
|
||||||
|
EventRelay<EditorSystem, Events::MouseRelease> m_EMouseRelease;
|
||||||
|
bool OnMouseRelease(const Events::MouseRelease& e);
|
||||||
|
EventRelay<EditorSystem, Events::MousePress> m_EMousePress;
|
||||||
|
bool OnMousePress(const Events::MousePress& e);
|
||||||
|
EventRelay<EditorSystem, Events::MouseMove> m_EMouseMove;
|
||||||
|
bool OnMouseMove(const Events::MouseMove& e);
|
||||||
|
EventRelay<EditorSystem, Events::FileDropped> m_EFileDropped;
|
||||||
|
bool OnFileDropped(const Events::FileDropped& e);
|
||||||
|
|
||||||
|
void Picking();
|
||||||
|
void createWidget();
|
||||||
|
void updateWidget();
|
||||||
|
void setWidgetMode(WidgetMode newMode);
|
||||||
|
void setWidgetSpace(WidgetSpace space);
|
||||||
|
void drawUI(World* world, double dt);
|
||||||
|
bool createDeleteButton(std::string componentType);
|
||||||
|
bool createEntityNode(World* world, EntityID entity);
|
||||||
|
void changeParent(EntityID entity, EntityID newParent);
|
||||||
|
void fileImport(World* world);
|
||||||
|
void fileSave(World* world);
|
||||||
|
void fileSaveAs(World* world);
|
||||||
|
};
|
||||||
@@ -40,7 +40,7 @@ public:
|
|||||||
m_TexturePressed = resourceName;
|
m_TexturePressed = resourceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw(RenderQueueCollection& rq) override
|
void Draw(RenderScene& rq) override
|
||||||
{
|
{
|
||||||
if (m_Texture == nullptr && !m_TextureReleased.empty()) {
|
if (m_Texture == nullptr && !m_TextureReleased.empty()) {
|
||||||
SetTexture(m_TextureReleased);
|
SetTexture(m_TextureReleased);
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ public:
|
|||||||
|
|
||||||
virtual void Update(double dt) { }
|
virtual void Update(double dt) { }
|
||||||
|
|
||||||
void DrawLayered(RenderQueueCollection& rq)
|
void DrawLayered(RenderScene& rq)
|
||||||
{
|
{
|
||||||
if (this->Hidden())
|
if (this->Hidden())
|
||||||
return;
|
return;
|
||||||
@@ -232,7 +232,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Draw(RenderQueueCollection& rq) { }
|
virtual void Draw(RenderScene& rq) { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
::EventBroker* m_EventBroker;
|
::EventBroker* m_EventBroker;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public:
|
|||||||
void EnableScissor() { m_ScissorEnabled = true; }
|
void EnableScissor() { m_ScissorEnabled = true; }
|
||||||
void DisableScissor() { m_ScissorEnabled = false; }
|
void DisableScissor() { m_ScissorEnabled = false; }
|
||||||
|
|
||||||
void Draw(RenderQueueCollection& rq) override
|
void Draw(RenderScene& rq) override
|
||||||
{
|
{
|
||||||
if (m_Texture == nullptr)
|
if (m_Texture == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
#ifndef Events_BindGamepadAxis_h__
|
|
||||||
#define Events_BindGamepadAxis_h__
|
|
||||||
|
|
||||||
#include "Core/EventBroker.h"
|
|
||||||
#include "Core/EGamepadAxis.h"
|
|
||||||
|
|
||||||
namespace Events
|
|
||||||
{
|
|
||||||
|
|
||||||
/** Called to bind a gamepad axis to an input command. */
|
|
||||||
struct BindGamepadAxis : Event
|
|
||||||
{
|
|
||||||
/** The axis to bind. */
|
|
||||||
Gamepad::Axis Axis;
|
|
||||||
/** The command to send. */
|
|
||||||
std::string Command;
|
|
||||||
/** The value to send for positive stimulation.
|
|
||||||
|
|
||||||
Multiplied by the 0-1 clamped value of the axis.
|
|
||||||
*/
|
|
||||||
float Value;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#ifndef Events_BindGamepadButton_h__
|
|
||||||
#define Events_BindGamepadButton_h__
|
|
||||||
|
|
||||||
#include "Core/EventBroker.h"
|
|
||||||
#include "Core/EGamepadButton.h"
|
|
||||||
|
|
||||||
namespace Events
|
|
||||||
{
|
|
||||||
|
|
||||||
/** Called to bind a gamepad button to an input command. */
|
|
||||||
struct BindGamepadButton : Event
|
|
||||||
{
|
|
||||||
/** The gamepad button to bind. */
|
|
||||||
Gamepad::Button Button;
|
|
||||||
/** The command to send. */
|
|
||||||
std::string Command;
|
|
||||||
/** The value to send for positive stimulation.
|
|
||||||
|
|
||||||
Multiplied by the 0-1 clamped value of the button.
|
|
||||||
*/
|
|
||||||
float Value;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#ifndef Events_BindKey_h__
|
|
||||||
#define Events_BindKey_h__
|
|
||||||
|
|
||||||
#include "Core/EventBroker.h"
|
|
||||||
|
|
||||||
namespace Events
|
|
||||||
{
|
|
||||||
|
|
||||||
/** Called to bind a keyboard key to an input command. */
|
|
||||||
struct BindKey : Event
|
|
||||||
{
|
|
||||||
/** The GLFW key code to bind. */
|
|
||||||
int KeyCode;
|
|
||||||
/** The command to send. */
|
|
||||||
std::string Command;
|
|
||||||
/** The value to send for positive stimulation.
|
|
||||||
|
|
||||||
Multiplied by the 0-1 clamped value of the key.
|
|
||||||
*/
|
|
||||||
float Value;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#ifndef Events_BindMouseButton_h__
|
|
||||||
#define Events_BindMouseButton_h__
|
|
||||||
|
|
||||||
#include "Core/EventBroker.h"
|
|
||||||
|
|
||||||
namespace Events
|
|
||||||
{
|
|
||||||
|
|
||||||
/** Called to bind a mouse button to an input command. */
|
|
||||||
struct BindMouseButton : Event
|
|
||||||
{
|
|
||||||
/** The GLFW mouse button code to bind. */
|
|
||||||
int Button;
|
|
||||||
/** The command to send. */
|
|
||||||
std::string Command;
|
|
||||||
/** The value to send for positive stimulation.
|
|
||||||
|
|
||||||
Multiplied by the 0-1 clamped value of the button.
|
|
||||||
*/
|
|
||||||
float Value;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef Events_BindOrigin_h__
|
||||||
|
#define Events_BindOrigin_h__
|
||||||
|
|
||||||
|
#include "Core/EventBroker.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Called to bind an input origin to an input command. */
|
||||||
|
struct BindOrigin : Event
|
||||||
|
{
|
||||||
|
/** The input origin to bind. */
|
||||||
|
std::string Origin;
|
||||||
|
/** The command to send. */
|
||||||
|
std::string Command;
|
||||||
|
/** The value to send for positive stimulation. */
|
||||||
|
float Value = 1.f;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -13,7 +13,7 @@ struct InputCommand : Event
|
|||||||
/** The command that was sent. */
|
/** The command that was sent. */
|
||||||
std::string Command;
|
std::string Command;
|
||||||
/** The value of the command. */
|
/** The value of the command. */
|
||||||
float Value;
|
float Value = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
#ifndef FirstPersonInputController_h__
|
||||||
|
#define FirstPersonInputController_h__
|
||||||
|
|
||||||
|
#include "../GLM.h"
|
||||||
|
#include "../Core/InputController.h"
|
||||||
|
#include "../Core/ELockMouse.h"
|
||||||
|
|
||||||
|
template <typename EventContext>
|
||||||
|
class FirstPersonInputController : public InputController<EventContext>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FirstPersonInputController(EventBroker* eventBroker, unsigned int playerID)
|
||||||
|
: InputController(eventBroker)
|
||||||
|
, m_PlayerID(playerID)
|
||||||
|
{
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse);
|
||||||
|
}
|
||||||
|
|
||||||
|
const glm::quat Orientation() const { return m_Orientation; }
|
||||||
|
|
||||||
|
void LockMouse()
|
||||||
|
{
|
||||||
|
Events::LockMouse e;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
m_MouseLocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnlockMouse()
|
||||||
|
{
|
||||||
|
Events::UnlockMouse e;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
m_MouseLocked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool OnCommand(const Events::InputCommand& e) override
|
||||||
|
{
|
||||||
|
if (m_PlayerID != e.PlayerID) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_MouseLocked) {
|
||||||
|
if (e.Command == "Pitch") {
|
||||||
|
float val = glm::radians(e.Value);
|
||||||
|
m_Orientation = m_Orientation * glm::angleAxis<float>(-val, glm::vec3(1, 0, 0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Command == "Yaw") {
|
||||||
|
float val = glm::radians(e.Value);
|
||||||
|
m_Orientation = glm::angleAxis<float>(-val, glm::vec3(0, 1, 0)) * m_Orientation;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const unsigned int m_PlayerID;
|
||||||
|
glm::quat m_Orientation;
|
||||||
|
bool m_MouseLocked = false;
|
||||||
|
|
||||||
|
EventRelay<EventContext, Events::LockMouse> m_ELockMouse;
|
||||||
|
bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; }
|
||||||
|
EventRelay<EventContext, Events::UnlockMouse> m_EUnlockMouse;
|
||||||
|
bool OnUnlockMouse(const Events::UnlockMouse& e) { m_MouseLocked = false; return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef InputHandler_h__
|
||||||
|
#define InputHandler_h__
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "../Core/EventBroker.h"
|
||||||
|
#include "InputProxy.h"
|
||||||
|
|
||||||
|
class InputHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InputHandler(EventBroker* eventBroker, InputProxy* inputProxy)
|
||||||
|
: m_EventBroker(eventBroker)
|
||||||
|
, m_InputProxy(inputProxy)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual bool BindOrigin(std::string origin, std::string command, float value) = 0;
|
||||||
|
virtual void Update(double dt) { }
|
||||||
|
virtual float GetCommandValue(std::string command) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
InputProxy* m_InputProxy;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef InputProxy_h__
|
||||||
|
#define InputProxy_h__
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "../Core/ResourceManager.h"
|
||||||
|
#include "../Core/ConfigFile.h"
|
||||||
|
#include "EInputCommand.h"
|
||||||
|
#include "EBindOrigin.h"
|
||||||
|
|
||||||
|
class InputHandler;
|
||||||
|
|
||||||
|
class InputProxy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InputProxy(EventBroker* eventBroker);
|
||||||
|
~InputProxy();
|
||||||
|
|
||||||
|
void LoadBindings(std::string file);
|
||||||
|
void Update(double dt);
|
||||||
|
void Process();
|
||||||
|
template <typename T>
|
||||||
|
void AddHandler();
|
||||||
|
void Publish(const Events::InputCommand& e);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
std::vector<InputHandler*> m_Handlers;
|
||||||
|
std::map<std::string, std::set<InputHandler*>> m_CommandHandlers;
|
||||||
|
|
||||||
|
// Represents every unique command (has of PlayerID & Command) and all values reported for that command this frame
|
||||||
|
std::map<std::pair<unsigned int, std::string>, std::vector<float>> m_CommandQueue;
|
||||||
|
|
||||||
|
std::map<std::string, float> m_CurrentCommandValues;
|
||||||
|
std::map<std::string, float> m_LastCommandValues;
|
||||||
|
|
||||||
|
EventRelay<InputProxy, Events::BindOrigin> m_EBindOrigin;
|
||||||
|
bool OnBindOrigin(const Events::BindOrigin& e);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void InputProxy::AddHandler()
|
||||||
|
{
|
||||||
|
m_Handlers.push_back(new T(m_EventBroker, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
#ifndef InputSystem_h__
|
|
||||||
#define InputSystem_h__
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
#include "Core/System.h"
|
|
||||||
#include "Core/EKeyUp.h"
|
|
||||||
#include "Core/EKeyDown.h"
|
|
||||||
#include "Core/EMousePress.h"
|
|
||||||
#include "Core/EMouseRelease.h"
|
|
||||||
#include "Core/EGamepadAxis.h"
|
|
||||||
#include "Core/EGamepadButton.h"
|
|
||||||
#include "Core/Util/EnumClassHash.h"
|
|
||||||
#include "EBindKey.h"
|
|
||||||
#include "EBindMouseButton.h"
|
|
||||||
#include "EBindGamepadAxis.h"
|
|
||||||
#include "EBindGamepadButton.h"
|
|
||||||
#include "EInputCommand.h"
|
|
||||||
|
|
||||||
namespace Systems
|
|
||||||
{
|
|
||||||
|
|
||||||
class InputSystem : public System
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
InputSystem(World* world, std::shared_ptr<dd::EventBroker> eventBroker)
|
|
||||||
: System(world, eventBroker)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void RegisterComponents(ComponentFactory* cf) override;
|
|
||||||
void Initialize() override;
|
|
||||||
|
|
||||||
void Update(double dt) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unordered_map<std::string, std::unordered_map<int, float>> m_CommandKeyboardValues; // command string -> keyboard key value for command
|
|
||||||
std::unordered_map<std::string, std::unordered_map<int, float>> m_CommandMouseButtonValues; // command string -> mouse button value for command
|
|
||||||
std::unordered_map<std::string, std::unordered_map<Gamepad::Axis, float, EnumClassHash>> m_CommandGamepadAxisValues; // command string -> gamepad axis value for command
|
|
||||||
std::unordered_map<std::string, std::unordered_map<Gamepad::Button, float, EnumClassHash>> m_CommandGamepadButtonValues; // command string -> gamepad button value for command
|
|
||||||
// Input binding tables
|
|
||||||
std::unordered_multimap<int, std::tuple<std::string, float>> m_KeyBindings; // GLFW_KEY... -> command string & value
|
|
||||||
std::unordered_multimap<int, std::tuple<std::string, float>> m_MouseButtonBindings; // GLFW_MOUSE_BUTTON... -> command string
|
|
||||||
std::unordered_multimap<Gamepad::Axis, std::tuple<std::string, float>, EnumClassHash> m_GamepadAxisBindings; // Gamepad::Axis -> command string & value
|
|
||||||
std::unordered_multimap<Gamepad::Button, std::tuple<std::string, float>, EnumClassHash> m_GamepadButtonBindings; // Gamepad::Button -> command string
|
|
||||||
|
|
||||||
// Input events
|
|
||||||
EventRelay<InputSystem, Events::KeyDown> m_EKeyDown;
|
|
||||||
bool OnKeyDown(const Events::KeyDown &event);
|
|
||||||
EventRelay<InputSystem, Events::KeyUp> m_EKeyUp;
|
|
||||||
bool OnKeyUp(const Events::KeyUp &event);
|
|
||||||
EventRelay<InputSystem, Events::MousePress> m_EMousePress;
|
|
||||||
bool OnMousePress(const Events::MousePress &event);
|
|
||||||
EventRelay<InputSystem, Events::MouseRelease> m_EMouseRelease;
|
|
||||||
bool OnMouseRelease(const Events::MouseRelease &event);
|
|
||||||
EventRelay<InputSystem, Events::GamepadAxis> m_EGamepadAxis;
|
|
||||||
bool OnGamepadAxis(const Events::GamepadAxis &event);
|
|
||||||
EventRelay<InputSystem, Events::GamepadButtonDown> m_EGamepadButtonDown;
|
|
||||||
bool OnGamepadButtonDown(const Events::GamepadButtonDown &event);
|
|
||||||
EventRelay<InputSystem, Events::GamepadButtonUp> m_EGamepadButtonUp;
|
|
||||||
bool OnGamepadButtonUp(const Events::GamepadButtonUp &event);
|
|
||||||
// Input binding events
|
|
||||||
EventRelay<InputSystem, Events::BindKey> m_EBindKey;
|
|
||||||
bool OnBindKey(const Events::BindKey &event);
|
|
||||||
EventRelay<InputSystem, Events::BindMouseButton> m_EBindMouseButton;
|
|
||||||
bool OnBindMouseButton(const Events::BindMouseButton &event);
|
|
||||||
EventRelay<InputSystem, Events::BindGamepadAxis> m_EBindGamepadAxis;
|
|
||||||
bool OnBindGamepadAxis(const Events::BindGamepadAxis &event);
|
|
||||||
EventRelay<InputSystem, Events::BindGamepadButton> m_EBindGamepadButton;
|
|
||||||
bool OnBindGamepadButton(const Events::BindGamepadButton &event);
|
|
||||||
|
|
||||||
float GetCommandTotalValue(std::string command);
|
|
||||||
void PublishCommand(int playerID, std::string command, float value);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef KeyboardInputHandler_h__
|
||||||
|
#define KeyboardInputHandler_h__
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include "InputHandler.h"
|
||||||
|
#include "Core/EKeyDown.h"
|
||||||
|
#include "Core/EKeyUp.h"
|
||||||
|
|
||||||
|
class KeyboardInputHandler : public InputHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy);
|
||||||
|
|
||||||
|
bool BindOrigin(std::string origin, std::string command, float value) override;
|
||||||
|
virtual float GetCommandValue(std::string command) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::string, int> m_OriginKeyCodes;
|
||||||
|
std::unordered_map<int, std::tuple<std::string, float>> m_KeyBindings; // GLFW_KEY... -> command string & value
|
||||||
|
std::unordered_map<std::string, float> m_CommandValues;
|
||||||
|
|
||||||
|
EventRelay<InputHandler, Events::KeyDown> m_EKeyDown;
|
||||||
|
bool OnKeyDown(const Events::KeyDown& e);
|
||||||
|
EventRelay<InputHandler, Events::KeyUp> m_EKeyUp;
|
||||||
|
bool OnKeyUp(const Events::KeyUp& e);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef MouseInputHandler_h__
|
||||||
|
#define MouseInputHandler_h__
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include "InputHandler.h"
|
||||||
|
#include "Core/EMousePress.h"
|
||||||
|
#include "Core/EMouseRelease.h"
|
||||||
|
#include "Core/EMouseMove.h"
|
||||||
|
|
||||||
|
class MouseInputHandler : public InputHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MouseInputHandler(EventBroker* eventBroker, InputProxy* inputProxy);
|
||||||
|
|
||||||
|
bool BindOrigin(std::string origin, std::string command, float value) override;
|
||||||
|
virtual float GetCommandValue(std::string command) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::string, int> m_OriginCodes;
|
||||||
|
std::unordered_map<std::string, char> m_OriginAxes;
|
||||||
|
std::unordered_map<int, std::tuple<std::string, float>> m_Bindings; // GLFW_MOUSE_BUTTON... -> command string & value
|
||||||
|
std::unordered_map<char, std::tuple<std::string, float>> m_Axes; // Axis -> command string & value
|
||||||
|
std::unordered_map<std::string, float> m_CommandValues;
|
||||||
|
std::unordered_map<std::string, float> m_ContinuousCommandValues;
|
||||||
|
|
||||||
|
EventRelay<InputHandler, Events::MousePress> m_EMousePress;
|
||||||
|
bool OnMousePress(const Events::MousePress& e);
|
||||||
|
EventRelay<InputHandler, Events::MouseRelease> m_EMouseRelease;
|
||||||
|
bool OnMouseRelease(const Events::MouseRelease& e);
|
||||||
|
EventRelay<InputHandler, Events::MouseMove> m_EMouseMove;
|
||||||
|
bool OnMouseMove(const Events::MouseMove& e);
|
||||||
|
|
||||||
|
bool hasOrigin(std::string origin);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,14 +1,84 @@
|
|||||||
#ifndef Client_h__
|
#ifndef Client_h__
|
||||||
#define Client_h__
|
#define Client_h__
|
||||||
|
|
||||||
#include <boost\asio.hpp>
|
#include <string>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
class Client
|
#include <glm/common.hpp>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
|
#include "Network/Network.h"
|
||||||
|
#include "Network/MessageType.h"
|
||||||
|
#include "Network/PlayerDefinition.h"
|
||||||
|
#include "Network/SnapshotDefinitions.h"
|
||||||
|
#include "Core/World.h"
|
||||||
|
#include "Core/EventBroker.h"
|
||||||
|
#include "Core/ConfigFile.h"
|
||||||
|
#include "Input/EInputCommand.h"
|
||||||
|
|
||||||
|
class Client : public Network
|
||||||
{
|
{
|
||||||
Client();
|
public:
|
||||||
|
Client(ConfigFile* config);
|
||||||
~Client();
|
~Client();
|
||||||
|
void Start(World* world, EventBroker* eventBroker) override;
|
||||||
|
void Update() override;
|
||||||
|
void Close();
|
||||||
|
private:
|
||||||
|
// Assio UDP logic
|
||||||
|
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
||||||
|
boost::asio::io_service m_IOService;
|
||||||
|
boost::asio::ip::udp::socket m_Socket;
|
||||||
|
|
||||||
|
// Sending message to server logic
|
||||||
|
int bytesRead = -1;
|
||||||
|
char readBuf[1024] = { 0 };
|
||||||
|
int snapshotInterval = 33;
|
||||||
|
std::clock_t previousSnapshotMessage = std::clock();
|
||||||
|
|
||||||
|
// Packet loss logic
|
||||||
|
unsigned int m_PacketID = 0;
|
||||||
|
unsigned int m_PreviousPacketID = 0;
|
||||||
|
unsigned int m_SendPacketID = 0;
|
||||||
|
|
||||||
|
// Game logic
|
||||||
|
World* m_World;
|
||||||
|
std::string m_PlayerName;
|
||||||
|
int m_PlayerID = -1;
|
||||||
|
|
||||||
|
// Network logic
|
||||||
|
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
|
||||||
|
SnapshotDefinitions m_NextSnapshot;
|
||||||
|
bool m_ThreadIsRunning = true;
|
||||||
|
double m_DurationOfPingTime;
|
||||||
|
std::clock_t m_StartPingTime;
|
||||||
|
// Use to check if we should send disconnect message
|
||||||
|
// if game is turned of by closing window.
|
||||||
|
bool m_WasStarted = false;
|
||||||
|
|
||||||
|
// Private member functions
|
||||||
|
void readFromServer();
|
||||||
|
void sendSnapshotToServer();
|
||||||
|
int receive(char* data, size_t length);
|
||||||
|
void send(Packet& packet);
|
||||||
|
void connect();
|
||||||
|
void disconnect();
|
||||||
|
void ping();
|
||||||
|
void moveMessageHead(char*& data, size_t& length, size_t stepSize);
|
||||||
|
void parseMessageType(Packet& packet);
|
||||||
|
void parseEventMessage(Packet& packet);
|
||||||
|
void parseConnect(Packet& packet);
|
||||||
|
void parsePing();
|
||||||
|
void parseServerPing();
|
||||||
|
void parseSnapshot(Packet& packet);
|
||||||
|
void identifyPacketLoss();
|
||||||
|
bool isConnected();
|
||||||
|
EntityID createPlayer();
|
||||||
|
|
||||||
|
// Events
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
EventRelay<Client, Events::InputCommand> m_EInputCommand;
|
||||||
|
bool OnInputCommand(const Events::InputCommand &e);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef MessageType_h__
|
||||||
|
#define MessageType_h__
|
||||||
|
|
||||||
|
// Message types used by both server and client.
|
||||||
|
// Used to determine what type of message was sent.
|
||||||
|
enum class MessageType
|
||||||
|
{
|
||||||
|
Connect,
|
||||||
|
Disconnect,
|
||||||
|
ClientPing,
|
||||||
|
ServerPing,
|
||||||
|
Message,
|
||||||
|
Snapshot,
|
||||||
|
Event,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef Network_h__
|
||||||
|
#define Network_h__
|
||||||
|
|
||||||
|
#include "Core/World.h"
|
||||||
|
#include "Core/EventBroker.h"
|
||||||
|
#include "Network/Packet.h"
|
||||||
|
|
||||||
|
#define MAXCONNECTIONS 8
|
||||||
|
#define INPUTSIZE 128
|
||||||
|
|
||||||
|
class Network
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Network() { };
|
||||||
|
virtual void Start(World* m_world, EventBroker *eventBroker) = 0;
|
||||||
|
virtual void Update() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#ifndef Packet_h__
|
||||||
|
#define Packet_h__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "Network/MessageType.h"
|
||||||
|
#include "Core/Util/Logging.h"
|
||||||
|
|
||||||
|
// Defines the
|
||||||
|
class Packet
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// arg1: Type of message (Connect, Disconnect...)
|
||||||
|
// arg2: PacketID for identifying packet loss.
|
||||||
|
Packet(MessageType type, unsigned int& packetID);
|
||||||
|
// Used to create packet from already existing data buffer.
|
||||||
|
Packet(char* data, const int sizeOfPacket);
|
||||||
|
|
||||||
|
~Packet();
|
||||||
|
// Add primitive types like int, float, char...
|
||||||
|
template<typename T>
|
||||||
|
void WritePrimitive(T val)
|
||||||
|
{
|
||||||
|
// Check if we are trying to add more than the package can fit.
|
||||||
|
if (m_MaxPacketSize < m_Offset + sizeof(T)) {
|
||||||
|
LOG_WARNING("Packet AddPrimitive(): You are trying to add more than we have allocated for!");
|
||||||
|
}
|
||||||
|
memcpy(m_Data + m_Offset, &val, sizeof(T));
|
||||||
|
m_Offset += sizeof(T);
|
||||||
|
}
|
||||||
|
// Pops the first element as if it was a primitive.
|
||||||
|
template<typename T>
|
||||||
|
T ReadPrimitive()
|
||||||
|
{
|
||||||
|
if (m_Offset < m_ReturnDataOffset + sizeof(T)) {
|
||||||
|
LOG_WARNING("Packet PopFrontPrimitive(): You are trying to remove more than what exists in this packet!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
T returnValue;
|
||||||
|
memcpy(&returnValue, m_Data + m_ReturnDataOffset, sizeof(T));
|
||||||
|
m_ReturnDataOffset += sizeof(T);
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
// Add a string to the message
|
||||||
|
void WriteString(std::string str);
|
||||||
|
// Add data to the message
|
||||||
|
void WriteData(char* data, int sizeOfData);
|
||||||
|
// Pops the first element as if it was a string.
|
||||||
|
std::string ReadString();
|
||||||
|
char* ReadData(int SizeOfData);
|
||||||
|
|
||||||
|
int Size() { return m_Offset; };
|
||||||
|
char* Data() { return m_Data; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
char* m_Data;
|
||||||
|
unsigned int m_ReturnDataOffset = 0;
|
||||||
|
int m_Offset = 0;
|
||||||
|
unsigned int m_MaxPacketSize = 128;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef PlayerDefinition_h__
|
||||||
|
#define PlayerDefinition_h__
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct PlayerDefinition {
|
||||||
|
int EntityID = -1;
|
||||||
|
std::string Name = "";
|
||||||
|
boost::asio::ip::udp::endpoint Endpoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,12 +1,85 @@
|
|||||||
#ifndef Server_h__
|
#ifndef Server_h__
|
||||||
#define Server_h__
|
#define Server_h__
|
||||||
|
|
||||||
#include <boost\asio.hpp>
|
#include <string>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
class Server
|
#include <glm/common.hpp>
|
||||||
|
#include <boost/asio/ip/udp.hpp>
|
||||||
|
|
||||||
|
#include "Network/MessageType.h"
|
||||||
|
#include "Network/PlayerDefinition.h"
|
||||||
|
#include "Core/World.h"
|
||||||
|
#include "Core/EventBroker.h"
|
||||||
|
#include "Network/Network.h"
|
||||||
|
|
||||||
|
class Server : public Network
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
Server();
|
Server();
|
||||||
~Server();
|
~Server();
|
||||||
|
void Start(World* m_world, EventBroker *eventBroker) override;
|
||||||
|
void Update() override;
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// UDP logic
|
||||||
|
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
||||||
|
boost::asio::io_service m_IOService;
|
||||||
|
boost::asio::ip::udp::socket m_Socket;
|
||||||
|
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
|
||||||
|
|
||||||
|
// Sending messages to client logic
|
||||||
|
char readBuffer[1024] = { 0 };
|
||||||
|
int bytesRead = 0;
|
||||||
|
// time for previouse message
|
||||||
|
std::clock_t previousePingMessage = std::clock();
|
||||||
|
std::clock_t previousSnapshotMessage = std::clock();
|
||||||
|
std::clock_t timOutTimer = std::clock();
|
||||||
|
// How often we send messages (milliseconds)
|
||||||
|
int intervalMs = 1000;
|
||||||
|
int snapshotInterval = 50;
|
||||||
|
int checkTimeOutInterval = 100;
|
||||||
|
|
||||||
|
//Timers
|
||||||
|
std::clock_t m_StartPingTime;
|
||||||
|
std::clock_t m_StopTimes[8];
|
||||||
|
|
||||||
|
// Game logic
|
||||||
|
World* m_World;
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
// vec.size() = ammount of players to create, stores playerID's
|
||||||
|
std::vector<unsigned int> m_PlayersToCreate;
|
||||||
|
|
||||||
|
// Packet loss logic
|
||||||
|
unsigned int m_PacketID;
|
||||||
|
unsigned int m_PreviousPacketID;
|
||||||
|
unsigned int m_SendPacketID;
|
||||||
|
|
||||||
|
// Close logic
|
||||||
|
bool m_ThreadIsRunning = true;
|
||||||
|
|
||||||
|
// Private member functions
|
||||||
|
int receive(char* data, size_t length);
|
||||||
|
void readFromClients();
|
||||||
|
void send(Packet& packet, int playerID);
|
||||||
|
void send(Packet& packet);
|
||||||
|
void moveMessageHead(char*& data, size_t& length, size_t stepSize);
|
||||||
|
void broadcast(std::string message);
|
||||||
|
void broadcast(Packet& packet);
|
||||||
|
void sendSnapshot();
|
||||||
|
void sendPing();
|
||||||
|
void checkForTimeOuts();
|
||||||
|
void disconnect(int i);
|
||||||
|
void parseMessageType(Packet& packet);
|
||||||
|
void parseEvent(Packet& packet);
|
||||||
|
void parseConnect(Packet& packet);
|
||||||
|
void parseDisconnect();
|
||||||
|
void parseClientPing();
|
||||||
|
void parseServerPing();
|
||||||
|
void parseSnapshot(Packet& packet);
|
||||||
|
void identifyPacketLoss();
|
||||||
|
EntityID createPlayer();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef SnapshotDefinitions_h__
|
||||||
|
#define SnapshotDefinitions_h__
|
||||||
|
|
||||||
|
struct SnapshotDefinitions
|
||||||
|
{
|
||||||
|
// "+Forward" is 8 characters * sizeof(char) = 8
|
||||||
|
std::string InputForward;
|
||||||
|
// "+Right" is 6 characters * sizeof(char) = 6
|
||||||
|
std::string InputRight;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -26,13 +26,12 @@ public:
|
|||||||
glm::quat Orientation() const { return m_Orientation; }
|
glm::quat Orientation() const { return m_Orientation; }
|
||||||
void SetOrientation(glm::quat val);
|
void SetOrientation(glm::quat val);
|
||||||
|
|
||||||
/*float Pitch() const { return m_Pitch; }
|
|
||||||
void Pitch(float val);
|
|
||||||
float Yaw() const { return m_Yaw; }
|
|
||||||
void Yaw(float val);*/
|
|
||||||
|
|
||||||
glm::mat4 ProjectionMatrix() const { return m_ProjectionMatrix; }
|
glm::mat4 ProjectionMatrix() const { return m_ProjectionMatrix; }
|
||||||
|
void SetProjectionMatrix(glm::mat4 val);
|
||||||
|
|
||||||
glm::mat4 ViewMatrix() const { return m_ViewMatrix; }
|
glm::mat4 ViewMatrix() const { return m_ViewMatrix; }
|
||||||
|
void SetViewMatrix(glm::mat4 val);
|
||||||
|
|
||||||
|
|
||||||
float AspectRatio() const { return m_AspectRatio; }
|
float AspectRatio() const { return m_AspectRatio; }
|
||||||
void SetAspectRatio(float val);
|
void SetAspectRatio(float val);
|
||||||
@@ -46,12 +45,11 @@ public:
|
|||||||
float FarClip() const { return m_FarClip; }
|
float FarClip() const { return m_FarClip; }
|
||||||
void SetFarClip(float val);
|
void SetFarClip(float val);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
void UpdateViewMatrix();
|
void UpdateViewMatrix();
|
||||||
void UpdateProjectionMatrix();
|
void UpdateProjectionMatrix();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
glm::vec3 m_Position;
|
glm::vec3 m_Position;
|
||||||
glm::quat m_Orientation;
|
glm::quat m_Orientation;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#include <imgui/imgui.h>
|
||||||
|
#include "../Input/FirstPersonInputController.h"
|
||||||
|
|
||||||
|
template <typename EventContext>
|
||||||
|
class DebugCameraInputController : public FirstPersonInputController<EventContext>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DebugCameraInputController(EventBroker* eventBroker, unsigned int playerID)
|
||||||
|
: FirstPersonInputController(eventBroker, playerID)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void SetPosition(const glm::vec3 position) { m_Position = position; }
|
||||||
|
void SetOrientation(const glm::quat orientation) { m_Orientation = orientation; }
|
||||||
|
|
||||||
|
const glm::vec3 Position() const { return m_Position; }
|
||||||
|
void SetBaseSpeed(float speed) { m_BaseSpeed = speed; }
|
||||||
|
|
||||||
|
virtual bool OnCommand(const Events::InputCommand& e) override
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
if (e.Command == "PrimaryFire") {
|
||||||
|
if (e.Value > 0) {
|
||||||
|
if (!io.WantCaptureMouse) {
|
||||||
|
LockMouse();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
UnlockMouse();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!io.WantCaptureKeyboard) {
|
||||||
|
if (e.Command == "Right") {
|
||||||
|
float value = std::max(-1.f, std::min(e.Value, 1.f));
|
||||||
|
m_Velocity.x = value;
|
||||||
|
}
|
||||||
|
if (e.Command == "Forward") {
|
||||||
|
float value = std::max(-1.f, std::min(e.Value, 1.f));
|
||||||
|
m_Velocity.z = -value;
|
||||||
|
}
|
||||||
|
if (e.Command == "Sprint") {
|
||||||
|
if (e.Value > 0.f) {
|
||||||
|
m_Speed = m_BaseSpeed * 2.f * (e.Value);
|
||||||
|
} else {
|
||||||
|
m_Speed = m_BaseSpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FirstPersonInputController::OnCommand(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(double dt)
|
||||||
|
{
|
||||||
|
if (glm::length2(m_Velocity) > 0) {
|
||||||
|
m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_Speed * (float)dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
glm::vec3 m_Position = glm::vec3(0, 0, 0);
|
||||||
|
glm::vec3 m_Velocity = glm::vec3(0, 0, 0);
|
||||||
|
float m_BaseSpeed = 2.0f;
|
||||||
|
float m_Speed = m_BaseSpeed;
|
||||||
|
};
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#ifndef DrawScenePass_h__
|
||||||
|
#define DrawScenePass_h__
|
||||||
|
|
||||||
|
#include "IRenderer.h"
|
||||||
|
#include "DrawScenePassState.h"
|
||||||
|
#include "FrameBuffer.h"
|
||||||
|
#include "ShaderProgram.h"
|
||||||
|
#include "Util/UnorderedMapVec2.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
|
||||||
|
class DrawScenePass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DrawScenePass(IRenderer* renderer);
|
||||||
|
~DrawScenePass() { }
|
||||||
|
void InitializeTextures();
|
||||||
|
void InitializeFrameBuffers();
|
||||||
|
void InitializeShaderPrograms();
|
||||||
|
|
||||||
|
void Draw(RenderScene& scene);
|
||||||
|
|
||||||
|
//Getters
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
|
||||||
|
|
||||||
|
static bool DepthSort(const std::shared_ptr<RenderJob> &i, const std::shared_ptr<RenderJob> &j)
|
||||||
|
{
|
||||||
|
return (i->Depth < j->Depth);
|
||||||
|
};
|
||||||
|
|
||||||
|
Texture* m_WhiteTexture;
|
||||||
|
|
||||||
|
const IRenderer* m_Renderer;
|
||||||
|
|
||||||
|
ShaderProgram* m_BasicForwardProgram;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#ifndef DrawScenePassState_h__
|
||||||
|
#define DrawScenePassState_h__
|
||||||
|
|
||||||
|
#include "Rendering/RenderState.h"
|
||||||
|
|
||||||
|
class DrawScenePassState : public RenderState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DrawScenePassState();
|
||||||
|
~DrawScenePassState();
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -9,7 +9,7 @@ class DummyRenderer : public IRenderer
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void Initialize() override;
|
virtual void Initialize() override;
|
||||||
virtual void Draw(RenderQueueCollection& rq) override;
|
virtual void Draw(RenderFrame& rq) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
#ifndef Events_Picking_h__
|
|
||||||
#define Events_Picking_h__
|
|
||||||
|
|
||||||
#include "../OpenGL.h"
|
|
||||||
#include "../GLM.h"
|
|
||||||
|
|
||||||
#include "../Core/EventBroker.h"
|
|
||||||
#include "Util/ScreenCoords.h"
|
|
||||||
#include "FrameBuffer.h"
|
|
||||||
#include "../Core/Entity.h"
|
|
||||||
#include "Util/UnorderedMapVec2.h"
|
|
||||||
|
|
||||||
namespace Events
|
|
||||||
{
|
|
||||||
|
|
||||||
/** Thrown Every frame, use functions to pick*/
|
|
||||||
struct Picking : Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Picking(FrameBuffer* pickingBuffer, GLuint* depthBuffer, glm::mat4 projectionMatrix, glm::mat4 viewMatrix, Rectangle resolution, const std::unordered_map<glm::vec2, EntityID>* pickingColorsToEntity)
|
|
||||||
: PickingBuffer(pickingBuffer)
|
|
||||||
, DepthBuffer(depthBuffer)
|
|
||||||
, ProjectionMatrix(projectionMatrix)
|
|
||||||
, ViewMatrix(viewMatrix)
|
|
||||||
, Resolution(resolution)
|
|
||||||
, PickingColorsToEntity(pickingColorsToEntity)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct PickData
|
|
||||||
{
|
|
||||||
//Picked Entity
|
|
||||||
EntityID Entity;
|
|
||||||
//World position of the "pick"
|
|
||||||
glm::vec3 Position;
|
|
||||||
};
|
|
||||||
|
|
||||||
PickData Pick(glm::vec2 screenCoord) const
|
|
||||||
{
|
|
||||||
PickData pickData;
|
|
||||||
|
|
||||||
ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, PickingBuffer, *DepthBuffer);
|
|
||||||
|
|
||||||
auto it = PickingColorsToEntity->find(glm::vec2(data.Color[0], data.Color[1]));
|
|
||||||
if (it != PickingColorsToEntity->end()) {
|
|
||||||
pickData.Entity = it->second;
|
|
||||||
} else {
|
|
||||||
pickData.Entity = -1;
|
|
||||||
}
|
|
||||||
pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, Resolution.Width - screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix);
|
|
||||||
|
|
||||||
return pickData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
FrameBuffer* PickingBuffer;
|
|
||||||
GLuint* DepthBuffer;
|
|
||||||
const glm::mat4 ProjectionMatrix;
|
|
||||||
const glm::mat4 ViewMatrix;
|
|
||||||
const Rectangle Resolution;
|
|
||||||
const std::unordered_map<glm::vec2, EntityID>* PickingColorsToEntity;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef Events_SetCamera_h__
|
||||||
|
#define Events_SetCamera_h__
|
||||||
|
|
||||||
|
#include "../Core/EventBroker.h"
|
||||||
|
#include "../Core/Entity.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct SetCamera : Event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SetCamera() { };
|
||||||
|
std::string Name;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -10,6 +10,15 @@
|
|||||||
#include "RenderQueue.h"
|
#include "RenderQueue.h"
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
|
|
||||||
|
struct PickData
|
||||||
|
{
|
||||||
|
EntityID Entity;
|
||||||
|
glm::vec3 Position; //World position
|
||||||
|
float Depth;
|
||||||
|
::Camera* Camera;
|
||||||
|
const ::World* World;
|
||||||
|
};
|
||||||
|
|
||||||
class IRenderer
|
class IRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -29,20 +38,20 @@ public:
|
|||||||
m_Camera = camera;
|
m_Camera = camera;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Initialize() = 0;
|
virtual void Initialize() = 0;
|
||||||
virtual void Update(double dt) = 0;
|
virtual void Update(double dt) = 0;
|
||||||
virtual void Draw(RenderQueueCollection& rq) = 0;
|
virtual void Draw(RenderFrame& rq) = 0;
|
||||||
|
virtual PickData Pick(glm::vec2 screenCord) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Rectangle m_Resolution = Rectangle(1280, 720);
|
Rectangle m_Resolution = Rectangle::Rectangle(1280, 720);
|
||||||
bool m_Fullscreen = false;
|
bool m_Fullscreen = false;
|
||||||
bool m_VSYNC = false;
|
bool m_VSYNC = false;
|
||||||
int m_GLVersion[2];
|
int m_GLVersion[2];
|
||||||
std::string m_GLVendor;
|
std::string m_GLVendor;
|
||||||
|
GLFWwindow* m_Window = nullptr;
|
||||||
::Camera* m_DefaultCamera;
|
::Camera* m_DefaultCamera;
|
||||||
::Camera* m_Camera = nullptr;
|
::Camera* m_Camera = nullptr;
|
||||||
GLFWwindow* m_Window = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // Renderer_h__
|
#endif // Renderer_h__
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
#include <imgui/imgui.h>
|
||||||
|
#include "../OpenGL.h"
|
||||||
|
#include "IRenderer.h"
|
||||||
|
#include "RenderState.h"
|
||||||
|
#include "../Core/EventBroker.h"
|
||||||
|
#include "../Core/EMousePress.h"
|
||||||
|
#include "../Core/EMouseRelease.h"
|
||||||
|
#include "../Core/EMouseMove.h"
|
||||||
|
#include "../Core/EMouseScroll.h"
|
||||||
|
#include "../Core/EKeyDown.h"
|
||||||
|
#include "../Core/EKeyUp.h"
|
||||||
|
#include "../Core/EKeyboardChar.h"
|
||||||
|
|
||||||
|
class ImGuiRenderState : public RenderState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImGuiRenderState()
|
||||||
|
: RenderState()
|
||||||
|
{
|
||||||
|
BindFramebuffer(0);
|
||||||
|
Enable(GL_BLEND);
|
||||||
|
BlendEquation(GL_FUNC_ADD);
|
||||||
|
BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
Disable(GL_CULL_FACE);
|
||||||
|
Disable(GL_DEPTH_TEST);
|
||||||
|
Enable(GL_SCISSOR_TEST);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImGuiRenderPass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImGuiRenderPass(IRenderer* renderer, EventBroker* eventBroker);
|
||||||
|
|
||||||
|
void Update(double dt);
|
||||||
|
void Draw();
|
||||||
|
|
||||||
|
private:
|
||||||
|
IRenderer* m_Renderer;
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
|
||||||
|
GLFWwindow* g_Window;
|
||||||
|
double g_DeltaTime = 0.0;
|
||||||
|
float g_MouseWheel = 0.f;
|
||||||
|
GLuint g_FontTexture;
|
||||||
|
int g_ShaderHandle;
|
||||||
|
int g_VertHandle;
|
||||||
|
int g_FragHandle;
|
||||||
|
int g_AttribLocationTex;
|
||||||
|
int g_AttribLocationProjMtx;
|
||||||
|
int g_AttribLocationPosition;
|
||||||
|
int g_AttribLocationUV;
|
||||||
|
int g_AttribLocationColor;
|
||||||
|
GLuint g_VboHandle;
|
||||||
|
GLuint g_VaoHandle;
|
||||||
|
GLuint g_ElementsHandle;
|
||||||
|
|
||||||
|
EventRelay<ImGuiRenderPass, Events::MousePress> m_EMousePress;
|
||||||
|
bool OnMousePress(const Events::MousePress& e);
|
||||||
|
EventRelay<ImGuiRenderPass, Events::MouseRelease> m_EMouseRelease;
|
||||||
|
bool OnMouseRelease(const Events::MouseRelease& e);
|
||||||
|
EventRelay<ImGuiRenderPass, Events::MouseMove> m_EMouseMove;
|
||||||
|
bool OnMouseMove(const Events::MouseMove& e);
|
||||||
|
EventRelay<ImGuiRenderPass, Events::MouseScroll> m_EMouseScroll;
|
||||||
|
bool OnMouseScroll(const Events::MouseScroll& e);
|
||||||
|
EventRelay<ImGuiRenderPass, Events::KeyDown> m_EKeyDown;
|
||||||
|
bool OnKeyDown(const Events::KeyDown& e);
|
||||||
|
EventRelay<ImGuiRenderPass, Events::KeyUp> m_EKeyUp;
|
||||||
|
bool OnKeyUp(const Events::KeyUp& e);
|
||||||
|
EventRelay<ImGuiRenderPass, Events::KeyboardChar> m_EKeyboardChar;
|
||||||
|
bool OnKeyboardChar(const Events::KeyboardChar& e);
|
||||||
|
|
||||||
|
bool createDeviceObjects();
|
||||||
|
bool createFontsTexture();
|
||||||
|
|
||||||
|
void newFrame();
|
||||||
|
};
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#ifndef ModelJob_h__
|
||||||
|
#define ModelJob_h__
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "../GLM.h"
|
||||||
|
#include "../Core/ComponentWrapper.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
#include "Model.h"
|
||||||
|
#include "RenderJob.h"
|
||||||
|
#include "../Core/ResourceManager.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "../Core/World.h"
|
||||||
|
|
||||||
|
struct ModelJob : RenderJob
|
||||||
|
{
|
||||||
|
ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::Model::MaterialGroup texGroup, ComponentWrapper modelComponent, World* world)
|
||||||
|
: RenderJob()
|
||||||
|
{
|
||||||
|
Model = model;
|
||||||
|
TextureID = (texGroup.Texture) ? texGroup.Texture->ResourceID : 0;
|
||||||
|
DiffuseTexture = texGroup.Texture.get();
|
||||||
|
NormalTexture = texGroup.NormalMap.get();
|
||||||
|
SpecularTexture = texGroup.SpecularMap.get();
|
||||||
|
StartIndex = texGroup.StartIndex;
|
||||||
|
EndIndex = texGroup.EndIndex;
|
||||||
|
Matrix = matrix;
|
||||||
|
Color = modelComponent["Color"];
|
||||||
|
Entity = modelComponent.EntityID;
|
||||||
|
World = world;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int TextureID;
|
||||||
|
unsigned int ShaderID;
|
||||||
|
|
||||||
|
EntityID Entity;
|
||||||
|
glm::mat4 Matrix;
|
||||||
|
const Texture* DiffuseTexture;
|
||||||
|
const Texture* NormalTexture;
|
||||||
|
const Texture* SpecularTexture;
|
||||||
|
float Shininess = 0.f;
|
||||||
|
glm::vec4 Color;
|
||||||
|
const ::Model* Model = nullptr;
|
||||||
|
unsigned int StartIndex = 0;
|
||||||
|
unsigned int EndIndex = 0;
|
||||||
|
const World* World;
|
||||||
|
|
||||||
|
void CalculateHash() override
|
||||||
|
{
|
||||||
|
Hash = TextureID;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#ifndef PickingPass_h__
|
||||||
|
#define PickingPass_h__
|
||||||
|
|
||||||
|
#include "IRenderer.h"
|
||||||
|
#include "PickingPassState.h"
|
||||||
|
#include "FrameBuffer.h"
|
||||||
|
#include "ShaderProgram.h"
|
||||||
|
#include "Util/UnorderedMapiVec2.h"
|
||||||
|
#include "../Core/EventBroker.h"
|
||||||
|
#include "../Core/World.h"
|
||||||
|
|
||||||
|
class PickingPass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PickingPass(IRenderer* renderer, EventBroker* eb);
|
||||||
|
~PickingPass();
|
||||||
|
void InitializeTextures();
|
||||||
|
void InitializeFrameBuffers();
|
||||||
|
void InitializeShaderPrograms();
|
||||||
|
|
||||||
|
void Draw(RenderScene& scene);
|
||||||
|
void ClearPicking();
|
||||||
|
|
||||||
|
|
||||||
|
//Getters
|
||||||
|
const ShaderProgram& PickingProgram() const { return *m_PickingProgram; }
|
||||||
|
//const std::unordered_map<glm::ivec2, EntityID>& PickingColorsToEntity() const { return m_PickingColorsToEntity; }
|
||||||
|
GLuint PickingTexture() const { return m_PickingTexture; }
|
||||||
|
GLuint DepthBuffer() const { return m_DepthBuffer; }
|
||||||
|
const FrameBuffer& PickingBuffer() const { return m_PickingBuffer; }
|
||||||
|
|
||||||
|
|
||||||
|
PickData Pick(glm::vec2 screenCoord);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const;
|
||||||
|
|
||||||
|
EventBroker* m_EventBroker;
|
||||||
|
|
||||||
|
const IRenderer* m_Renderer;
|
||||||
|
|
||||||
|
ShaderProgram* m_PickingProgram;
|
||||||
|
Camera* m_Camera;
|
||||||
|
|
||||||
|
struct PickingInfo
|
||||||
|
{
|
||||||
|
EntityID Entity;
|
||||||
|
const ::World* World;
|
||||||
|
::Camera* Camera;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<glm::ivec2, PickingInfo> m_PickingColorsToEntity;
|
||||||
|
|
||||||
|
GLuint m_PickingTexture;
|
||||||
|
GLuint m_DepthBuffer;
|
||||||
|
|
||||||
|
FrameBuffer m_PickingBuffer;
|
||||||
|
|
||||||
|
int m_ColorCounter[2];
|
||||||
|
std::map<std::tuple<EntityID, const World*, Camera*>, glm::ivec2> m_EntityColors;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#ifndef PickingPassState_h__
|
||||||
|
#define PickingPassState_h__
|
||||||
|
|
||||||
|
#include "Rendering/RenderState.h"
|
||||||
|
|
||||||
|
class PickingPassState : public RenderState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PickingPassState(GLuint frameBuffer);
|
||||||
|
~PickingPassState();
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -46,6 +46,7 @@ public:
|
|||||||
struct MaterialGroup
|
struct MaterialGroup
|
||||||
{
|
{
|
||||||
float Shininess;
|
float Shininess;
|
||||||
|
float Transparency;
|
||||||
std::shared_ptr<::Texture> Texture;
|
std::shared_ptr<::Texture> Texture;
|
||||||
std::shared_ptr<::Texture> NormalMap;
|
std::shared_ptr<::Texture> NormalMap;
|
||||||
std::shared_ptr<::Texture> SpecularMap;
|
std::shared_ptr<::Texture> SpecularMap;
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef RenderJob_h__
|
||||||
|
#define RenderJob_h__
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "../GLM.h"
|
||||||
|
#include "../Core/ComponentWrapper.h"
|
||||||
|
#include "RenderQueue.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct RenderJob
|
||||||
|
{
|
||||||
|
friend class RenderQueue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
float Depth;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint64_t Hash;
|
||||||
|
|
||||||
|
virtual void CalculateHash() = 0;
|
||||||
|
|
||||||
|
bool operator<(const RenderJob& rhs)
|
||||||
|
{
|
||||||
|
return this->Hash < rhs.Hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -8,164 +8,57 @@
|
|||||||
#include "../GLM.h"
|
#include "../GLM.h"
|
||||||
#include "../Core/Util/Rectangle.h"
|
#include "../Core/Util/Rectangle.h"
|
||||||
#include "../Core/Entity.h"
|
#include "../Core/Entity.h"
|
||||||
#include "Font.h"
|
#include "Camera.h"
|
||||||
|
#include "RenderJob.h"
|
||||||
|
#include "ModelJob.h"
|
||||||
|
#include "TextJob.h"
|
||||||
|
|
||||||
class Model;
|
struct RenderScene
|
||||||
class Skeleton;
|
|
||||||
class Texture;
|
|
||||||
class RenderQueue;
|
|
||||||
|
|
||||||
//TODO: Render: Remove obsolete RenderJobs and fix standard values on variables.
|
|
||||||
|
|
||||||
struct RenderJob
|
|
||||||
{
|
{
|
||||||
friend class RenderQueue;
|
::Camera* Camera;
|
||||||
|
std::list<std::shared_ptr<RenderJob>> ForwardJobs;
|
||||||
|
std::list<std::shared_ptr<RenderJob>> LightJobs;
|
||||||
|
std::list<std::shared_ptr<RenderJob>> TextJobs;
|
||||||
|
Rectangle Viewport;
|
||||||
|
|
||||||
float Depth;
|
void Clear()
|
||||||
|
|
||||||
protected:
|
|
||||||
uint64_t Hash;
|
|
||||||
|
|
||||||
virtual void CalculateHash() = 0;
|
|
||||||
|
|
||||||
bool operator<(const RenderJob& rhs)
|
|
||||||
{
|
{
|
||||||
return this->Hash < rhs.Hash;
|
ForwardJobs.clear();
|
||||||
|
LightJobs.clear();
|
||||||
|
TextJobs.clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ModelJob : RenderJob
|
struct RenderFrame
|
||||||
{
|
|
||||||
unsigned int ShaderID = 0;
|
|
||||||
unsigned int TextureID = 0;
|
|
||||||
|
|
||||||
//TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this
|
|
||||||
EntityID Entity;
|
|
||||||
|
|
||||||
glm::mat4 ModelMatrix;
|
|
||||||
const Texture* DiffuseTexture;
|
|
||||||
const Texture* NormalTexture;
|
|
||||||
const Texture* SpecularTexture;
|
|
||||||
float Shininess = 0.f;
|
|
||||||
glm::vec4 Color;
|
|
||||||
const Model* Model = nullptr;
|
|
||||||
unsigned int StartIndex = 0;
|
|
||||||
unsigned int EndIndex = 0;
|
|
||||||
|
|
||||||
// Animation
|
|
||||||
Skeleton* Skeleton = nullptr;
|
|
||||||
bool NoRootMotion = true;
|
|
||||||
std::string AnimationName;
|
|
||||||
double AnimationTime = 0;
|
|
||||||
|
|
||||||
void CalculateHash() override
|
|
||||||
{
|
|
||||||
Hash = TextureID;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SpriteJob : RenderJob
|
|
||||||
{
|
|
||||||
unsigned int ShaderID = 0;
|
|
||||||
unsigned int TextureID = 0;
|
|
||||||
|
|
||||||
glm::mat4 ModelMatrix;
|
|
||||||
const Texture* DiffuseTexture = nullptr;
|
|
||||||
const Texture* NormalTexture = nullptr;
|
|
||||||
const Texture* SpecularTexture = nullptr;
|
|
||||||
glm::vec4 Color;
|
|
||||||
|
|
||||||
void CalculateHash() override
|
|
||||||
{
|
|
||||||
Hash = TextureID;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TextJob : RenderJob
|
|
||||||
{
|
|
||||||
glm::mat4 ModelMatrix;
|
|
||||||
glm::vec4 Color;
|
|
||||||
std::string Content;
|
|
||||||
Font* Resource;
|
|
||||||
|
|
||||||
void CalculateHash() override
|
|
||||||
{
|
|
||||||
Hash = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PointLightJob : RenderJob
|
|
||||||
{
|
|
||||||
glm::vec3 Position;
|
|
||||||
glm::vec3 SpecularColor = glm::vec3(1, 1, 1);
|
|
||||||
glm::vec3 DiffuseColor = glm::vec3(1, 1, 1);
|
|
||||||
float Radius = 1.f;
|
|
||||||
float Intensity = 0.8f;
|
|
||||||
|
|
||||||
void CalculateHash() override
|
|
||||||
{
|
|
||||||
Hash = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class RenderQueue
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
|
||||||
void Add(T &job)
|
|
||||||
{
|
|
||||||
job.CalculateHash();
|
|
||||||
Jobs.push_back(std::shared_ptr<T>(new T(job)));
|
|
||||||
m_Size++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sort()
|
void Add(RenderScene &scene)
|
||||||
{
|
{
|
||||||
Jobs.sort();
|
RenderScenes.push_back(std::shared_ptr<RenderScene>(new RenderScene(scene)));
|
||||||
|
m_Size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
Jobs.clear();
|
RenderScenes.clear();
|
||||||
m_Size = 0;
|
m_Size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Size() const { return m_Size; }
|
int Size() const { return m_Size; }
|
||||||
std::list<std::shared_ptr<RenderJob>>::const_iterator begin()
|
std::list<std::shared_ptr<RenderScene>>::const_iterator begin()
|
||||||
{
|
{
|
||||||
return Jobs.begin();
|
return RenderScenes.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<std::shared_ptr<RenderJob>>::const_iterator end()
|
std::list<std::shared_ptr<RenderScene>>::const_iterator end()
|
||||||
{
|
{
|
||||||
return Jobs.end();
|
return RenderScenes.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<std::shared_ptr<RenderJob>> Jobs;
|
std::list<std::shared_ptr<RenderScene>> RenderScenes;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_Size = 0;
|
int m_Size = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RenderQueueCollection
|
|
||||||
{
|
|
||||||
RenderQueue Forward;
|
|
||||||
RenderQueue Lights;
|
|
||||||
RenderQueue Text;
|
|
||||||
|
|
||||||
void Clear()
|
|
||||||
{
|
|
||||||
Forward.Clear();
|
|
||||||
Lights.Clear();
|
|
||||||
Text.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sort()
|
|
||||||
{
|
|
||||||
Forward.Sort();
|
|
||||||
Lights.Sort();
|
|
||||||
Text.Sort();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#ifndef RenderQueueFactory_h__
|
|
||||||
#define RenderQueueFactory_h__
|
|
||||||
|
|
||||||
#include "../Core/World.h"
|
|
||||||
#include "RenderQueue.h"
|
|
||||||
#include "../Core/ResourceManager.h"
|
|
||||||
#include "Model.h"
|
|
||||||
#include "../GLM.h"
|
|
||||||
|
|
||||||
class RenderQueueFactory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RenderQueueFactory();
|
|
||||||
void Update(World* world);
|
|
||||||
|
|
||||||
|
|
||||||
RenderQueueCollection RenderQueues() const { return m_RenderQueues; }
|
|
||||||
private:
|
|
||||||
RenderQueueCollection m_RenderQueues;
|
|
||||||
|
|
||||||
void FillModels(World* world, RenderQueue* renderQueue);
|
|
||||||
void FillLights(World* world, RenderQueue* renderQueue);
|
|
||||||
void FillText(World* world, RenderQueue* renderQueue);
|
|
||||||
|
|
||||||
glm::mat4 ModelMatrix(World* world, EntityID entity);
|
|
||||||
|
|
||||||
glm::vec3 AbsolutePosition(World* world, EntityID entity);
|
|
||||||
glm::quat AbsoluteOrientation(World* world, EntityID entity);
|
|
||||||
glm::vec3 AbsoluteScale(World* world, EntityID entity);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef RenderState_h__
|
||||||
|
#define RenderState_h__
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "../OpenGL.h"
|
||||||
|
#include "../GLM.h"
|
||||||
|
|
||||||
|
class RenderState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RenderState() = default;
|
||||||
|
~RenderState();
|
||||||
|
|
||||||
|
bool Enable(GLenum cap);
|
||||||
|
bool Disable(GLenum cap);
|
||||||
|
bool CullFace(GLenum mode);
|
||||||
|
bool ClearColor(glm::vec4 color);
|
||||||
|
bool Clear(GLbitfield mask);
|
||||||
|
bool BindFramebuffer(GLint framebuffer);
|
||||||
|
bool BlendEquation(GLenum mode);
|
||||||
|
bool BlendFunc(GLenum sfactor, GLenum dfactor);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::function<void(void)>> m_ResetFunctions;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#ifndef RenderSystem_h__
|
||||||
|
#define RenderSystem_h__
|
||||||
|
|
||||||
|
#include "../Core/System.h"
|
||||||
|
#include "RenderQueue.h"
|
||||||
|
#include "../GLM.h"
|
||||||
|
#include "../OpenGL.h"
|
||||||
|
#include "../Core/ResourceManager.h"
|
||||||
|
#include "ESetCamera.h"
|
||||||
|
#include "Model.h"
|
||||||
|
#include "../Core/EKeyDown.h"
|
||||||
|
#include "../Input/EInputCommand.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "ModelJob.h"
|
||||||
|
#include "Renderer.h"
|
||||||
|
#include "../Core/Transform.h"
|
||||||
|
|
||||||
|
class RenderSystem : public ImpureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RenderSystem(EventBroker* eventBrokerer, const IRenderer* renderer, RenderFrame* renderFrame);
|
||||||
|
|
||||||
|
virtual void Update(World* world, double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
World* m_World = nullptr;
|
||||||
|
const IRenderer* m_Renderer = nullptr;
|
||||||
|
|
||||||
|
RenderFrame* m_RenderFrame;
|
||||||
|
bool m_SwitchCamera = false;
|
||||||
|
Camera* m_Camera = nullptr;
|
||||||
|
Camera* m_DefaultCamera = nullptr;
|
||||||
|
|
||||||
|
std::list<ComponentWrapper> m_CameraComponents;
|
||||||
|
|
||||||
|
EventRelay<RenderSystem, Events::SetCamera> m_ESetCamera;
|
||||||
|
bool OnSetCamera(const Events::SetCamera &event);
|
||||||
|
EntityID m_CurrentCamera = EntityID_Invalid;
|
||||||
|
|
||||||
|
void switchCamera(EntityID entity);
|
||||||
|
|
||||||
|
void updateCamera(World* world, double dt);
|
||||||
|
void updateProjectionMatrix(ComponentWrapper& cameraComponent);
|
||||||
|
glm::mat4 m_ViewMatrix;
|
||||||
|
glm::mat4 m_ProjectionMatrix;
|
||||||
|
|
||||||
|
void fillModels(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
|
||||||
|
void fillText(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
|
||||||
|
|
||||||
|
EventRelay<RenderSystem, Events::InputCommand> m_EInputCommand;
|
||||||
|
bool OnInputCommand(const Events::InputCommand& e);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -10,58 +10,61 @@
|
|||||||
#include "Util/UnorderedMapVec2.h"
|
#include "Util/UnorderedMapVec2.h"
|
||||||
#include "FrameBuffer.h"
|
#include "FrameBuffer.h"
|
||||||
#include "../Core/World.h"
|
#include "../Core/World.h"
|
||||||
|
#include "PickingPass.h"
|
||||||
|
#include "DrawScenePass.h"
|
||||||
#include "../Core/EventBroker.h"
|
#include "../Core/EventBroker.h"
|
||||||
#include "EPicking.h"
|
#include "ImGuiRenderPass.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
|
||||||
#include "TextRenderer.h"
|
#include "TextRenderer.h"
|
||||||
|
|
||||||
class Renderer : public IRenderer
|
class Renderer : public IRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Renderer(EventBroker* eventBroker)
|
Renderer(EventBroker* eventBroker, World* world)
|
||||||
: m_EventBroker(eventBroker)
|
: m_EventBroker(eventBroker)
|
||||||
|
, m_World(world)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void Initialize() override;
|
virtual void Initialize() override;
|
||||||
virtual void Update(double dt) override;
|
virtual void Update(double dt) override;
|
||||||
virtual void Draw(RenderQueueCollection& rq) override;
|
virtual void Draw(RenderFrame& frame) override;
|
||||||
|
|
||||||
|
virtual PickData Pick(glm::vec2 screenCoord) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//----------------------Variables----------------------//
|
//----------------------Variables----------------------//
|
||||||
EventBroker* m_EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
|
World* m_World;
|
||||||
TextRenderer* m_TextRenderer;
|
TextRenderer* m_TextRenderer;
|
||||||
|
|
||||||
Texture* m_ErrorTexture;
|
Texture* m_ErrorTexture;
|
||||||
Texture* m_WhiteTexture;
|
Texture* m_WhiteTexture;
|
||||||
float m_CameraMoveSpeed;
|
|
||||||
FrameBuffer m_PickingBuffer;
|
|
||||||
GLuint m_PickingTexture;
|
|
||||||
GLuint m_DepthBuffer;
|
|
||||||
|
|
||||||
Model* m_ScreenQuad;
|
Model* m_ScreenQuad;
|
||||||
Model* m_UnitQuad;
|
Model* m_UnitQuad;
|
||||||
Model* m_UnitSphere;
|
Model* m_UnitSphere;
|
||||||
|
|
||||||
std::unordered_map<glm::vec2, EntityID> m_PickingColorsToEntity;
|
DrawScenePass* m_DrawScenePass;
|
||||||
|
PickingPass* m_PickingPass;
|
||||||
|
ImGuiRenderPass* m_ImGuiRenderPass;
|
||||||
|
|
||||||
//----------------------Functions----------------------//
|
//----------------------Functions----------------------//
|
||||||
void InitializeWindow();
|
void InitializeWindow();
|
||||||
void InitializeShaders();
|
void InitializeShaders();
|
||||||
void InitializeTextures();
|
void InitializeTextures();
|
||||||
void InitializeFrameBuffers();
|
void InitializeSSBOs();
|
||||||
|
void InitializeRenderPasses();
|
||||||
//TODO: Renderer: Get InputUpdate out of renderer
|
//TODO: Renderer: Get InputUpdate out of renderer
|
||||||
void InputUpdate(double dt);
|
void InputUpdate(double dt);
|
||||||
void PickingPass(RenderQueueCollection& rq);
|
//void PickingPass(RenderQueueCollection& rq);
|
||||||
void DrawScreenQuad(GLuint textureToDraw);
|
void DrawScreenQuad(GLuint textureToDraw);
|
||||||
void DrawScene(RenderQueueCollection& rq);
|
|
||||||
|
|
||||||
|
|
||||||
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type);
|
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type);
|
||||||
//--------------------ShaderPrograms-------------------//
|
//--------------------ShaderPrograms-------------------//
|
||||||
ShaderProgram m_BasicForwardProgram;
|
ShaderProgram* m_BasicForwardProgram;
|
||||||
ShaderProgram m_PickingProgram;
|
ShaderProgram* m_DrawScreenQuadProgram;
|
||||||
ShaderProgram m_DrawScreenQuadProgram;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
#ifndef ShaderProgram_h__
|
#ifndef ShaderProgram_h__
|
||||||
#define ShaderProgram_h__
|
#define ShaderProgram_h__
|
||||||
|
|
||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "../OpenGL.h"
|
#include "../OpenGL.h"
|
||||||
|
#include "../Core/ResourceManager.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
class Shader
|
class Shader
|
||||||
@@ -63,11 +63,13 @@ public:
|
|||||||
: ShaderType(fileName) { }
|
: ShaderType(fileName) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShaderProgram
|
class ShaderProgram : public Resource
|
||||||
{
|
{
|
||||||
public:
|
friend class ResourceManager;
|
||||||
ShaderProgram()
|
private:
|
||||||
|
ShaderProgram(std::string)
|
||||||
: m_ShaderProgramHandle(0) { }
|
: m_ShaderProgramHandle(0) { }
|
||||||
|
public:
|
||||||
~ShaderProgram();
|
~ShaderProgram();
|
||||||
|
|
||||||
void AddShader(std::shared_ptr<Shader> shader);
|
void AddShader(std::shared_ptr<Shader> shader);
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef TextJob_h__
|
||||||
|
#define TextJob_h__
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "../GLM.h"
|
||||||
|
#include "../Core/ComponentWrapper.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
#include "RenderJob.h"
|
||||||
|
#include "../Core/ResourceManager.h"
|
||||||
|
#include "Font.h"
|
||||||
|
|
||||||
|
struct TextJob : RenderJob
|
||||||
|
{
|
||||||
|
TextJob(glm::mat4 matrix, Font* font, ComponentWrapper textComponent)
|
||||||
|
: RenderJob()
|
||||||
|
{
|
||||||
|
Matrix = matrix;
|
||||||
|
Color = (glm::vec4)textComponent["Color"];
|
||||||
|
Content = (std::string)textComponent["Content"];
|
||||||
|
Resource = font;
|
||||||
|
};
|
||||||
|
|
||||||
|
glm::mat4 Matrix;
|
||||||
|
glm::vec4 Color;
|
||||||
|
std::string Content;
|
||||||
|
Font* Resource;
|
||||||
|
|
||||||
|
|
||||||
|
void CalculateHash() override
|
||||||
|
{
|
||||||
|
Hash = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -17,7 +17,7 @@ public:
|
|||||||
TextRenderer();
|
TextRenderer();
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void Update();
|
void Update();
|
||||||
void Draw(RenderQueue &rq, glm::mat4 projection, glm::mat4 view);
|
void Draw(RenderScene& scene);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Font* font;
|
Font* font;
|
||||||
@@ -26,7 +26,7 @@ private:
|
|||||||
|
|
||||||
void RenderText(std::string text, Font* font, GLfloat scale, glm::vec4 color, glm::mat4 modelMatrix, glm::mat4 projectionMatrix, glm::mat4 viewMatrix);
|
void RenderText(std::string text, Font* font, GLfloat scale, glm::vec4 color, glm::mat4 modelMatrix, glm::mat4 projectionMatrix, glm::mat4 viewMatrix);
|
||||||
|
|
||||||
ShaderProgram m_TextProgram;
|
ShaderProgram* m_TextProgram;
|
||||||
|
|
||||||
std::string text = "";
|
std::string text = "";
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ inline bool _GLERROR(const char* info, const char* file, const char* func, unsig
|
|||||||
GLenum error = glGetError();
|
GLenum error = glGetError();
|
||||||
if (error != GL_NO_ERROR)
|
if (error != GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
_LOG(LOG_LEVEL_ERROR, file, func, line, "GL Error: %s %i %s", info, error, gluErrorString(error));
|
_LOG(LOG_LEVEL_ERROR, file, func, line, "GL Error: %s, %i, %s", info, error, gluErrorString(error));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef UnorderedMapiVec2_h__
|
||||||
|
#define UnorderedMapiVec2_h__
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
|
#include <glm/vec2.hpp>
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct std::hash<glm::ivec2>
|
||||||
|
{
|
||||||
|
inline std::size_t operator()(const glm::ivec2 &v) const
|
||||||
|
{
|
||||||
|
return boost::hash<float>()(v.x) ^ boost::hash<float>()(v.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator()(const glm::ivec2& a, const glm::ivec2& b)const
|
||||||
|
{
|
||||||
|
return a.x == b.x && a.y == b.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
+31
-7
@@ -8,13 +8,27 @@
|
|||||||
#include "Core/InputManager.h"
|
#include "Core/InputManager.h"
|
||||||
#include "GUI/Frame.h"
|
#include "GUI/Frame.h"
|
||||||
#include "Core/World.h"
|
#include "Core/World.h"
|
||||||
#include "Rendering/RenderQueueFactory.h"
|
#include "Input/InputProxy.h"
|
||||||
|
#include "Input/KeyboardInputHandler.h"
|
||||||
|
#include "Input/MouseInputHandler.h"
|
||||||
#include "Core/EKeyDown.h"
|
#include "Core/EKeyDown.h"
|
||||||
#include "Core/EntityXMLFile.h"
|
#include "Core/EntityFilePreprocessor.h"
|
||||||
#include "Core/SystemPipeline.h"
|
#include "Core/SystemPipeline.h"
|
||||||
#include "RaptorCopterSystem.h"
|
#include "RaptorCopterSystem.h"
|
||||||
|
#include "PlayerSystem.h"
|
||||||
|
#include "Editor/EditorSystem.h"
|
||||||
|
#include "Core/EntityFile.h"
|
||||||
|
#include "Rendering/RenderSystem.h"
|
||||||
|
#include "Core/EntityFileParser.h"
|
||||||
#include "Rendering/Font.h"
|
#include "Rendering/Font.h"
|
||||||
|
|
||||||
|
// Network
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
#include "Network/Network.h"
|
||||||
|
#include "Network/Server.h"
|
||||||
|
#include "Network/Client.h"
|
||||||
|
|
||||||
|
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -30,16 +44,26 @@ private:
|
|||||||
EventBroker* m_EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
IRenderer* m_Renderer;
|
IRenderer* m_Renderer;
|
||||||
InputManager* m_InputManager;
|
InputManager* m_InputManager;
|
||||||
|
InputProxy* m_InputProxy;
|
||||||
GUI::Frame* m_FrameStack;
|
GUI::Frame* m_FrameStack;
|
||||||
World* m_World;
|
World* m_World;
|
||||||
SystemPipeline* m_SystemPipeline;
|
SystemPipeline* m_SystemPipeline;
|
||||||
RenderQueueFactory* m_RenderQueueFactory;
|
RenderFrame* m_RenderFrame;
|
||||||
|
// Network variables
|
||||||
|
boost::thread m_NetworkThread;
|
||||||
|
|
||||||
EventRelay<Game, Events::KeyUp> m_EKeyUp;
|
// Network methods
|
||||||
bool testOnKeyUp(const Events::KeyUp& e);
|
void networkFunction();
|
||||||
|
Network* m_ClientOrServer;
|
||||||
|
bool m_IsClientOrServer = false;
|
||||||
|
|
||||||
|
EventRelay<Game, Events::InputCommand> m_EInputCommand;
|
||||||
|
bool debugOnInputCommand(const Events::InputCommand& e);
|
||||||
|
|
||||||
|
void debugInitialize();
|
||||||
|
void debugTick(double dt);
|
||||||
|
EventRelay<Client, Events::KeyDown> m_EKeyDown;
|
||||||
|
|
||||||
void testIntialize();
|
|
||||||
void testTick(double dt);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef HealthSystem_h__
|
||||||
|
#define HealthSystem_h__
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/common.hpp>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
#include "Core\EPlayerDamage.h";
|
||||||
|
#include "Core\EPlayerHealthPickup.h";
|
||||||
|
#include "Core\EPlayerDeath.h";
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class HealthSystem : public PureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HealthSystem(EventBroker* eventBroker);
|
||||||
|
|
||||||
|
//updatecomponent
|
||||||
|
virtual void UpdateComponent(World* world, ComponentWrapper& health, double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//methods which will take care of specific events
|
||||||
|
EventRelay<HealthSystem, Events::PlayerDamage> m_EPlayerDamage;
|
||||||
|
bool HealthSystem::OnPlayerDamaged(const Events::PlayerDamage& e);
|
||||||
|
EventRelay<HealthSystem, Events::PlayerHealthPickup> m_EPlayerHealthPickup;
|
||||||
|
bool HealthSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup& e);
|
||||||
|
|
||||||
|
//vector which will keep track of health changes
|
||||||
|
std::vector<std::tuple<EntityID, double>> m_DeltaHealthVector;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef PlayerSystem_h__
|
||||||
|
#define PlayerSystem_h__
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/common.hpp>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
#include "Collision/ETrigger.h"
|
||||||
|
|
||||||
|
class PlayerSystem : public PureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PlayerSystem(EventBroker* eventBroker)
|
||||||
|
: PureSystem(eventBroker, "Player")
|
||||||
|
{
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_ETouch, &PlayerSystem::OnTouch);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EEnter, &PlayerSystem::OnEnter);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_ELeave, &PlayerSystem::OnLeave);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void UpdateComponent(World* world, ComponentWrapper& player, double dt) override;
|
||||||
|
private:
|
||||||
|
float m_Speed = 5;
|
||||||
|
EventRelay<PlayerSystem, Events::TriggerEnter> m_EEnter;
|
||||||
|
bool OnEnter(const Events::TriggerEnter &event);
|
||||||
|
EventRelay<PlayerSystem, Events::TriggerTouch> m_ETouch;
|
||||||
|
bool PlayerSystem::OnTouch(const Events::TriggerTouch &event);
|
||||||
|
EventRelay<PlayerSystem, Events::TriggerLeave> m_ELeave;
|
||||||
|
bool PlayerSystem::OnLeave(const Events::TriggerLeave &event);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
|
|
||||||
class RaptorCopterSystem : public System
|
class RaptorCopterSystem : public PureSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RaptorCopterSystem(const EventBroker* eventBroker)
|
RaptorCopterSystem(EventBroker* eventBroker)
|
||||||
: System(eventBroker, "RaptorCopter")
|
: PureSystem(eventBroker, "RaptorCopter")
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void Update(World* world, ComponentWrapper& raptorCopter, double dt) override
|
virtual void UpdateComponent(World* world, ComponentWrapper& raptorCopter, double dt) override
|
||||||
{
|
{
|
||||||
ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform");
|
ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform");
|
||||||
(glm::vec3&)transform["Orientation"] += (float)(double)raptorCopter["Speed"] * (float)dt * (glm::vec3)raptorCopter["Axis"];
|
(glm::vec3&)transform["Orientation"] += (float)(double)raptorCopter["Speed"] * (float)dt * (glm::vec3)raptorCopter["Axis"];
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
[Debug]
|
[Debug]
|
||||||
LogLevel=1
|
LogLevel=1
|
||||||
LoadMap=
|
LoadMap=
|
||||||
|
EditorEnabled=false
|
||||||
|
|
||||||
|
|
||||||
[Video]
|
[Video]
|
||||||
Fullscreen=false
|
Fullscreen=false
|
||||||
VSYNC=false
|
VSYNC=false
|
||||||
Width=1280
|
Width=1280
|
||||||
Height=720
|
Height=720
|
||||||
|
FOV=45
|
||||||
|
|
||||||
|
[Networking]
|
||||||
|
StartNetwork=false
|
||||||
|
IsServer=false
|
||||||
|
Name=Bob
|
||||||
|
Address=127.0.0.1
|
||||||
|
Port=13
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
[Mouse]
|
||||||
|
Sensitivity=0.5
|
||||||
|
InvertPitch=false
|
||||||
|
|
||||||
|
[Bindings]
|
||||||
|
MouseLeft=PrimaryFire
|
||||||
|
MouseX=Yaw
|
||||||
|
MouseY=Pitch
|
||||||
|
W=+Forward
|
||||||
|
S=-Forward
|
||||||
|
D=+Right
|
||||||
|
A=-Right
|
||||||
|
R=Reload
|
||||||
|
Space=Jump
|
||||||
|
LeftControl=Crouch
|
||||||
|
LeftShift=Sprint
|
||||||
|
F1=ToggleEditor
|
||||||
|
1=EditorToolMove
|
||||||
|
2=EditorToolRotate
|
||||||
|
3=EditorToolScale
|
||||||
|
X=EditorToggleTransformSpace
|
||||||
|
C=ConnectToServer
|
||||||
|
N=SwitchToServer
|
||||||
|
M=SwitchToClient
|
||||||
@@ -5,5 +5,10 @@
|
|||||||
<xs:include schemaLocation="Components/Model.xsd"/>
|
<xs:include schemaLocation="Components/Model.xsd"/>
|
||||||
<xs:include schemaLocation="Components/Test.xsd"/>
|
<xs:include schemaLocation="Components/Test.xsd"/>
|
||||||
<xs:include schemaLocation="Components/RaptorCopter.xsd"/>
|
<xs:include schemaLocation="Components/RaptorCopter.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/Player.xsd"/>
|
||||||
<xs:include schemaLocation="Components/Text.xsd"/>
|
<xs:include schemaLocation="Components/Text.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/Camera.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/AABB.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/Trigger.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/Health.xsd"/>
|
||||||
</xs:schema>
|
</xs:schema>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<c:AABB>
|
||||||
|
<BoxCenter X="0" Y="0" Z="0"/>
|
||||||
|
<BoxSize X="1" Y="1" Z="1"/>
|
||||||
|
</c:AABB>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:element name="AABB">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="BoxCenter" type="t:Vector" minOccurs="0"/>
|
||||||
|
<xs:element name="BoxSize" type="t:Vector" minOccurs="0"/>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<c:Camera>
|
||||||
|
<Name>cam</Name>
|
||||||
|
<FOV>60.0</FOV>
|
||||||
|
<NearClip>0.01</NearClip>
|
||||||
|
<FarClip>5000</FarClip>
|
||||||
|
</c:Camera>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:element name="Camera">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>It's a camera thingy!</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="Name" type="t:string" minOccurs="0"/>
|
||||||
|
<xs:element name="FOV" type="t:double" minOccurs="0"/>
|
||||||
|
<xs:element name="NearClip" type="t:double" minOccurs="0"/>
|
||||||
|
<xs:element name="FarClip" type="t:double" minOccurs="0"/>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<c:Health>
|
||||||
|
<Health>100</Health>
|
||||||
|
<MaxHealth>100</MaxHealth>
|
||||||
|
</c:Health>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:element name="Health">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="Health" type="t:double" minOccurs="0"/>
|
||||||
|
<xs:element name="MaxHealth" type="t:double" minOccurs="0"/>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<c:Player>
|
||||||
|
<Velocity X="0" Y="0" Z="0"/>
|
||||||
|
<Forward>false</Forward>
|
||||||
|
<Left>false</Left>
|
||||||
|
<Back>false</Back>
|
||||||
|
<Right>false</Right>
|
||||||
|
</c:Player>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:element name="Player">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="Velocity" type="t:Vector" minOccurs="0"/>
|
||||||
|
<xs:element name="Forward" type="t:bool" minOccurs="0"/>
|
||||||
|
<xs:element name="Left" type="t:bool" minOccurs="0"/>
|
||||||
|
<xs:element name="Back" type="t:bool" minOccurs="0"/>
|
||||||
|
<xs:element name="Right" type="t:bool" minOccurs="0"/>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<c:Test>
|
|
||||||
<Integer>1</Integer>
|
|
||||||
<Float>1.333</Float>
|
|
||||||
<Vector X="1.33333" Y="2.33333" Z="3.33333"/>
|
|
||||||
<Quaternion X="1.33333" Y="2.33333" Z="3.33333" W="4.44444"/>
|
|
||||||
</c:Test>
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user