Merge remote-tracking branch 'origin/Picking' into RendererDecoupling

# Conflicts:
#	include/Engine/Rendering/Renderer.h
#	src/Engine/Rendering/Renderer.cpp
This commit is contained in:
Tleety
2015-12-11 11:21:58 +01:00
39 changed files with 1186 additions and 246 deletions
+2 -2
View File
@@ -2,7 +2,7 @@
#define ComponentWrapper_h__
#include "../Common.h"
#include "EntityWrapper.h"
#include "Entity.h"
#include "ComponentInfo.h"
#include "Util/Any.h"
@@ -11,7 +11,7 @@ struct ComponentWrapper
ComponentWrapper(const ComponentInfo& componentInfo, char* data)
: Info(componentInfo)
, EntityID(*reinterpret_cast<::EntityID*>(data))
, Data(data + sizeof(EntityID))
, Data(data + sizeof(::EntityID))
{ }
const ComponentInfo& Info;
+6
View File
@@ -0,0 +1,6 @@
#ifndef Entity_h__
#define Entity_h__
typedef unsigned int EntityID;
#endif
-12
View File
@@ -1,12 +0,0 @@
#include "ResourceManager.h"
class EntityFile : public Resource
{
friend class ResourceManager;
private:
EntityFile(std::string path);
public:
};
-15
View File
@@ -1,15 +0,0 @@
#ifndef Entity_h__
#define Entity_h__
typedef unsigned int EntityID;
struct EntityWrapper
{
EntityWrapper(EntityID entityID)
: ID(entityID)
{ }
EntityID ID;
};
#endif
+141
View File
@@ -0,0 +1,141 @@
#ifndef EntityXMLFile_h__
#define EntityXMLFile_h__
#include <sstream>
#include "../Common.h"
#include "../GLM.h"
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMLSInput.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/framework/Wrapper4InputSource.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
#include <xercesc/framework/LocalFileFormatTarget.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLFloat.hpp>
#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
#include <xercesc/framework/psvi/XSParticle.hpp>
#include <xercesc/framework/psvi/XSModelGroup.hpp>
#include <xercesc/framework/psvi/XSAnnotation.hpp>
#include <xercesc/framework/psvi/XSValue.hpp>
#include <xercesc/framework/XMLValidator.hpp>
#include "ResourceManager.h"
#include "Entity.h"
#include "ComponentInfo.h"
class World;
class EntityPreprocessorXMLErrorHandler : public xercesc::DOMErrorHandler
{
public:
bool handleError(const xercesc::DOMError &e) override
{
char* message = xercesc::XMLString::transcode(e.getMessage());
std::cerr << "Preprocessor DOMError: " << message << std::endl;
xercesc::XMLString::release(&message);
return false;
}
};
class EntityParserXMLErrorHandler : public xercesc::ErrorHandler
{
public:
void warning(const xercesc::SAXParseException& e) override
{
reportParseException("Warning", e);
}
void error(const xercesc::SAXParseException& e) override
{
reportParseException("Error", e);
}
void fatalError(const xercesc::SAXParseException& e) override
{
reportParseException("FATAL ERROR", e);
}
void resetErrors() override { }
private:
void reportParseException(std::string type, const xercesc::SAXParseException& e)
{
char* message = xercesc::XMLString::transcode(e.getMessage());
char* systemID = xercesc::XMLString::transcode(e.getSystemId());
std::cerr << systemID << ":" << e.getLineNumber() << ":" << e.getColumnNumber() << std::endl;
std::cerr << type << ": " << message << std::endl;
xercesc::XMLString::release(&systemID);
xercesc::XMLString::release(&message);
}
};
class XSTR
{
public:
XSTR(const XMLCh* const xmlString)
{
m_AsChar = xercesc::XMLString::transcode(xmlString);
}
XSTR(const char* normalString)
{
m_AsXMLCh = xercesc::XMLString::transcode(normalString);
}
~XSTR()
{
if (m_AsChar != nullptr) {
xercesc::XMLString::release(&m_AsChar);
}
if (m_AsXMLCh != nullptr) {
xercesc::XMLString::release(&m_AsXMLCh);
}
}
operator const char*() const { return m_AsChar; }
operator const XMLCh*() const { return m_AsXMLCh; }
private:
char* m_AsChar = nullptr;
XMLCh* m_AsXMLCh = nullptr;
};
class EntityXMLFile : public Resource
{
friend class ResourceManager;
private:
EntityXMLFile(std::string path);
public:
~EntityXMLFile();
void PopulateWorld(World* world);
private:
static unsigned int InstanceCount;
std::string m_EntityFile;
xercesc::XMLGrammarPool* m_GrammarPool = nullptr;
EntityParserXMLErrorHandler* m_ErrorHandler = nullptr;
xercesc::XercesDOMParser* m_DOMParser = nullptr;
xercesc::DOMDocument* m_DOMDocument = nullptr;
std::map<std::string, ComponentInfo> m_ComponentInfo;
// Preprocesses the entity file to insert include-by-copy child entities
// TODO: Make this work in memory instead of saving to file
void preprocess(std::string inPath, std::string outPath);
void parseComponentInfo();
void parseDefaults();
void predictComponentAllocation();
void parseEntityGraph(World* world, xercesc::DOMElement* parent, EntityID parentEntity);
std::size_t getTypeStride(std::string typeName);
float getFloatAttribute(const xercesc::DOMElement* element, const char* attribute) const;
void writeData(const xercesc::DOMElement* element, std::string typeName, char* outData);
};
#endif
+2
View File
@@ -81,6 +81,8 @@ public:
@param resourceName Fully qualified name of the resource to reload.
*/
static void Reload(std::string resourceName);
static void Release(std::string resourceType, std::string resourceName);
static void Update();
+25
View File
@@ -0,0 +1,25 @@
#ifndef System_h__
#define System_h__
#include "EventBroker.h"
#include "World.h"
#include "ComponentWrapper.h"
class System
{
friend class SystemPipeline;
public:
System(const EventBroker* eventBroker, std::string componentType)
: m_EventBroker(eventBroker)
, m_ComponentType(componentType)
{ }
virtual void Update(World* world, ComponentWrapper& component, double dt) = 0;
private:
const EventBroker* m_EventBroker;
std::string m_ComponentType;
};
#endif
+58
View File
@@ -0,0 +1,58 @@
#ifndef SystemPipeline_h__
#define SystemPipeline_h__
#include "../Common.h"
#include "EventBroker.h"
#include "System.h"
#include "World.h"
class SystemPipeline
{
public:
SystemPipeline(const EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{ }
~SystemPipeline()
{
for (auto& pair : m_Systems) {
for (auto& system : pair.second) {
delete system;
}
}
}
template <typename T, typename... Arguments>
void AddSystem(Arguments... args)
{
System* system = new T(m_EventBroker, args...);
if (!system->m_ComponentType.empty()) {
m_Systems[system->m_ComponentType].push_back(system);
} else {
LOG_ERROR("Failed to add system \"%s\": Missing component type!", typeid(T).name());
delete system;
}
}
void Update(World* world, double dt)
{
for (auto& pair : m_Systems) {
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->Update(world, component, dt);
}
}
}
}
private:
const EventBroker* m_EventBroker;
std::unordered_map<std::string, std::vector<System*>> m_Systems;
};
#endif
+6 -3
View File
@@ -2,7 +2,7 @@
#define World_h__
#include "../Common.h"
#include "EntityWrapper.h"
#include "Entity.h"
#include "ObjectPool.h"
#include "ComponentPool.h"
@@ -12,6 +12,7 @@ public:
World() = default;
~World();
// Create empty entity
EntityID CreateEntity(EntityID parent = 0);
// Register a component type and allocate space for it
@@ -21,10 +22,12 @@ public:
// Get a component of an entity
ComponentWrapper GetComponent(EntityID entity, std::string componentType);
// 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);
private:
EntityID m_CurrentEntityID = 0;
EntityID m_CurrentEntityID = 1;
std::unordered_map<EntityID, EntityID> m_EntityParents;
std::unordered_multimap<EntityID, EntityID> m_EntityChildren;
+69
View File
@@ -0,0 +1,69 @@
#ifndef Events_Picking_h__
#define Events_Picking_h__
#include "../OpenGL.h"
#include "../GLM.h"
#include "../Core/EventBroker.h"
#include "Util/ScreenCoords.h"
#include "FrameBuffer.h"
#include "../Core/Entity.h"
#include "Util/UnorderedMapVec2.h"
namespace Events
{
/** Thrown Every frame, use functions to pick*/
struct Picking : Event
{
public:
Picking(FrameBuffer* pickingBuffer, GLuint* depthBuffer, glm::mat4 projectionMatrix, glm::mat4 viewMatrix, Rectangle resolution, const std::unordered_map<glm::vec2, EntityID>* pickingColorsToEntity)
: PickingBuffer(pickingBuffer)
, DepthBuffer(depthBuffer)
, ProjectionMatrix(projectionMatrix)
, ViewMatrix(viewMatrix)
, Resolution(resolution)
, PickingColorsToEntity(pickingColorsToEntity)
{ }
struct PickData
{
//Picked Entity
EntityID Entity;
//World position of the "pick"
glm::vec3 Position;
};
PickData Pick(glm::vec2 screenCoord) const
{
PickData pickData;
ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, PickingBuffer, *DepthBuffer);
auto it = PickingColorsToEntity->find(glm::vec2(data.Color[0], data.Color[1]));
if (it != PickingColorsToEntity->end()) {
pickData.Entity = it->second;
} else {
pickData.Entity = -1;
}
pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, Resolution.Width - screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix);
return pickData;
}
private:
FrameBuffer* PickingBuffer;
GLuint* DepthBuffer;
const glm::mat4 ProjectionMatrix;
const glm::mat4 ViewMatrix;
const Rectangle Resolution;
const std::unordered_map<glm::vec2, EntityID>* PickingColorsToEntity;
};
}
#endif
+1 -1
View File
@@ -7,7 +7,7 @@
#include "../Common.h"
#include "../GLM.h"
#include "../Core/Util/Rectangle.h"
#include "../Core/EntityWrapper.h"
#include "../Core/Entity.h"
class Model;
class Skeleton;
@@ -22,7 +22,10 @@ private:
void FillLights(World* world, RenderQueue* renderQueue);
glm::mat4 ModelMatrix(World* world, EntityID entity);
glm::vec3 GetAbsolutePosition(World* world, ComponentWrapper transformComponent);
glm::vec3 AbsolutePosition(World* world, EntityID entity);
glm::quat AbsoluteOrientation(World* world, EntityID entity);
glm::vec3 AbsoluteScale(World* world, EntityID entity);
};
#endif
+9
View File
@@ -25,15 +25,24 @@ enum lightType
Area
};
#include "../Core/EventBroker.h"
#include "EPicking.h"
class Renderer : public IRenderer
{
public:
Renderer(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{ }
virtual void Initialize() override;
virtual void Update(double dt) override;
virtual void Draw(RenderQueueCollection& rq) override;
private:
//----------------------Variables----------------------//
EventBroker* m_EventBroker;
Texture* m_ErrorTexture;
Texture* m_WhiteTexture;
float m_CameraMoveSpeed;