Compare commits

..

4 Commits

Author SHA1 Message Date
maqu14 7fc83d1471 Live texturing 2016-03-18 10:14:02 +01:00
maqu14 65e5729118 Added assets 2016-01-27 12:34:24 +01:00
maqu14 26d6f4c7cf Live texturing, fixed so Maya wont crash when the plugin is unloaded and Photoshop not being able to read the file under specific circumstances. 2015-12-16 17:45:20 +01:00
Teejoon e513059522 This is the "working"(little buggy) PhotoShop to Maya connection.
Ask Johan if you want to get this to work, since you need to install zmq, nodeJS, add a line to Maya.env file and som othe stuff for it to work.
2015-12-09 15:11:53 +01:00
494 changed files with 38169 additions and 12486 deletions
+4
View File
@@ -4,3 +4,7 @@ bin/
lib/ lib/
# Because apparently nobody has any self control # Because apparently nobody has any self control
*.orig *.orig
tools/LiveTexturing/mayaPluginRTT/mayaPluginRTT/x64/Debug/
tools/LiveTexturing/mayaPluginRTT/x64/Debug/
*.suo
+10 -13
View File
@@ -1,22 +1,19 @@
#### Bundled libraries #### Bundled libraries
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) |
| **[Assimp](http://assimp.sourceforge.net)** | 3.1.1 | [BSD 3-Clause License](http://assimp.sourceforge.net/main_license.html) | | **[Assimp](http://assimp.sourceforge.net)** | 3.1.1 | [BSD 3-Clause License](http://assimp.sourceforge.net/main_license.html) |
| **[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 | [nativefiledialog Licence](https://github.com/mlabbe/nativefiledialog/blob/master/LICENSE) |
| **[OpenAL](https://www.openal.org/)** | 1.1 | [OpenAL License](resources/Licenses/OpenAL.txt)
#### 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.60.0+ | [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt) | BOOST_ROOT | | **[Boost](http://www.boost.org)** | 1.59.0+ | [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt) | BOOST_ROOT |
+1 -1
Submodule assets updated: a3c92ac876...e4dc9529f2
+9 -9
View File
@@ -1,13 +1,13 @@
# Xerces_FOUND # XERCES_FOUND
# Xerces_INCLUDE_DIRS # XERCES_INCLUDE_DIRS
# Xerces_LIBRARIES # XERCES_LIBRARIES
find_path(Xerces_INCLUDE_DIR xercesc/dom/dom.hpp find_path(XERCES_INCLUDE_DIR xercesc/dom/dom.hpp
/usr/local/include /usr/local/include
/usr/include /usr/include
) )
find_library(Xerces_LIBRARY find_library(XERCES_LIBRARY
NAMES NAMES
xerces-c_3 xerces-c_3
xerces-c_3D xerces-c_3D
@@ -16,8 +16,8 @@ find_library(Xerces_LIBRARY
/usr/lib /usr/lib
) )
set(Xerces_INCLUDE_DIRS ${Xerces_INCLUDE_DIR}) set(XERCES_INCLUDE_DIRS ${XERCES_INCLUDE_DIR})
set(Xerces_LIBRARIES ${Xerces_LIBRARY}) set(XERCES_LIBRARIES ${XERCES_LIBRARY})
find_package_handle_standard_args(Xerces DEFAULT_MSG Xerces_LIBRARY Xerces_INCLUDE_DIR) find_package_handle_standard_args(Xerces DEFAULT_MSG XERCES_LIBRARY XERCES_INCLUDE_DIR)
mark_as_advanced(Xerces_FOUND Xerces_INCLUDE_DIR Xerces_LIBRARY) mark_as_advanced(Xerces_FOUND XERCES_INCLUDE_DIR XERCES_LIBRARY)
+1 -1
Submodule deps updated: bf83f099ba...1b478d3159
-59
View File
@@ -1,59 +0,0 @@
#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 "../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
@@ -1,31 +0,0 @@
#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
-39
View File
@@ -1,39 +0,0 @@
#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
-38
View File
@@ -1,38 +0,0 @@
#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
+1 -2
View File
@@ -4,5 +4,4 @@
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
#include "Core/Util/Logging.h" #include "Core/Util/Logging.h"
#include "Core/Util/IfDebug.h"
-29
View File
@@ -1,29 +0,0 @@
#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
+2 -10
View File
@@ -12,17 +12,9 @@ struct ComponentInfo
unsigned int Stride = 0; unsigned int Stride = 0;
}; };
struct Field_t
{
std::string Name;
std::string Type;
unsigned int Offset;
unsigned int Stride;
};
std::string Name; std::string Name;
std::unordered_map<std::string, Field_t> Fields; std::unordered_map<std::string, std::string> FieldTypes;
std::vector<std::string> FieldsInOrder; std::unordered_map<std::string, unsigned int> FieldOffsets;
Meta_t Meta; Meta_t Meta;
std::shared_ptr<char> Defaults = nullptr; std::shared_ptr<char> Defaults = nullptr;
}; };
+1 -3
View File
@@ -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,8 +54,6 @@ 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);
+5 -6
View File
@@ -2,7 +2,7 @@
#define ComponentWrapper_h__ #define ComponentWrapper_h__
#include "../Common.h" #include "../Common.h"
#include "Entity.h" #include "EntityWrapper.h"
#include "ComponentInfo.h" #include "ComponentInfo.h"
#include "Util/Any.h" #include "Util/Any.h"
@@ -11,7 +11,7 @@ struct ComponentWrapper
ComponentWrapper(const ComponentInfo& componentInfo, char* data) ComponentWrapper(const ComponentInfo& componentInfo, char* data)
: Info(componentInfo) : Info(componentInfo)
, EntityID(*reinterpret_cast<::EntityID*>(data)) , EntityID(*reinterpret_cast<::EntityID*>(data))
, Data(data + sizeof(::EntityID)) , Data(data + sizeof(EntityID))
{ } { }
const ComponentInfo& Info; const ComponentInfo& Info;
@@ -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.Fields.at(name).Offset; unsigned int offset = Info.FieldOffsets.at(name);
return *reinterpret_cast<T*>(&Data[offset]); return *reinterpret_cast<T*>(&Data[offset]);
} }
@@ -78,9 +78,8 @@ 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.Fields[fieldName].Name = typeid(T).name(); m_ComponentInfo.FieldTypes[fieldName] = typeid(T).name();
m_ComponentInfo.Fields[fieldName].Offset = m_ComponentInfo.Meta.Stride; m_ComponentInfo.FieldOffsets[fieldName] = m_ComponentInfo.Meta.Stride;
m_ComponentInfo.Fields[fieldName].Stride = sizeof(T);
m_ComponentInfo.Meta.Stride += sizeof(T); m_ComponentInfo.Meta.Stride += sizeof(T);
} }
+1 -19
View File
@@ -5,7 +5,6 @@
#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,14 +19,12 @@ private:
public: public:
template <typename T> template <typename T>
T Get(std::string key, T defaultValue); T Get(std::string key, T defaultValue);
template <typename T>
std::vector<std::pair<std::string, T>> GetAll(std::string key);
template <typename T> template <typename T>
void Set(std::string key, T value); void Set(std::string key, T value);
void SaveToDisk(); void SaveToDisk();
private: private:
boost::filesystem::path m_Path; boost::filesystem::path m_Path;
boost::property_tree::ptree m_PTreeDefaults; boost::property_tree::ptree m_PTreeDefaults;
boost::property_tree::ptree m_PTreeOverrides; boost::property_tree::ptree m_PTreeOverrides;
@@ -40,21 +37,6 @@ 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)
{ {
-16
View File
@@ -1,16 +0,0 @@
#ifndef EFileDropped_h__
#define EFileDropped_h__
#include "EventBroker.h"
namespace Events
{
struct FileDropped : Event
{
std::string Path;
};
}
#endif
-17
View File
@@ -1,17 +0,0 @@
#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
-17
View File
@@ -1,17 +0,0 @@
#ifndef Events_MouseScroll_h__
#define Events_MouseScroll_h__
#include "EventBroker.h"
namespace Events
{
struct MouseScroll : Event
{
double DeltaX;
double DeltaY;
};
}
#endif
-20
View File
@@ -1,20 +0,0 @@
#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
-20
View File
@@ -1,20 +0,0 @@
#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
-18
View File
@@ -1,18 +0,0 @@
#ifndef EPlayerHealthPickup_h__
#define EPlayerHealthPickup_h__
#include "EventBroker.h"
#include "../Core/Entity.h"
namespace Events
{
struct PlayerHealthPickup : Event
{
double HealthAmount;
EntityID PlayerHealedID;
};
}
#endif
-7
View File
@@ -1,7 +0,0 @@
#ifndef Entity_h__
#define Entity_h__
typedef unsigned int EntityID;
const static unsigned int EntityID_Invalid = -1;
#endif
+4 -285
View File
@@ -1,293 +1,12 @@
#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 "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 class EntityFile : public Resource
{ {
friend class ResourceManager; friend class ResourceManager;
private: private:
EntityFile(boost::filesystem::path path); EntityFile(std::string path);
~EntityFile();
public: 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
-28
View File
@@ -1,28 +0,0 @@
#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
@@ -1,36 +0,0 @@
#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
-39
View File
@@ -1,39 +0,0 @@
#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
+15
View File
@@ -0,0 +1,15 @@
#ifndef Entity_h__
#define Entity_h__
typedef unsigned int EntityID;
struct EntityWrapper
{
EntityWrapper(EntityID entityID)
: ID(entityID)
{ }
EntityID ID;
};
#endif
+67 -71
View File
@@ -13,127 +13,123 @@
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
{ {
friend class EventBroker; friend class EventBroker;
protected: protected:
BaseEventRelay(std::string contextTypeName, std::string eventTypeName) BaseEventRelay(std::string contextTypeName, std::string eventTypeName)
: m_ContextTypeName(contextTypeName) : m_ContextTypeName(contextTypeName)
, m_EventTypeName(eventTypeName) , m_EventTypeName(eventTypeName)
, m_Broker(nullptr) , m_Broker(nullptr)
{ } { }
~BaseEventRelay(); ~BaseEventRelay();
public: 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;
}; };
template <typename ContextType, typename EventType> template <typename ContextType, typename EventType>
class EventRelay : public BaseEventRelay class EventRelay : public BaseEventRelay
{ {
public: public:
typedef std::function<bool(const EventType&)> CallbackType; typedef std::function<bool(const EventType&)> CallbackType;
EventRelay() EventRelay()
: m_Callback(nullptr) : m_Callback(nullptr)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name()) , BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ } { }
EventRelay(CallbackType callback) EventRelay(CallbackType callback)
: m_Callback(callback) : m_Callback(callback)
, BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name()) , BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name())
{ } { }
protected: protected:
bool Receive(const std::shared_ptr<Event> event) override; bool Receive(const std::shared_ptr<Event> event) override;
private: private:
CallbackType m_Callback; CallbackType m_Callback;
}; };
template <typename ContextType, typename EventType> template <typename ContextType, typename EventType>
bool EventRelay<ContextType, EventType>::Receive(const std::shared_ptr<Event> event) bool EventRelay<ContextType, EventType>::Receive(const std::shared_ptr<Event> event)
{ {
if (m_Callback != nullptr) { if (m_Callback != nullptr) {
return m_Callback(*static_cast<const EventType*>(event.get())); return m_Callback(*static_cast<const EventType*>(event.get()));
} else { } else {
return false; return false;
} }
} }
class EventBroker class EventBroker
{ {
template <typename ContextType, typename EventType> friend class EventRelay; template <typename ContextType, typename EventType> friend class EventRelay;
public: public:
EventBroker() EventBroker()
{ {
m_EventQueueRead = std::make_shared<EventQueue_t>(); m_EventQueueRead = std::make_shared<EventQueue_t>();
m_EventQueueWrite = std::make_shared<EventQueue_t>(); m_EventQueueWrite = std::make_shared<EventQueue_t>();
} }
void Subscribe(BaseEventRelay &relay); void Subscribe(BaseEventRelay &relay);
template <typename EventType> template <typename EventType>
void Publish(const EventType &event); void Publish(const EventType &event);
/* /*
Process all events in a given context. Process all events in a given context.
Returns: Number of events processed Returns: Number of events processed
*/ */
template <typename ContextType> template <typename ContextType>
int Process(); int Process();
int Process(std::string contextTypeName); int Process(std::string contextTypeName);
void Swap(); void Swap();
void Clear(); void Clear();
void Unsubscribe(BaseEventRelay &relay); void Unsubscribe(BaseEventRelay &relay);
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()
typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t; typedef std::unordered_multimap<EventTypeName_t, BaseEventRelay*> EventRelays_t;
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<std::tuple<EventID, ContextTypeName_t, EventTypeName_t>> m_RelaysToUnsubscribe; std::vector<BaseEventRelay*> 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(std::tuple<EventID, ContextTypeName_t, EventTypeName_t> identifier); void unsubscribeImmediate(BaseEventRelay& relay);
}; };
template <typename EventType> template <typename EventType>
void EventBroker::Publish(const EventType &event) void EventBroker::Publish(const EventType &event)
{ {
/*auto itpair = m_Subscribers.equal_range(typeid(EventType).name()); /*auto itpair = m_Subscribers.equal_range(typeid(EventType).name());
for (auto it = itpair.first; it != itpair.second; ++it) for (auto it = itpair.first; it != itpair.second; ++it)
{ {
it->second->Receive(event); it->second->Receive(event);
}*/ }*/
m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr<EventType>(new EventType(event)))); m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr<EventType>(new EventType(event))));
} }
template <typename ContextType> template <typename ContextType>
int EventBroker::Process() int EventBroker::Process()
{ {
const std::string contextTypeName = typeid(ContextType).name(); const std::string contextTypeName = typeid(ContextType).name();
return Process(contextTypeName); return Process(contextTypeName);
} }
#endif #endif
+7 -4
View File
@@ -11,22 +11,25 @@ template <typename EventContext>
class InputController class InputController
{ {
public: public:
InputController(EventBroker* eventBroker) InputController(std::shared_ptr<dd::EventBroker> eventBroker)
: m_EventBroker(eventBroker) : 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& e) { return false; } virtual bool OnCommand(const Events::InputCommand &event) { return false; }
virtual bool OnMouseMove(const Events::MouseMove &event) { return false; }
protected: protected:
EventBroker* m_EventBroker; std::shared_ptr<dd::EventBroker> EventBroker;
private: private:
EventRelay<EventContext, Events::InputCommand> m_EInputCommand; EventRelay<EventContext, Events::InputCommand> m_EInputCommand;
EventRelay<EventContext, Events::MouseMove> m_EMouseMove;
}; };
#endif #endif
-10
View File
@@ -8,15 +8,12 @@
#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
{ {
@@ -67,13 +64,6 @@ 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
+5 -15
View File
@@ -5,14 +5,6 @@
template <typename T> template <typename T>
class MemoryPoolForwardIterator; class MemoryPoolForwardIterator;
namespace DisableMemoryPool
{
//if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation.
//if false -> Use pool allocation.
//Should default to false, unless the DisableMemoryPool is true in the Config.ini files.
extern bool Value;
}
//This is the class to use if you want to allocate blocks (slots) of raw memory, with a fixed maximum size (stride). //This is the class to use if you want to allocate blocks (slots) of raw memory, with a fixed maximum size (stride).
//Additionally, if you know that every memory-block will contain one object of a specific type, (i.e. the stride for the slot //Additionally, if you know that every memory-block will contain one object of a specific type, (i.e. the stride for the slot
//will the size of the object type) you should use ObjectPool<T> instead, your life will become easier. //will the size of the object type) you should use ObjectPool<T> instead, your life will become easier.
@@ -88,8 +80,8 @@ public:
//If element cannot be allocated in the pool, because the memory ran out, memory is allocated dynamically with malloc() "outside the pool". //If element cannot be allocated in the pool, because the memory ran out, memory is allocated dynamically with malloc() "outside the pool".
char* Allocate() char* Allocate()
{ {
for (; m_CurrentAllocSlot < m_NumSlots && m_SlotIsAllocated[m_CurrentAllocSlot] && !DisableMemoryPool::Value; ++m_CurrentAllocSlot); for (; m_CurrentAllocSlot < m_NumSlots && m_SlotIsAllocated[m_CurrentAllocSlot]; ++m_CurrentAllocSlot);
if (m_CurrentAllocSlot < m_NumSlots && !DisableMemoryPool::Value) { if (m_CurrentAllocSlot < m_NumSlots) {
if (m_LowestAllocatedSlot > m_CurrentAllocSlot) if (m_LowestAllocatedSlot > m_CurrentAllocSlot)
m_LowestAllocatedSlot = m_CurrentAllocSlot; m_LowestAllocatedSlot = m_CurrentAllocSlot;
//Mark the slot as allocated. //Mark the slot as allocated.
@@ -101,9 +93,7 @@ public:
else { else {
m_ExtraMemory.push_back((char*)malloc(m_Stride)); m_ExtraMemory.push_back((char*)malloc(m_Stride));
//We should preferably not enter here to avoid performance issues. Set more numMaxElements in constructor instead. //We should preferably not enter here to avoid performance issues. Set more numMaxElements in constructor instead.
if (!DisableMemoryPool::Value) { LOG_WARNING("Allocated slots exceed Pool size, extra memory allocated dynamically. Pool size: %u, dynamic size: %u.", m_NumSlots, m_ExtraMemory.size());
LOG_WARNING("Allocated slots exceed Pool size, extra memory allocated dynamically. Pool size: %u, dynamic size: %u.", m_NumSlots, m_ExtraMemory.size());
}
return m_ExtraMemory.back(); return m_ExtraMemory.back();
} }
} }
@@ -118,7 +108,7 @@ public:
//(i.e. IsAllocatedInPool may give false positives) //(i.e. IsAllocatedInPool may give false positives)
//if it was malloc():ed //if it was malloc():ed
//so, we may enter here even if we shouldn't. //so, we may enter here even if we shouldn't.
if (!DisableMemoryPool::Value && IsAllocatedInPool(obj)) { if (IsAllocatedInPool(obj)) {
--m_NumAllocatedSlots; --m_NumAllocatedSlots;
const size_t freeSlot = (obj - m_StartAddress) / m_Stride; const size_t freeSlot = (obj - m_StartAddress) / m_Stride;
m_SlotIsAllocated[freeSlot] = false; m_SlotIsAllocated[freeSlot] = false;
@@ -263,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++();
-104
View File
@@ -1,104 +0,0 @@
#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
-31
View File
@@ -1,31 +0,0 @@
#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__
+39 -134
View File
@@ -12,6 +12,7 @@
/** Base Resource class. /** Base Resource class.
Implement this class for every resource to be handled by the resource manager. Implement this class for every resource to be handled by the resource manager.
Implement Create() to return a new object of that type.
*/ */
class Resource class Resource
{ {
@@ -21,23 +22,6 @@ protected:
Resource() { } Resource() { }
public: public:
//Should be thrown in a Resource's constructor if it cannot complete because another resource is still loading.
//Not actually an error, just a message to the ResourceManager.
struct StillLoadingException : public std::exception
{
virtual const char* what() const throw()
{
return "Resource is still loading.";
}
};
struct FailedLoadingException : public std::exception
{
virtual const char* what() const throw()
{
return "Resource is failed to load.";
}
};
// Pretend that this is a pure virtual function that you have to implement // Pretend that this is a pure virtual function that you have to implement
// FIXME: Why did we do this again instead of just using the constructor? // FIXME: Why did we do this again instead of just using the constructor?
// static Resource* Create(std::string resourceName); // static Resource* Create(std::string resourceName);
@@ -49,15 +33,6 @@ public:
unsigned int ResourceID; unsigned int ResourceID;
}; };
//Any class inheriting from this class will always be loaded on the master thread, not on a parallel worker thread.
//This is important in case some instructions must be executed on the main thread, e.g. OpenGL commands, like glBindBuffer.
//This resource can still be loaded asyncronously, but it will not be loaded in a thread, instead it's constructor will
//be called once on every ResourceManager::Load, just throw StillLoadingException in the constructor if it is not done yet.
class ThreadUnsafeResource : public Resource
{
friend class ResourceManager;
};
/** Singleton resource manager to keep track of and cache any external engine assets */ /** Singleton resource manager to keep track of and cache any external engine assets */
class ResourceManager class ResourceManager
{ {
@@ -65,7 +40,6 @@ private:
ResourceManager(); ResourceManager();
public: public:
static bool UseThreading;
/*static ResourceManager& Instance() /*static ResourceManager& Instance()
{ {
static ResourceManager s; static ResourceManager s;
@@ -75,6 +49,15 @@ public:
template <typename T> template <typename T>
static void RegisterType(std::string typeName); static void RegisterType(std::string typeName);
/** Preloads a resource and caches it for future use
@tparam T Resource type.
@param resourceName Fully qualified name of the resource to preload.
*/
template <typename T>
static void Preload(std::string resourceName);
static void Preload(std::string resourceType, std::string resourceName);
/** Checks if a resource is in cache /** Checks if a resource is in cache
@param resourceType Resource type as string. @param resourceType Resource type as string.
@@ -82,20 +65,15 @@ public:
*/ */
// TODO: Templateify // TODO: Templateify
static bool IsResourceLoaded(std::string resourceType, std::string resourceName); static bool IsResourceLoaded(std::string resourceType, std::string resourceName);
/** Return value should always be a valid pointer, will throw an exception on error.
If the resource has been loaded already, returns a pointer to it.
If Async is false: Hot-loads a resource, caches it for future use, and returns a pointer to it. /** Hot-loads a resource and caches it for future use
If Async is true: If the resource is not loaded yet, starts loading the resource
in the background and throws Resource::StillLoadingException immediately.
@tparam T Resource type. @tparam T Resource type.
@tparam async Set this to true if the resource should be loaded asyncronously.
@param resourceName Fully qualified name of the resource to load. @param resourceName Fully qualified name of the resource to load.
*/ */
template <typename T, bool async = false> template <typename T>
static T* Load(const std::string& resourceName, Resource* parent = nullptr); static T* Load(std::string resourceName, Resource* parent = nullptr);
static Resource* Load(std::string resourceType, std::string resourceName, Resource* parent = nullptr);
/** Reloads an already loaded resource, keeping its resource ID intact. /** Reloads an already loaded resource, keeping its resource ID intact.
@@ -103,37 +81,23 @@ public:
@param resourceName Fully qualified name of the resource to reload. @param resourceName Fully qualified name of the resource to reload.
*/ */
static void Reload(std::string resourceName); static void Reload(std::string resourceName);
static void Release(std::string resourceType, std::string resourceName);
static void Update(); static void Update();
private: private:
//This is a haxy way to make sure that IsMainThread is run when the program starts, so the master thread id is set.
struct MasterThreadChecker
{
MasterThreadChecker()
{
ResourceManager::IsMainThread();
}
};
const static MasterThreadChecker m_Checker;
static std::unordered_map<std::string, std::string> m_CompilerTypenameToResourceType; static std::unordered_map<std::string, std::string> m_CompilerTypenameToResourceType;
static std::unordered_map<std::string, std::function<Resource*(std::string)>> m_FactoryFunctions; // type -> factory function static std::unordered_map<std::string, std::function<Resource*(std::string)>> m_FactoryFunctions; // type -> factory function
static std::unordered_map<std::pair<std::string, std::string>, Resource*> m_ResourceCache; // (type, name) -> resource static std::unordered_map<std::pair<std::string, std::string>, Resource*> m_ResourceCache; // (type, name) -> resource
static std::unordered_map<std::string, Resource*> m_ResourceFromName; // name -> resource static std::unordered_map<std::string, Resource*> m_ResourceFromName; // name -> resource
static std::unordered_map<Resource*, Resource*> m_ResourceParents; // resource -> parent resource static std::unordered_map<Resource*, Resource*> m_ResourceParents; // resource -> parent resource
static std::unordered_map<std::pair<std::string, std::string>, boost::thread> m_LoadingThreads; // (type, name) -> loading thread
static std::unordered_map<std::pair<std::string, std::string>, std::exception_ptr> m_LoadingThreadExceptions; // (type, name) -> exceptions
static boost::recursive_mutex m_Mutex;
// TODO: Getters for IDs // TODO: Getters for IDs
static unsigned int m_CurrentResourceTypeID; static unsigned int m_CurrentResourceTypeID;
static std::unordered_map<std::string, unsigned int> m_ResourceTypeIDs; static std::unordered_map<std::string, unsigned int> m_ResourceTypeIDs;
// Number of resources of a type. Doubles as local ID. // Number of resources of a type. Doubles as local ID.
static std::unordered_map<unsigned int, unsigned int> m_ResourceCount; static std::unordered_map<unsigned int, unsigned int> m_ResourceCount;
// Flag to suppress hot-load warnings when a preloading resource chain loads another resource
static bool m_Preloading;
static FileWatcher m_FileWatcher; static FileWatcher m_FileWatcher;
static void fileWatcherCallback(std::string path, FileWatcher::FileEventFlags flags); static void fileWatcherCallback(std::string path, FileWatcher::FileEventFlags flags);
@@ -142,13 +106,22 @@ private:
static unsigned int GetNewResourceID(unsigned int typeID); static unsigned int GetNewResourceID(unsigned int typeID);
// Internal: Create a resource and cache it // Internal: Create a resource and cache it
static Resource* createResourceThrowing(const std::string& resourceType, const std::string& resourceName, Resource* parent); static Resource* CreateResource(std::string resourceType, std::string resourceName, Resource* parent);
static Resource* createResource(const std::string& resourceType, const std::string& resourceName, Resource* parent, std::exception_ptr& exception);
static Resource* cacheResource(Resource* resource, const std::string& resourceType, const std::string& resourceName, Resource* parent);
static bool IsMainThread();
}; };
template <typename T>
T* ResourceManager::Load(std::string resourceName, Resource* parent /* = nullptr */)
{
auto resourceTypename = typeid(T).name();
auto it = m_CompilerTypenameToResourceType.find(resourceTypename);
if (it == m_CompilerTypenameToResourceType.end()) {
LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": type not registered", resourceName.c_str(), resourceTypename);
return nullptr;
}
return static_cast<T*>(Load(it->second, resourceName, parent));
}
template <typename T> template <typename T>
void ResourceManager::RegisterType(std::string typeName) void ResourceManager::RegisterType(std::string typeName)
{ {
@@ -156,85 +129,17 @@ void ResourceManager::RegisterType(std::string typeName)
m_FactoryFunctions[typeName] = [](std::string resourceName) { return new T(resourceName); }; m_FactoryFunctions[typeName] = [](std::string resourceName) { return new T(resourceName); };
} }
template <typename T, bool async> template <typename T>
static T* ResourceManager::Load(const std::string& resourceName, Resource* parent /* = nullptr */) void ResourceManager::Preload(std::string resourceName)
{ {
auto resourceTypename = typeid(T).name(); auto resourceTypename = typeid(T).name();
auto iter = m_CompilerTypenameToResourceType.find(resourceTypename); auto it = m_CompilerTypenameToResourceType.find(resourceTypename);
if (iter == m_CompilerTypenameToResourceType.end()) { if (it == m_CompilerTypenameToResourceType.end()) {
LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": type not registered", resourceName.c_str(), resourceTypename); LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": type not registered", resourceName.c_str(), resourceTypename);
throw Resource::FailedLoadingException(); return;
} }
std::string resourceType = iter->second; Preload(it->second, resourceName);
constexpr bool mustNotLoadInThread = std::is_base_of<ThreadUnsafeResource, T>::value;
if (mustNotLoadInThread && !IsMainThread()) {
LOG_ERROR("Failed to Load \"%s\": ThreadUnsafeResource type \"%s\" load in the constructor of another resource that is loaded asyncronously.", resourceName.c_str(), iter->second.c_str());
throw Resource::FailedLoadingException();
}
auto cacheKey = std::make_pair(resourceType, resourceName);
decltype(m_ResourceCache)::iterator it;
//If a thread has already been launched to load this resource.
auto tIt = m_LoadingThreads.find(cacheKey);
if (UseThreading && tIt != m_LoadingThreads.end()) {
if (async) {
//Throw StillLoadingException if the thread is still working.
if (!tIt->second.try_join_for(boost::chrono::nanoseconds(1))) {
throw Resource::StillLoadingException();
}
//Else we know the thread has completed.
} else {
//Wait for the thread to finish loading.
tIt->second.join();
}
//When the thread is done, delete the thread.
m_LoadingThreads.erase(tIt);
//Rethrow the thread exception if it threw any.
auto excIt = m_LoadingThreadExceptions.find(cacheKey);
std::exception_ptr exception = excIt->second;
m_LoadingThreadExceptions.erase(excIt);
if (exception) {
std::rethrow_exception(exception);
}
}
//If resource has already been cached and completely loaded.
it = m_ResourceCache.find(cacheKey);
if (it != m_ResourceCache.end()) {
if (it->second != nullptr) {
return static_cast<T*>(it->second);
} else {
//Don't return null on failure, exception instead.
throw Resource::FailedLoadingException();
}
}
//If resource is not cached..
if (UseThreading && async) {
if (mustNotLoadInThread) {
try {
return static_cast<T*>(createResourceThrowing(resourceType, resourceName, parent));
} catch (const Resource::StillLoadingException&) {
throw;
}
} else {
//Create a thread that loads the resource into cache.
m_LoadingThreads[cacheKey] = boost::thread(createResource, resourceType, resourceName, parent, m_LoadingThreadExceptions[cacheKey]);
throw Resource::StillLoadingException();
}
} else {
//load and return the resource.
while (true) {
try {
return static_cast<T*>(createResourceThrowing(resourceType, resourceName, parent));
} catch (const Resource::StillLoadingException&) {
continue;
} catch (const std::exception&) {
throw;
}
}
}
} }
#endif #endif
-50
View File
@@ -1,50 +0,0 @@
#ifndef System_h__
#define System_h__
#include "EventBroker.h"
#include "World.h"
#include "ComponentWrapper.h"
class System
{
friend class SystemPipeline;
protected:
System(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)
{ }
virtual ~PureSystem() = default;
const std::string m_ComponentType;
virtual void UpdateComponent(World* world, ComponentWrapper& component, double dt) = 0;
};
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
-89
View File
@@ -1,89 +0,0 @@
#ifndef SystemPipeline_h__
#define SystemPipeline_h__
#include "../Common.h"
#include "EventBroker.h"
#include "System.h"
#include "World.h"
class SystemPipeline
{
public:
SystemPipeline(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{ }
~SystemPipeline()
{
for (UnorderedSystems& group : m_OrderedSystemGroups) {
for (auto& pair : group.Systems) {
delete pair.second;
}
}
}
template <typename T, typename... Arguments>
//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...);
group.Systems[typeid(T).name()] = 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 {
LOG_ERROR("Failed to add pure system \"%s\": Missing component type!", typeid(T).name());
}
}
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)
{
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;
auto& systems = pair.second;
const ComponentPool* pool = world->GetComponents(componentName);
if (pool == nullptr) {
continue;
}
for (auto& component : *pool) {
for (auto& system : systems) {
system->UpdateComponent(world, component, dt);
}
}
}
for (auto& system : group.ImpureSystems) {
system->Update(world, dt);
}
}
}
private:
EventBroker* m_EventBroker;
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
-17
View File
@@ -1,17 +0,0 @@
#ifndef Transform_h__
#define Transform_h__
#include "../GLM.h"
#include "World.h"
namespace Transform
{
glm::vec3 AbsolutePosition(World* world, EntityID entity);
glm::quat AbsoluteOrientation(World* world, EntityID entity);
glm::vec3 AbsoluteScale(World* world, EntityID entity);
glm::mat4 ModelMatrix(EntityID entity, World* world);
}
#endif
-12
View File
@@ -1,12 +0,0 @@
// 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
-46
View File
@@ -1,46 +0,0 @@
#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
+3 -25
View File
@@ -2,7 +2,7 @@
#define World_h__ #define World_h__
#include "../Common.h" #include "../Common.h"
#include "Entity.h" #include "EntityWrapper.h"
#include "ObjectPool.h" #include "ObjectPool.h"
#include "ComponentPool.h" #include "ComponentPool.h"
@@ -12,45 +12,23 @@ public:
World() = default; World() = default;
~World(); ~World();
// 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
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 = 0; 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();
}; };
-94
View File
@@ -1,94 +0,0 @@
#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);
};
+1 -1
View File
@@ -40,7 +40,7 @@ public:
m_TexturePressed = resourceName; m_TexturePressed = resourceName;
} }
void Draw(RenderScene& rq) override void Draw(RenderQueueCollection& rq) override
{ {
if (m_Texture == nullptr && !m_TextureReleased.empty()) { if (m_Texture == nullptr && !m_TextureReleased.empty()) {
SetTexture(m_TextureReleased); SetTexture(m_TextureReleased);
+2 -2
View File
@@ -212,7 +212,7 @@ public:
virtual void Update(double dt) { } virtual void Update(double dt) { }
void DrawLayered(RenderScene& rq) void DrawLayered(RenderQueueCollection& rq)
{ {
if (this->Hidden()) if (this->Hidden())
return; return;
@@ -232,7 +232,7 @@ public:
} }
} }
virtual void Draw(RenderScene& rq) { } virtual void Draw(RenderQueueCollection& rq) { }
protected: protected:
::EventBroker* m_EventBroker; ::EventBroker* m_EventBroker;
+1 -1
View File
@@ -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(RenderScene& rq) override void Draw(RenderQueueCollection& rq) override
{ {
if (m_Texture == nullptr) if (m_Texture == nullptr)
return; return;
+24
View File
@@ -0,0 +1,24 @@
#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;
};
}
+26
View File
@@ -0,0 +1,26 @@
#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
+25
View File
@@ -0,0 +1,25 @@
#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
+25
View File
@@ -0,0 +1,25 @@
#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
-22
View File
@@ -1,22 +0,0 @@
#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
+1 -1
View File
@@ -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 = 0; float Value;
}; };
} }
@@ -1,70 +0,0 @@
#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
-25
View File
@@ -1,25 +0,0 @@
#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
-46
View File
@@ -1,46 +0,0 @@
#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
+78
View File
@@ -0,0 +1,78 @@
#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
@@ -1,28 +0,0 @@
#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
-38
View File
@@ -1,38 +0,0 @@
#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
+4 -73
View File
@@ -1,83 +1,14 @@
#ifndef Client_h__ #ifndef Client_h__
#define Client_h__ #define Client_h__
#include <string> #include <boost\asio.hpp>
#include <ctime>
#include <glm/common.hpp> class Client
#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
{ {
public: Client();
Client(ConfigFile* config); ~Client();
~Client();
void Start(World* world, EventBroker* eventBroker) override;
void Update() override;
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[INPUTSIZE] = { 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;
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 updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType);
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
-17
View File
@@ -1,17 +0,0 @@
#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
-19
View File
@@ -1,19 +0,0 @@
#ifndef Network_h__
#define Network_h__
#include "Core/World.h"
#include "Core/EventBroker.h"
#include "Network/Packet.h"
#define MAXCONNECTIONS 8
#define INPUTSIZE 4097
class Network
{
public:
virtual ~Network() { };
virtual void Start(World* m_world, EventBroker *eventBroker) = 0;
virtual void Update() = 0;
};
#endif
-66
View File
@@ -1,66 +0,0 @@
#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();
void Init(MessageType type, unsigned int& packetID);
// 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! New size is %i bytes\n", m_MaxPacketSize*2);
resizeData();
}
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(const 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; };
unsigned int DataReadSize() { return m_ReturnDataOffset; }
unsigned int MaxSize() { return m_MaxPacketSize; }
private:
char* m_Data;
unsigned int m_ReturnDataOffset = 0;
int m_Offset = 0;
unsigned int m_MaxPacketSize = 512;
void resizeData();
};
#endif
-11
View File
@@ -1,11 +0,0 @@
#ifndef PlayerDefinition_h__
#define PlayerDefinition_h__
#include <string>
struct PlayerDefinition {
int EntityID = -1;
std::string Name = "";
boost::asio::ip::udp::endpoint Endpoint;
};
#endif
+4 -72
View File
@@ -1,80 +1,12 @@
#ifndef Server_h__ #ifndef Server_h__
#define Server_h__ #define Server_h__
#include <string> #include <boost\asio.hpp>
#include <ctime>
#include <glm/common.hpp> class Server
#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;
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[INPUTSIZE] = { 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;
// 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
@@ -1,12 +0,0 @@
#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
+1 -1
View File
@@ -3,7 +3,7 @@
#include "../Core/ResourceManager.h" #include "../Core/ResourceManager.h"
class BaseTexture : public ThreadUnsafeResource class BaseTexture : public Resource
{ {
friend class ResourceManager; friend class ResourceManager;
+8 -6
View File
@@ -26,12 +26,13 @@ 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);
@@ -45,10 +46,11 @@ public:
float FarClip() const { return m_FarClip; } float FarClip() const { return m_FarClip; }
void SetFarClip(float val); void SetFarClip(float val);
void UpdateViewMatrix();
void UpdateProjectionMatrix();
private: private:
void UpdateViewMatrix();
void UpdateProjectionMatrix();
glm::vec3 m_Position; glm::vec3 m_Position;
glm::quat m_Orientation; glm::quat m_Orientation;
@@ -1,66 +0,0 @@
#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;
};
-38
View File
@@ -1,38 +0,0 @@
#ifndef DrawFinalPass_h__
#define DrawFinalPass_h__
#include "IRenderer.h"
#include "DrawFinalPassState.h"
#include "LightCullingPass.h"
#include "FrameBuffer.h"
#include "ShaderProgram.h"
#include "Util/UnorderedMapVec2.h"
#include "Texture.h"
class DrawFinalPass
{
public:
DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass);
~DrawFinalPass() { }
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;
Texture* m_WhiteTexture;
const IRenderer* m_Renderer;
const LightCullingPass* m_LightCullingPass;
ShaderProgram* m_ForwardPlusProgram;
};
#endif
@@ -1,15 +0,0 @@
#ifndef DrawFinalPassState_h__
#define DrawFinalPassState_h__
#include "Rendering/RenderState.h"
class DrawFinalPassState : public RenderState
{
public:
DrawFinalPassState();
~DrawFinalPassState();
private:
};
#endif
-42
View File
@@ -1,42 +0,0 @@
#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
@@ -1,15 +0,0 @@
#ifndef DrawScenePassState_h__
#define DrawScenePassState_h__
#include "Rendering/RenderState.h"
class DrawScenePassState : public RenderState
{
public:
DrawScenePassState();
~DrawScenePassState();
private:
};
#endif
+1 -1
View File
@@ -9,7 +9,7 @@ class DummyRenderer : public IRenderer
{ {
public: public:
virtual void Initialize() override; virtual void Initialize() override;
virtual void Draw(RenderFrame& rq) override; virtual void Draw(RenderQueueCollection& rq) override;
}; };
#endif #endif
-23
View File
@@ -1,23 +0,0 @@
#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
+14 -27
View File
@@ -9,17 +9,6 @@
#include "Camera.h" #include "Camera.h"
#include "RenderQueue.h" #include "RenderQueue.h"
#include "Model.h" #include "Model.h"
#include "../Core/World.h" //So temp
struct PickData
{
EntityID Entity;
glm::vec3 Position; //World position
float Depth;
::Camera* Camera;
const ::World* World;
};
class IRenderer class IRenderer
{ {
@@ -31,31 +20,29 @@ public:
void SetFullscreen(bool fullscreen) { m_Fullscreen = fullscreen; } void SetFullscreen(bool fullscreen) { m_Fullscreen = fullscreen; }
bool VSYNC() const { return m_VSYNC; } bool VSYNC() const { return m_VSYNC; }
void SetVSYNC(bool vsync) { m_VSYNC = vsync; } void SetVSYNC(bool vsync) { m_VSYNC = vsync; }
::Camera* Camera() const { return m_Camera; } ::Camera* Camera() const { return m_Camera; }
void SetCamera(::Camera* camera) void SetCamera(::Camera* camera)
{ {
if (camera == nullptr) { if (camera == nullptr) {
m_Camera = m_DefaultCamera; m_Camera = m_DefaultCamera;
} else { } else {
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(RenderFrame& rq) = 0; virtual void Draw(RenderQueueCollection& rq) = 0;
virtual PickData Pick(glm::vec2 screenCord) = 0;
World* m_World; //Temp world, untill viktor merge.
protected: protected:
Rectangle m_Resolution = Rectangle::Rectangle(1280, 720); Rectangle m_Resolution = 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;
::Camera* m_DefaultCamera;
::Camera* m_Camera = nullptr;
GLFWwindow* m_Window = nullptr; GLFWwindow* m_Window = nullptr;
::Camera* m_DefaultCamera;
::Camera* m_Camera = nullptr;
}; };
#endif // Renderer_h__ #endif // Renderer_h__
@@ -1,77 +0,0 @@
#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();
};
@@ -1,83 +0,0 @@
#ifndef LightCullingPass_h__
#define LightCullingPass_h__
#define TILE_SIZE 16
#define MAX_LIGHTS_PER_TILE 200
#include "IRenderer.h"
#include "LightCullingPassState.h"
#include "ShaderProgram.h"
#include "RenderQueue.h"
class LightCullingPass
{
public:
LightCullingPass(IRenderer* renderer);
~LightCullingPass();
void GenerateNewFrustum(RenderScene& scene);
void OnResolutionChange();
void SetSSBOSizes();
void CullLights(RenderScene& scene);
void FillLightList(RenderScene& scene);
GLuint FrustumSSBO() const { return m_FrustumSSBO; }
GLuint LightSSBO() const { return m_LightSSBO; }
GLuint LightGridSSBO() const { return m_LightGridSSBO; }
GLuint LightOffsetSSBO() const { return m_LightOffsetSSBO; }
GLuint LightIndexSSBO() const { return m_LightIndexSSBO; }
private:
void InitializeSSBOs();
void InitializeShaderPrograms();
const IRenderer* m_Renderer;
GLuint m_FrustumSSBO = 0;
GLuint m_LightSSBO = 0;
GLuint m_LightGridSSBO = 0;
GLuint m_LightOffsetSSBO = 0;
GLuint m_LightIndexSSBO = 0;
ShaderProgram* m_CalculateFrustumProgram;
ShaderProgram* m_LightCullProgram;
int m_NumberOfTiles = 0;
struct Plane {
glm::vec3 Normal;
float d;
};
struct Frustum {
Plane Planes[4];
};
Frustum* m_Frustums;
//This should be a component
struct PointLight {
glm::vec4 Position = glm::vec4(0.f);
glm::vec4 Color = glm::vec4(1.f);
float Radius = 5.f;
float Intensity = 0.8f;
float Falloff = 0.3f;
float Padding = 1337;
};
std::vector<PointLight> m_PointLights;
struct LightGrid {
float Start;
float Amount;
glm::vec2 Padding;
};
LightGrid* m_LightGrid;
int m_LightOffset = 0;
float* m_LightIndex;
};
#endif
+1 -5
View File
@@ -4,7 +4,7 @@
#include "RawModel.h" #include "RawModel.h"
#include "../OpenGL.h" #include "../OpenGL.h"
class Model : public ThreadUnsafeResource class Model : public RawModel
{ {
friend class ResourceManager; friend class ResourceManager;
@@ -13,15 +13,11 @@ private:
public: public:
~Model(); ~Model();
const std::vector<RawModel::MaterialGroup>& MaterialGroups() const { return m_RawModel->MaterialGroups; }
const glm::mat4& Matrix() const { return m_RawModel->m_Matrix; }
const std::vector<RawModel::Vertex>& Vertices() const { return m_RawModel->m_Vertices; }
GLuint VAO; GLuint VAO;
GLuint ElementBuffer; GLuint ElementBuffer;
private: private:
RawModel* m_RawModel;
GLuint VertexBuffer; GLuint VertexBuffer;
GLuint DiffuseVertexColorBuffer; GLuint DiffuseVertexColorBuffer;
GLuint SpecularVertexColorBuffer; GLuint SpecularVertexColorBuffer;
-55
View File
@@ -1,55 +0,0 @@
#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, ::RawModel::MaterialGroup matGroup, ComponentWrapper modelComponent, World* world)
: RenderJob()
{
Model = model;
TextureID = (matGroup.Texture) ? matGroup.Texture->ResourceID : 0;
DiffuseTexture = matGroup.Texture.get();
NormalTexture = matGroup.NormalMap.get();
SpecularTexture = matGroup.SpecularMap.get();
StartIndex = matGroup.StartIndex;
EndIndex = matGroup.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;
World* World;
void CalculateHash() override
{
Hash = TextureID;
}
};
#endif
-66
View File
@@ -1,66 +0,0 @@
#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
@@ -1,15 +0,0 @@
#ifndef PickingPassState_h__
#define PickingPassState_h__
#include "Rendering/RenderState.h"
class PickingPassState : public RenderState
{
public:
PickingPassState(GLuint frameBuffer);
~PickingPassState();
private:
};
#endif
-39
View File
@@ -1,39 +0,0 @@
#ifndef PointLightJob_h__
#define PointLightJob_h__
#include <cstdint>
#include "../Common.h"
#include "../GLM.h"
#include "../Core/ComponentWrapper.h"
#include "RenderJob.h"
#include "../Core/Transform.h"
#include "../Core/World.h"
struct PointLightJob : RenderJob
{
PointLightJob(ComponentWrapper transformComponent, ComponentWrapper pointLightComponent, World* m_World)
: RenderJob()
{
Position = glm::vec4((glm::vec3)transformComponent["Position"], 1.0f);
Position = glm::vec4(Transform::AbsolutePosition(m_World, transformComponent.EntityID), 1.f);
Color = (glm::vec4)pointLightComponent["Color"];
Radius = (double)pointLightComponent["Radius"];
Intensity = (double)pointLightComponent["Intensity"];
Falloff = (double)pointLightComponent["Falloff"];
};
glm::vec4 Position;
glm::vec4 Color;
float Radius;
float Intensity;
float Falloff;
float padding = 123;
void CalculateHash() override
{
Hash = 0;
}
};
#endif
+1 -5
View File
@@ -46,18 +46,14 @@ public:
struct MaterialGroup struct MaterialGroup
{ {
float Shininess; float Shininess;
float Transparency;
std::string TexturePath;
std::shared_ptr<::Texture> Texture; std::shared_ptr<::Texture> Texture;
std::string NormalMapPath;
std::shared_ptr<::Texture> NormalMap; std::shared_ptr<::Texture> NormalMap;
std::string SpecularMapPath;
std::shared_ptr<::Texture> SpecularMap; std::shared_ptr<::Texture> SpecularMap;
unsigned int StartIndex; unsigned int StartIndex;
unsigned int EndIndex; unsigned int EndIndex;
}; };
std::vector<MaterialGroup> MaterialGroups; std::vector<MaterialGroup> TextureGroups;
std::vector<Vertex> m_Vertices; std::vector<Vertex> m_Vertices;
std::vector<unsigned int> m_Indices; std::vector<unsigned int> m_Indices;
-32
View File
@@ -1,32 +0,0 @@
#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
+109 -53
View File
@@ -7,14 +7,62 @@
#include "../Common.h" #include "../Common.h"
#include "../GLM.h" #include "../GLM.h"
#include "../Core/Util/Rectangle.h" #include "../Core/Util/Rectangle.h"
#include "../Core/Entity.h" #include "../Core/EntityWrapper.h"
#include "Camera.h"
#include "RenderJob.h"
#include "ModelJob.h"
#include "PointLightJob.h"
class Model;
class Skeleton;
class Texture;
class RenderQueue;
//TODO: Render: Remove obsolete RenderJobs and fix standard values on variables.
struct RenderJob
{
friend class RenderQueue;
float Depth;
protected:
uint64_t Hash;
virtual void CalculateHash() = 0;
bool operator<(const RenderJob& rhs)
{
return this->Hash < rhs.Hash;
}
};
struct ModelJob : RenderJob
{
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 struct SpriteJob : RenderJob
{ {
unsigned int ShaderID = 0; unsigned int ShaderID = 0;
@@ -34,65 +82,73 @@ struct SpriteJob : RenderJob
struct PointLightJob : RenderJob struct PointLightJob : RenderJob
{ {
glm::vec4 Position; glm::vec3 Position;
glm::vec4 Color; glm::vec3 SpecularColor = glm::vec3(1, 1, 1);
float Radius; glm::vec3 DiffuseColor = glm::vec3(1, 1, 1);
float Intensity; float Radius = 1.f;
float Falloff; float Intensity = 0.8f;
float padding = 123;
void CalculateHash() override void CalculateHash() override
{ {
Hash = 0; Hash = 0;
} }
}; };
*/
struct RenderScene class RenderQueue
{ {
::Camera* Camera; public:
std::list<std::shared_ptr<RenderJob>> ForwardJobs; template <typename T>
std::list<std::shared_ptr<RenderJob>> PointLightJobs; void Add(T &job)
Rectangle Viewport; {
job.CalculateHash();
Jobs.push_back(std::shared_ptr<T>(new T(job)));
m_Size++;
}
void Sort()
{
Jobs.sort();
}
void Clear() void Clear()
{ {
ForwardJobs.clear(); Jobs.clear();
PointLightJobs.clear(); m_Size = 0;
}
int Size() const { return m_Size; }
std::list<std::shared_ptr<RenderJob>>::const_iterator begin()
{
return Jobs.begin();
}
std::list<std::shared_ptr<RenderJob>>::const_iterator end()
{
return Jobs.end();
}
std::list<std::shared_ptr<RenderJob>> Jobs;
private:
int m_Size = 0;
};
struct RenderQueueCollection
{
RenderQueue Forward;
RenderQueue Lights;
void Clear()
{
Forward.Clear();
Lights.Clear();
}
void Sort()
{
Forward.Sort();
Lights.Sort();
} }
}; };
struct RenderFrame
{
public:
void Add(RenderScene &scene)
{
RenderScenes.push_back(std::shared_ptr<RenderScene>(new RenderScene(scene)));
m_Size++;
}
void Clear()
{
RenderScenes.clear();
m_Size = 0;
}
int Size() const { return m_Size; }
std::list<std::shared_ptr<RenderScene>>::const_iterator begin()
{
return RenderScenes.begin();
}
std::list<std::shared_ptr<RenderScene>>::const_iterator end()
{
return RenderScenes.end();
}
std::list<std::shared_ptr<RenderScene>> RenderScenes;
private:
int m_Size = 0;
};
#endif #endif
@@ -0,0 +1,28 @@
#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);
glm::mat4 ModelMatrix(World* world, EntityID entity);
glm::vec3 GetAbsolutePosition(World* world, ComponentWrapper transformComponent);
};
#endif
-27
View File
@@ -1,27 +0,0 @@
#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
-55
View File
@@ -1,55 +0,0 @@
#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 "PointLightJob.h"
#include "../Core/Transform.h"
#include "DebugCameraInputController.h"
class RenderSystem : public ImpureSystem
{
public:
RenderSystem(EventBroker* eventBrokerer, const IRenderer* renderer, RenderFrame* renderFrame);
~RenderSystem();
virtual void Update(World* world, double dt) override;
private:
World* m_World = nullptr;
const IRenderer* m_Renderer;
RenderFrame* m_RenderFrame;
bool m_SwitchCamera = false;
Camera* m_Camera;
DebugCameraInputController<RenderSystem>* m_DebugCameraInputController;
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);
void fillModels(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
void fillLight(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
EventRelay<RenderSystem, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e);
};
#endif
+24 -39
View File
@@ -10,63 +10,48 @@
#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 "LightCullingPass.h"
#include "DrawFinalPass.h"
#include "../Core/EventBroker.h"
#include "ImGuiRenderPass.h"
#include "Camera.h"
#include "../Core/Transform.h"
class Renderer : public IRenderer class Renderer : public IRenderer
{ {
public: public:
Renderer(EventBroker* eventBroker, World* world) virtual void Initialize() override;
: m_EventBroker(eventBroker) virtual void Update(double dt) override;
, m_World(world) virtual void Draw(RenderQueueCollection& rq) override;
{ }
virtual void Initialize() override;
virtual void Update(double dt) override;
virtual void Draw(RenderFrame& frame) override;
virtual PickData Pick(glm::vec2 screenCoord) override;
private: private:
//----------------------Variables----------------------// //----------------------Variables----------------------//
EventBroker* m_EventBroker; Texture* m_ErrorTexture;
World* m_World; Texture* m_WhiteTexture;
float m_CameraMoveSpeed;
Texture* m_ErrorTexture; FrameBuffer m_PickingBuffer;
Texture* m_WhiteTexture; GLuint m_PickingTexture;
GLuint m_DepthBuffer;
Model* m_ScreenQuad; Model* m_ScreenQuad;
Model* m_UnitQuad; Model* m_UnitQuad;
Model* m_UnitSphere; Model* m_UnitSphere;
DrawScenePass* m_DrawScenePass;
PickingPass* m_PickingPass;
LightCullingPass* m_LightCullingPass;
ImGuiRenderPass* m_ImGuiRenderPass;
DrawFinalPass* m_DrawFinalPass;
//----------------------Functions----------------------//
void InitializeWindow(); std::unordered_map<glm::vec2, EntityID> m_PickingColorsToEntity;
void InitializeShaders();
//----------------------Functions----------------------//
void InitializeWindow();
void InitializeShaders();
void InitializeTextures(); void InitializeTextures();
void InitializeRenderPasses(); void InitializeFrameBuffers();
//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);
static bool DepthSort(const std::shared_ptr<RenderJob> &i, const std::shared_ptr<RenderJob> &j) { return (i->Depth < j->Depth); }
void FillDepth(RenderScene& scene);
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_DrawScreenQuadProgram; ShaderProgram m_PickingProgram;
ShaderProgram m_DrawScreenQuadProgram;
}; };
#endif #endif
+3 -10
View File
@@ -1,9 +1,6 @@
#ifndef 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,13 +60,11 @@ public:
: ShaderType(fileName) { } : ShaderType(fileName) { }
}; };
class ShaderProgram : public Resource class ShaderProgram
{ {
friend class ResourceManager;
private:
ShaderProgram(std::string)
: m_ShaderProgramHandle(0) { }
public: public:
ShaderProgram()
: m_ShaderProgramHandle(0) { }
~ShaderProgram(); ~ShaderProgram();
void AddShader(std::shared_ptr<Shader> shader); void AddShader(std::shared_ptr<Shader> shader);
@@ -84,5 +79,3 @@ private:
GLuint m_ShaderProgramHandle; GLuint m_ShaderProgramHandle;
std::vector<std::shared_ptr<Shader>> m_Shaders; std::vector<std::shared_ptr<Shader>> m_Shaders;
}; };
#endif
+1 -1
View File
@@ -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;
} }
+2 -9
View File
@@ -11,13 +11,6 @@ class ScreenCoords
{ {
public: public:
ScreenCoords() = delete; ScreenCoords() = delete;
struct PixelData
{
int Color[2];
float Depth;
};
//Return world position from given screenspace coordinates and depth value in viewspace. //Return world position from given screenspace coordinates and depth value in viewspace.
static glm::vec3 ToWorldPos(glm::vec2 screenCoord, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat); static glm::vec3 ToWorldPos(glm::vec2 screenCoord, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
static glm::vec3 ToWorldPos(float x, float y, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat); static glm::vec3 ToWorldPos(float x, float y, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
@@ -25,8 +18,8 @@ public:
static glm::vec3 ToWorldPos(float x, float y, float depth, float screenWidth, float screenHeight, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat); static glm::vec3 ToWorldPos(float x, float y, float depth, float screenWidth, float screenHeight, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat);
//Return data from the given buffers at the coordinates given in screenspace. Buffer should probably have a texture that covers the screen. //Return data from the given buffers at the coordinates given in screenspace. Buffer should probably have a texture that covers the screen.
//Data is given as R = x, B = y, and //Data is given as R = x, B = y, and
static PixelData ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer); static glm::vec3 ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer);
static PixelData ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer); static glm::vec3 ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer);
//Return EntityID of the clicked coordinate in given screenspace coordinates. //Return EntityID of the clicked coordinate in given screenspace coordinates.
//EntityID ScreenCoordsToEntityID(glm::vec2 screenCoord, float depth); //EntityID ScreenCoordsToEntityID(glm::vec2 screenCoord, float depth);
@@ -1,24 +0,0 @@
#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
-17
View File
@@ -1,17 +0,0 @@
#ifndef Events_ContinueSound_h__
#define Events_ContinueSound_h__
#include "Core/EventBroker.h"
#include "Core/Entity.h"
namespace Events
{
// Continues to play a sound from where it was paused.
struct ContinueSound : Event
{
EntityID EmitterID;
};
}
#endif
-17
View File
@@ -1,17 +0,0 @@
#ifndef Events_PauseSound_h__
#define Events_PauseSound_h__
#include "Core/EventBroker.h"
#include "Core/Entity.h"
namespace Events
{
// Pauses a playing sound
struct PauseSound : Event
{
EntityID EmitterID;
};
}
#endif
@@ -1,18 +0,0 @@
#ifndef Events_PlayBackgroundMusic_h__
#define Events_PlayBackgroundMusic_h__
#include <string>
#include "Core/Entity.h"
#include "Core/Event.h"
namespace Events
{
// Play a sound that will be heared the same anywhere
struct PlayBackgroundMusic : public Event
{
std::string FilePath = "";
};
}
#endif
-21
View File
@@ -1,21 +0,0 @@
#ifndef Events_PlaySoundOnEntity_h__
#define Events_PlaySoundOnEntity_h__
#include <string>
#include "Core/Entity.h"
#include "Core/Event.h"
namespace Events
{
// Plays a sound on an entity with a SoundEmitter component attached.
// Sound behavior is thereby specified in the SoundEmitter component.
struct PlaySoundOnEntity : public Event
{
EntityID EmitterID = 0;
std::string FilePath = "";
};
}
#endif
@@ -1,26 +0,0 @@
#ifndef Events_PlaySoundOnPosition_h__
#define Events_PlaySoundOnPosition_h__
#include <string>
#include <glm/common.hpp>
#include "Core/Event.h"
namespace Events
{
// Plays a sound on a given position. Idk if this would be useful.
struct PlaySoundOnPosition : public Event
{
glm::vec3 Position = glm::vec3(0);
std::string FilePath = "";
float Gain = 1;
float Pitch = 1;
bool Loop = false;
float MaxDistance = 20;
float RollOffFactor = 1;
float ReferenceDistance = 1;
};
}
#endif
-16
View File
@@ -1,16 +0,0 @@
#ifndef Events_SetBGMGain_h__
#define Events_SetBGMGain_h__
#include "Core/Event.h"
namespace Events
{
// Set the "volume" for all background sounds
struct SetBGMGain : public Event
{
float Gain;
};
}
#endif
-16
View File
@@ -1,16 +0,0 @@
#ifndef Events_SetSFXGain_h__
#define Events_SetSFXGain_h__
#include "Core/Event.h"
namespace Events
{
// Set the "volume" for all effect sounds
struct SetSFXGain : public Event
{
float Gain;
};
}
#endif
-17
View File
@@ -1,17 +0,0 @@
#ifndef Events_StopSound_h__
#define Events_StopSound_h__
#include "Core/EventBroker.h"
#include "Core/Entity.h"
namespace Events
{
// Stops a sound emitter, and will also delete it.
struct StopSound : Event
{
EntityID EmitterID;
};
}
#endif

Some files were not shown because too many files have changed in this diff Show More