Merge branch 'master' of https://github.com/teamfisk/TacticalZ into Importer

# Conflicts:
#	include/Engine/Collision/Collision.h
#	resources/Shaders/ForwardPlus.frag.glsl
#	resources/Shaders/ForwardPlus.vert.glsl
This commit is contained in:
antc13
2016-01-19 18:26:45 +01:00
119 changed files with 1871 additions and 756 deletions
+1 -1
Submodule assets updated: a3c92ac876...6ffb46e155
@@ -0,0 +1,24 @@
#ifndef CollidableOctreeSystem_h__
#define CollidableOctreeSystem_h__
#include "../Core/System.h"
#include "../Core/Octree.h"
#include "Collision.h"
class CollidableOctreeSystem : public ImpureSystem, public PureSystem
{
public:
CollidableOctreeSystem(EventBroker* eventBroker, Octree* octree)
: System(eventBroker)
, PureSystem("Collidable")
, m_Octree(octree)
{ }
virtual void Update(World* world, double dt) override;
virtual void UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt) override;
private:
Octree* m_Octree;
};
#endif
+11 -3
View File
@@ -6,12 +6,15 @@
//or you will get "fatal error C1189: #error: gl.h included before glew.h" //or you will get "fatal error C1189: #error: gl.h included before glew.h"
#include <vector> #include <vector>
#include <boost/optional.hpp>
#include "../Core/Ray.h" #include "../Core/Ray.h"
#include "../Core/AABB.h" #include "../Core/AABB.h"
//#include "Engine/Rendering/RawModelAssimp.h" //#include "Engine/Rendering/RawModelAssimp.h"
#include "Engine/Rendering/RawModelCustom.h" #include "Engine/Rendering/RawModelCustom.h"
#include "../Core/Transform.h"
#include "../Core/Entity.h" #include "../Core/Entity.h"
#include "../Core/EntityWrapper.h"
class World; class World;
struct ComponentWrapper; struct ComponentWrapper;
@@ -44,6 +47,12 @@ bool RayVsModel(const Ray& ray,
float& outUCoord, float& outUCoord,
float& outVCoord); float& outVCoord);
bool AABBvsTriangles(const AABB& box,
const std::vector<RawModel::Vertex>& modelVertices,
const std::vector<unsigned int>& modelIndices,
const glm::mat4& modelMatrix,
glm::vec3& outResolutionVector);
//Return true if the boxes are intersecting. //Return true if the boxes are intersecting.
bool AABBVsAABB(const AABB& a, const AABB& b); bool AABBVsAABB(const AABB& a, const AABB& b);
//Return true if the boxes are intersecting. //Return true if the boxes are intersecting.
@@ -51,9 +60,8 @@ bool AABBVsAABB(const AABB& a, const AABB& b);
bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation); bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation);
bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon = 0.0001f); 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]. // Calculates an absolute AABB from an entity AABB component
bool GetEntityBox(World* world, EntityID entity, AABB& outBox, bool forceBoxFromModel = false); boost::optional<AABB> EntityAbsoluteAABB(EntityWrapper& entity);
bool GetEntityBox(World* world, ComponentWrapper& AABBComponent, AABB& outBox);
} }
+8 -3
View File
@@ -8,22 +8,27 @@
#include "../Core/System.h" #include "../Core/System.h"
#include "../Core/EventBroker.h" #include "../Core/EventBroker.h"
#include "../Core/EKeyUp.h" #include "../Core/EKeyUp.h"
#include "../Core/Octree.h"
class CollisionSystem : public PureSystem class CollisionSystem : public PureSystem
{ {
public: public:
CollisionSystem(EventBroker* eventBroker) CollisionSystem(EventBroker* eventBroker, Octree* octree)
: PureSystem(eventBroker, "AABB") : System(eventBroker)
, PureSystem("Collidable")
, m_Octree(octree)
, zPress(false) , zPress(false)
{ {
//TODO: Debug stuff, remove later. //TODO: Debug stuff, remove later.
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &CollisionSystem::OnKeyUp); EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &CollisionSystem::OnKeyUp);
} }
virtual void UpdateComponent(World* world, ComponentWrapper& cAABB, double dt) override; virtual void UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt) override;
private: private:
Octree* m_Octree;
bool zPress; bool zPress;
EventRelay<CollisionSystem, Events::KeyUp> m_EKeyUp; EventRelay<CollisionSystem, Events::KeyUp> m_EKeyUp;
bool OnKeyUp(const Events::KeyUp &event); bool OnKeyUp(const Events::KeyUp &event);
}; };
+20 -4
View File
@@ -6,6 +6,7 @@
#include "../Core/System.h" #include "../Core/System.h"
#include "../Core/EventBroker.h" #include "../Core/EventBroker.h"
#include "../Core/Octree.h"
#include "ETrigger.h" #include "ETrigger.h"
class AABB; class AABB;
@@ -13,16 +14,31 @@ class AABB;
class TriggerSystem : public PureSystem class TriggerSystem : public PureSystem
{ {
public: public:
TriggerSystem(EventBroker* eventBroker) TriggerSystem(EventBroker* eventBroker, Octree* octree)
: PureSystem(eventBroker, "Trigger") : System(eventBroker)
{} , PureSystem("Trigger")
, m_Octree(octree)
{
EVENT_SUBSCRIBE_MEMBER(m_ETouch, &TriggerSystem::OnTouch);
EVENT_SUBSCRIBE_MEMBER(m_EEnter, &TriggerSystem::OnEnter);
EVENT_SUBSCRIBE_MEMBER(m_ELeave, &TriggerSystem::OnLeave);
}
virtual void UpdateComponent(World* world, ComponentWrapper& collision, double dt) override; virtual void UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt) override;
private: private:
Octree* m_Octree;
std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesTouchingTrigger; std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesTouchingTrigger;
std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesCompletelyInTrigger; std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesCompletelyInTrigger;
//TODO: Only exists for debug purposes, remove later.
EventRelay<TriggerSystem, Events::TriggerEnter> m_EEnter;
bool OnEnter(const Events::TriggerEnter &event);
EventRelay<TriggerSystem, Events::TriggerTouch> m_ETouch;
bool OnTouch(const Events::TriggerTouch &event);
EventRelay<TriggerSystem, Events::TriggerLeave> m_ELeave;
bool OnLeave(const Events::TriggerLeave &event);
//True if leave event was thrown. //True if leave event was thrown.
bool throwLeaveIfWasInTrigger(std::unordered_set<EntityID>& triggerSet, EntityID pId, EntityID tId); bool throwLeaveIfWasInTrigger(std::unordered_set<EntityID>& triggerSet, EntityID pId, EntityID tId);
template<typename Event> template<typename Event>
+1
View File
@@ -1,5 +1,6 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <sstream>
#include <vector> #include <vector>
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
+3 -3
View File
@@ -11,18 +11,18 @@ public:
AABB(const glm::vec3& minPos, const glm::vec3& maxPos); AABB(const glm::vec3& minPos, const glm::vec3& maxPos);
AABB(const glm::vec4& minPos, const glm::vec4& maxPos); AABB(const glm::vec4& minPos, const glm::vec4& maxPos);
//No checks are made. Size must consist of non-negative numbers. //No checks are made. Size must consist of non-negative numbers.
virtual void CreateFromCenter(const glm::vec3& center, const glm::vec3& size); static AABB FromOriginSize(const glm::vec3& origin, const glm::vec3& size);
virtual ~AABB(); virtual ~AABB();
const glm::vec3& MinCorner() const { return m_MinCorner; } const glm::vec3& MinCorner() const { return m_MinCorner; }
const glm::vec3& MaxCorner() const { return m_MaxCorner; } const glm::vec3& MaxCorner() const { return m_MaxCorner; }
const glm::vec3& Center() const { return m_Center; } const glm::vec3& Origin() const { return m_Origin; }
const glm::vec3 Size() const { return 2.0f * m_HalfSize; } const glm::vec3 Size() const { return 2.0f * m_HalfSize; }
const glm::vec3& HalfSize() const { return m_HalfSize; } const glm::vec3& HalfSize() const { return m_HalfSize; }
private: private:
glm::vec3 m_MinCorner; glm::vec3 m_MinCorner;
glm::vec3 m_MaxCorner; glm::vec3 m_MaxCorner;
glm::vec3 m_Center; glm::vec3 m_Origin;
glm::vec3 m_HalfSize; glm::vec3 m_HalfSize;
}; };
+4 -2
View File
@@ -9,7 +9,8 @@ struct ComponentInfo
{ {
std::string Annotation; std::string Annotation;
unsigned int Allocation = 0; unsigned int Allocation = 0;
unsigned int Stride = 0; std::map<std::string, std::string> FieldAnnotations;
std::map<std::string, std::map<std::string, int>> FieldEnumDefinitions;
}; };
struct Field_t struct Field_t
@@ -23,8 +24,9 @@ struct ComponentInfo
std::string Name; std::string Name;
std::unordered_map<std::string, Field_t> Fields; std::unordered_map<std::string, Field_t> Fields;
std::vector<std::string> FieldsInOrder; std::vector<std::string> FieldsInOrder;
Meta_t Meta; unsigned int Stride = 0;
std::shared_ptr<char> Defaults = nullptr; std::shared_ptr<char> Defaults = nullptr;
std::shared_ptr<Meta_t> Meta = nullptr;
}; };
template<> template<>
+1 -1
View File
@@ -43,7 +43,7 @@ public:
ComponentPool(const ::ComponentInfo& ci) ComponentPool(const ::ComponentInfo& ci)
: m_ComponentInfo(ci) : m_ComponentInfo(ci)
, m_Pool(ci.Meta.Allocation, sizeof(EntityID) + ci.Meta.Stride) , m_Pool(ci.Meta->Allocation, sizeof(EntityID) + ci.Stride)
{ } { }
ComponentPool(const ComponentPool& other) = delete; ComponentPool(const ComponentPool& other) = delete;
ComponentPool(const ComponentPool&& other) = delete; ComponentPool(const ComponentPool&& other) = delete;
+30 -17
View File
@@ -18,21 +18,31 @@ struct ComponentWrapper
const ::EntityID EntityID; const ::EntityID EntityID;
char* Data; char* Data;
template <typename T> int Enum(const char* fieldName, const char* enumKey)
T& Property(std::string name)
{ {
unsigned int offset = Info.Fields.at(name).Offset; return Info.Meta->FieldEnumDefinitions.at(fieldName).at(enumKey);
return *reinterpret_cast<T*>(&Data[offset]);
} }
template <typename T> template <typename T>
void SetProperty(std::string name, const T value) { Property<T>(name) = value; } T& Field(std::string name)
{
const ComponentInfo::Field_t& field = Info.Fields.at(name);
if (sizeof(T) > field.Stride) {
std::stringstream message;
message << "Type size of \"" << typeid(T).name() << "\" doesn't match size of component field \"" << Info.Name << "." << name << "\"!";
throw new std::runtime_error(message.str().c_str());
}
return *reinterpret_cast<T*>(&Data[field.Offset]);
}
template <typename T>
void SetField(std::string name, const T value) { Field<T>(name) = value; }
//template <typename T> //template <typename T>
//void SetProperty(std::string name, T& value) { Property<T>(name) = value; } //void SetField(std::string name, T& value) { Field<T>(name) = value; }
// Specialization for string literals // Specialization for string literals
template <std::size_t N> template <std::size_t N>
void SetProperty(std::string name, const char(&value)[N]) { Property<std::string>(name) = std::string(value); } void SetField(std::string name, const char(&value)[N]) { Field<std::string>(name) = std::string(value); }
struct SubscriptProxy struct SubscriptProxy
{ {
@@ -47,18 +57,21 @@ struct ComponentWrapper
std::string m_PropertyName; std::string m_PropertyName;
public: public:
template <typename T> // Return the integer value of an enum type key for this field
operator T&() { return m_Component->Property<T>(m_PropertyName); } int Enum(const char* enumKey) { return m_Component->Enum(m_PropertyName.c_str(), enumKey); }
template <typename T> template <typename T>
void operator=(const T val) { m_Component->SetProperty<T>(m_PropertyName, val); } operator T&() { return m_Component->Field<T>(m_PropertyName); }
template <typename T>
void operator=(const T val) { m_Component->SetField<T>(m_PropertyName, val); }
// TODO: Pass by reference and rvalue (universal reference?) // TODO: Pass by reference and rvalue (universal reference?)
//template <typename T> //template <typename T>
//void operator=(T& val) { m_Component->SetProperty<T>(m_PropertyName, val); } //void operator=(T& val) { m_Component->SetField<T>(m_PropertyName, val); }
// Specialization for string literals // Specialization for string literals
template<std::size_t N> template <std::size_t N>
void operator=(const char(&val)[N]) { m_Component->SetProperty<N>(m_PropertyName, val); } void operator=(const char(&val)[N]) { m_Component->SetField<N>(m_PropertyName, val); }
}; };
SubscriptProxy operator[](std::string propertyName) { return SubscriptProxy(this, propertyName); } SubscriptProxy operator[](std::string propertyName) { return SubscriptProxy(this, propertyName); }
}; };
@@ -71,7 +84,7 @@ public:
ComponentWrapperFactory(std::string componentTypeName, std::size_t allocation = 0) ComponentWrapperFactory(std::string componentTypeName, std::size_t allocation = 0)
{ {
m_ComponentInfo.Name = componentTypeName; m_ComponentInfo.Name = componentTypeName;
m_ComponentInfo.Meta.Allocation = allocation; m_ComponentInfo.Meta->Allocation = allocation;
} }
template <typename T> template <typename T>
@@ -79,14 +92,14 @@ public:
{ {
m_DefaultValues.push_back(defaultValue); m_DefaultValues.push_back(defaultValue);
m_ComponentInfo.Fields[fieldName].Name = typeid(T).name(); m_ComponentInfo.Fields[fieldName].Name = typeid(T).name();
m_ComponentInfo.Fields[fieldName].Offset = m_ComponentInfo.Meta.Stride; m_ComponentInfo.Fields[fieldName].Offset = m_ComponentInfo.Stride;
m_ComponentInfo.Fields[fieldName].Stride = sizeof(T); m_ComponentInfo.Fields[fieldName].Stride = sizeof(T);
m_ComponentInfo.Meta.Stride += sizeof(T); m_ComponentInfo.Stride += sizeof(T);
} }
ComponentInfo& Finalize() ComponentInfo& Finalize()
{ {
m_ComponentInfo.Defaults = std::shared_ptr<char>(new char[m_ComponentInfo.Meta.Stride]); m_ComponentInfo.Defaults = std::shared_ptr<char>(new char[m_ComponentInfo.Stride]);
std::size_t offset = 0; std::size_t offset = 0;
for (auto& val : m_DefaultValues) { for (auto& val : m_DefaultValues) {
memcpy(m_ComponentInfo.Defaults.get() + offset, val.Data.get(), val.Size); memcpy(m_ComponentInfo.Defaults.get() + offset, val.Data.get(), val.Size);
+20
View File
@@ -0,0 +1,20 @@
#ifndef EComponentAttached_h__
#define EComponentAttached_h__
#include "EventBroker.h"
#include "World.h"
#include "Entity.h"
#include "ComponentWrapper.h"
namespace Events
{
struct ComponentAttached : Event
{
EntityWrapper Entity;
ComponentWrapper Component;
};
}
#endif
+1
View File
@@ -4,4 +4,5 @@
typedef unsigned int EntityID; typedef unsigned int EntityID;
const static unsigned int EntityID_Invalid = -1; const static unsigned int EntityID_Invalid = -1;
#endif #endif
+8 -8
View File
@@ -285,7 +285,7 @@ private:
XSValue::Status status; XSValue::Status status;
XSValue* val = XSValue::getActualValue(child->getNodeValue(), XSValue::dt_integer, status); XSValue* val = XSValue::getActualValue(child->getNodeValue(), XSValue::dt_integer, status);
compInfo.Meta.Allocation += val->fData.fValue.f_int; compInfo.Meta->Allocation += val->fData.fValue.f_int;
} }
// Save documentation string // Save documentation string
@@ -293,11 +293,11 @@ private:
if (documentationTags->getLength() != 0) { if (documentationTags->getLength() != 0) {
auto child = documentationTags->item(0)->getFirstChild(); auto child = documentationTags->item(0)->getFirstChild();
if (child != nullptr) { if (child != nullptr) {
compInfo.Meta.Annotation = XSTR(child->getNodeValue()); compInfo.Meta->Annotation = XSTR(child->getNodeValue());
} }
} }
// TODO: Parse annotation string XML // TODO: Parse annotation string XML
// compInfo.Meta.Allocation = ... // compInfo.Meta->Allocation = ...
} else { } else {
std::cout << "Warning: Component is missing an annotation!" << std::endl; std::cout << "Warning: Component is missing an annotation!" << std::endl;
} }
@@ -344,7 +344,7 @@ private:
fieldOffset += getTypeStride(type); fieldOffset += getTypeStride(type);
} }
compInfo.Meta.Stride = fieldOffset; compInfo.Stride = fieldOffset;
m_ComponentInfo[compInfo.Name] = compInfo; m_ComponentInfo[compInfo.Name] = compInfo;
} }
} }
@@ -367,14 +367,14 @@ private:
std::string componentName = XSTR(component->getLocalName()); std::string componentName = XSTR(component->getLocalName());
auto& compInfo = m_ComponentInfo.at(componentName); auto& compInfo = m_ComponentInfo.at(componentName);
compInfo.Meta.Allocation += 1; compInfo.Meta->Allocation += 1;
} }
std::cout << "COMPONENT INFO" << std::endl; std::cout << "COMPONENT INFO" << std::endl;
for (auto& pair : m_ComponentInfo) { for (auto& pair : m_ComponentInfo) {
ComponentInfo& ci = pair.second; ComponentInfo& ci = pair.second;
std::cout << "Component: " << ci.Name << " (" << ci.Meta.Annotation << ")" << std::endl; std::cout << "Component: " << ci.Name << " (" << ci.Meta->Annotation << ")" << std::endl;
std::cout << " Allocation: " << ci.Meta.Allocation << std::endl; std::cout << " Allocation: " << ci.Meta->Allocation << std::endl;
std::cout << " Fields:" << std::endl; std::cout << " Fields:" << std::endl;
// Calculate component size // Calculate component size
@@ -393,7 +393,7 @@ private:
cs.ComponentName = ci.Name; cs.ComponentName = ci.Name;
cs.Stride = stride; cs.Stride = stride;
cs.Info = ci; cs.Info = ci;
cs.Data = new char[stride*ci.Meta.Allocation]; cs.Data = new char[stride*ci.Meta->Allocation];
m_ComponentStore[cs.ComponentName] = cs; m_ComponentStore[cs.ComponentName] = cs;
} }
} }
+18 -147
View File
@@ -73,88 +73,15 @@ public:
ComponentField ComponentField
}; };
EntityFileSAXHandler(const EntityFileHandler* handler, xercesc::SAX2XMLReader* reader) 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 void startElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname, const xercesc::Attributes& attrs) override;
{ void characters(const XMLCh* const chars, const XMLSize_t length) override;
std::string name = XS::ToString(_localName); void endElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname) override;
if (m_StateStack.top() == State::Unknown || m_StateStack.top() == State::Entity) { void warning(const xercesc::SAXParseException& e);
if (name == "Entity") { void error(const xercesc::SAXParseException& e);
m_StateStack.push(State::Entity); void fatalError(const xercesc::SAXParseException& e);
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: private:
const EntityFileHandler* m_Handler; const EntityFileHandler* m_Handler;
@@ -168,73 +95,14 @@ private:
std::string m_CurrentField; std::string m_CurrentField;
std::map<std::string, std::string> m_CurrentAttributes; std::map<std::string, std::string> m_CurrentAttributes;
void onStartEntity(const xercesc::Attributes& attrs) void onStartEntity(const xercesc::Attributes& attrs);
{ void onEndEntity();
EntityID parent = m_EntityStack.top(); void onStartEntityRef(const xercesc::Attributes& attrs);
void onStartComponent(const std::string& name);
if (m_Handler->m_OnStartEntityCallback) { void onEndComponent(const std::string& name);
std::string name; void onStartComponentField(const std::string& field, const xercesc::Attributes& attrs);
auto xName = attrs.getValue(XS::ToXMLCh("name")); void onEndComponentField(const std::string& field);
if (xName != nullptr) { void onFieldData(char* data);
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 class EntityFileXMLErrorHandler : public xercesc::ErrorHandler
@@ -269,6 +137,7 @@ private:
class EntityFile : public Resource class EntityFile : public Resource
{ {
friend class ResourceManager; friend class ResourceManager;
friend class EntityFileSAXHandler;
private: private:
EntityFile(boost::filesystem::path path); EntityFile(boost::filesystem::path path);
~EntityFile(); ~EntityFile();
@@ -288,6 +157,8 @@ private:
xercesc::SAX2XMLReader* m_SAX2XMLReader; xercesc::SAX2XMLReader* m_SAX2XMLReader;
//std::map<std::string, ::ComponentInfo> m_ComponentInfo; //std::map<std::string, ::ComponentInfo> m_ComponentInfo;
//std::vector<std::string> m_EntityReferences; //std::vector<std::string> m_EntityReferences;
static void setReaderFeatures(xercesc::SAX2XMLReader* reader);
}; };
#endif #endif
+2 -1
View File
@@ -9,12 +9,13 @@ class EntityFileParser
public: public:
EntityFileParser(const EntityFile* entityFile); EntityFileParser(const EntityFile* entityFile);
void MergeEntities(World* world); EntityID MergeEntities(World* world, EntityID baseParent = EntityID_Invalid);
private: private:
const EntityFile* m_EntityFile; const EntityFile* m_EntityFile;
EntityFileHandler m_Handler; EntityFileHandler m_Handler;
World* m_World = nullptr; World* m_World = nullptr;
EntityID m_FirstEntity = EntityID_Invalid;
// Maps EntityIDs local to the file to real IDs in the world after they've been // Maps EntityIDs local to the file to real IDs in the world after they've been
// created in order to resolve parent-child relationships. // created in order to resolve parent-child relationships.
std::map<EntityID, EntityID> m_EntityIDMapper; std::map<EntityID, EntityID> m_EntityIDMapper;
@@ -5,6 +5,7 @@
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp> #include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
#include <xercesc/framework/psvi/XSParticle.hpp> #include <xercesc/framework/psvi/XSParticle.hpp>
#include <xercesc/framework/psvi/XSModelGroup.hpp> #include <xercesc/framework/psvi/XSModelGroup.hpp>
#include <xercesc/framework/psvi/XSModelGroupDefinition.hpp>
#include <xercesc/framework/psvi/XSAnnotation.hpp> #include <xercesc/framework/psvi/XSAnnotation.hpp>
#include <xercesc/framework/psvi/XSValue.hpp> #include <xercesc/framework/psvi/XSValue.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp> #include <xercesc/framework/MemBufFormatTarget.hpp>
@@ -31,6 +32,7 @@ private:
void onStartComponent(EntityID entity, std::string type); void onStartComponent(EntityID entity, std::string type);
void parseComponentInfo(); void parseComponentInfo();
void parseDefaults(); void parseDefaults();
std::string parseAnnotationXML(const XMLCh* xml);
}; };
#endif #endif
+32
View File
@@ -0,0 +1,32 @@
#ifndef EntityWrapper_h__
#define EntityWrapper_h__
#include <boost/optional.hpp>
#include "ComponentWrapper.h"
class World;
struct EntityWrapper
{
EntityWrapper()
: World(nullptr)
, ID(EntityID_Invalid)
{ }
EntityWrapper(::World* world, EntityID id)
: World(world)
, ID(id)
{ }
::World* World;
EntityID ID;
static const EntityWrapper Invalid;
bool HasComponent(const std::string& componentName);
ComponentWrapper operator[](const std::string& componentName);
bool operator==(const EntityWrapper& e);
explicit operator EntityID();
};
#endif
+2 -2
View File
@@ -43,7 +43,7 @@ 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(EventType&)> CallbackType;
EventRelay() EventRelay()
: m_Callback(nullptr) : m_Callback(nullptr)
@@ -65,7 +65,7 @@ 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<EventType*>(event.get()));
} else { } else {
return false; return false;
} }
+14 -4
View File
@@ -5,6 +5,14 @@
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.
@@ -80,8 +88,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]; ++m_CurrentAllocSlot); for (; m_CurrentAllocSlot < m_NumSlots && m_SlotIsAllocated[m_CurrentAllocSlot] && !DisableMemoryPool::Value; ++m_CurrentAllocSlot);
if (m_CurrentAllocSlot < m_NumSlots) { if (m_CurrentAllocSlot < m_NumSlots && !DisableMemoryPool::Value) {
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.
@@ -93,7 +101,9 @@ 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.
LOG_WARNING("Allocated slots exceed Pool size, extra memory allocated dynamically. Pool size: %u, dynamic size: %u.", m_NumSlots, m_ExtraMemory.size()); 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());
}
return m_ExtraMemory.back(); return m_ExtraMemory.back();
} }
} }
@@ -108,7 +118,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 (IsAllocatedInPool(obj)) { if (!DisableMemoryPool::Value && 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;
@@ -1,11 +1,12 @@
#ifndef OctTree_h__ #ifndef Octree_h__
#define OctTree_h__ #define Octree_h__
#include "Core/AABB.h" #include "../Common.h"
#include "AABB.h"
class Ray; class Ray;
class OctTree class Octree
{ {
public: public:
struct Output struct Output
@@ -13,16 +14,16 @@ public:
float CollideDistance; float CollideDistance;
}; };
OctTree(); Octree() = delete;
~OctTree(); ~Octree();
//For the root OctTree, [octTreeBounds] should be a box containing the entire level. //For the root Octree, [octreeBounds] should be a box containing the entire level.
OctTree(const AABB& octTreeBounds, int subDivisions); Octree(const AABB& octreeBounds, int subDivisions);
//We cannot copy the OctTree as of now, because of the recursive dynamic allocation. //We cannot copy the Octree 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. //Define these if the Octree suddenly needs to be copied, think of the children Child* ptrs.
OctTree(const OctTree& other) = delete; Octree(const Octree& other) = delete;
OctTree(const OctTree&& other) = delete; Octree(const Octree&& other) = delete;
OctTree& operator= (const OctTree& other) = delete; Octree& operator= (const Octree& other) = delete;
//Add a dynamic object (one that moves around) into the tree. //Add a dynamic object (one that moves around) into the tree.
void AddDynamicObject(const AABB& box); void AddDynamicObject(const AABB& box);
//Add a static object (that does not move) into the tree. //Add a static object (that does not move) into the tree.
@@ -42,7 +43,7 @@ public:
bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected); bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected);
private: private:
struct OctChild; //Fwd declaration; struct Child; //Fwd declaration;
struct ContainedObject struct ContainedObject
{ {
ContainedObject() ContainedObject()
@@ -56,7 +57,7 @@ private:
AABB Box; AABB Box;
bool Checked; bool Checked;
}; };
OctChild* m_Root; Child* m_Root;
std::vector<ContainedObject> m_StaticObjects; std::vector<ContainedObject> m_StaticObjects;
std::vector<ContainedObject> m_DynamicObjects; std::vector<ContainedObject> m_DynamicObjects;
@@ -67,16 +68,16 @@ private:
void falsifyObjectChecks(); void falsifyObjectChecks();
struct OctChild struct Child
{ {
~OctChild(); ~Child();
OctChild(const AABB& octTreeBounds, Child(const AABB& octTreeBounds,
int subDivisions, int subDivisions,
std::vector<OctTree::ContainedObject>& staticObjects, std::vector<Octree::ContainedObject>& staticObjects,
std::vector<OctTree::ContainedObject>& dynamicObjects); std::vector<Octree::ContainedObject>& dynamicObjects);
OctChild(const OctChild& other) = delete; Child(const Child& other) = delete;
OctChild(const OctChild&& other) = delete; Child(const Child&& other) = delete;
OctChild& operator= (const OctChild& other) = delete; Child& operator= (const Child& other) = delete;
void AddDynamicObject(const AABB& box); void AddDynamicObject(const AABB& box);
void AddStaticObject(const AABB& box); void AddStaticObject(const AABB& box);
void BoxesInSameRegion(const AABB& box, std::vector<AABB>& outBoxes) const; void BoxesInSameRegion(const AABB& box, std::vector<AABB>& outBoxes) const;
@@ -85,14 +86,14 @@ private:
bool RayCollides(const Ray& ray, Output& data) const; bool RayCollides(const Ray& ray, Output& data) const;
bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) const; bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) const;
OctChild* m_Children[8]; Child* m_Children[8];
//Indices into the lists in OctTree. //Indices into the lists in Octree.
std::vector<int> m_StaticObjIndices; std::vector<int> m_StaticObjIndices;
std::vector<int> m_DynamicObjIndices; std::vector<int> m_DynamicObjIndices;
AABB m_Box; AABB m_Box;
//Reference to the lists in OctTree. //Reference to the lists in Octree.
std::vector<OctTree::ContainedObject>& m_StaticObjectsRef; std::vector<Octree::ContainedObject>& m_StaticObjectsRef;
std::vector<OctTree::ContainedObject>& m_DynamicObjectsRef; std::vector<Octree::ContainedObject>& m_DynamicObjectsRef;
inline bool hasChildren() const; inline bool hasChildren() const;
int childIndexContainingPoint(const glm::vec3& point) const; int childIndexContainingPoint(const glm::vec3& point) const;
+10 -9
View File
@@ -3,6 +3,7 @@
#include "EventBroker.h" #include "EventBroker.h"
#include "World.h" #include "World.h"
#include "EntityWrapper.h"
#include "ComponentWrapper.h" #include "ComponentWrapper.h"
class System class System
@@ -10,6 +11,9 @@ class System
friend class SystemPipeline; friend class SystemPipeline;
protected: protected:
System()
: m_EventBroker(nullptr)
{ }
System(EventBroker* eventBroker) System(EventBroker* eventBroker)
: m_EventBroker(eventBroker) : m_EventBroker(eventBroker)
{ } { }
@@ -18,30 +22,27 @@ protected:
EventBroker* m_EventBroker; EventBroker* m_EventBroker;
}; };
class PureSystem : public System class PureSystem : public virtual System
{ {
friend class SystemPipeline; friend class SystemPipeline;
protected: protected:
PureSystem(EventBroker* eventBroker, std::string componentType) PureSystem(std::string componentType)
: System(eventBroker) : m_ComponentType(componentType)
, m_ComponentType(componentType)
{ } { }
virtual ~PureSystem() = default; virtual ~PureSystem() = default;
const std::string m_ComponentType; const std::string m_ComponentType;
virtual void UpdateComponent(World* world, ComponentWrapper& component, double dt) = 0; virtual void UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt) = 0;
}; };
class ImpureSystem : public System class ImpureSystem : public virtual System
{ {
friend class SystemPipeline; friend class SystemPipeline;
protected: protected:
ImpureSystem(EventBroker* eventBroker) ImpureSystem() = default;
: System(eventBroker)
{ }
virtual ~ImpureSystem() = default; virtual ~ImpureSystem() = default;
virtual void Update(World* world, double dt) = 0; virtual void Update(World* world, double dt) = 0;
+8 -8
View File
@@ -32,8 +32,8 @@ public:
System* system = new T(m_EventBroker, args...); System* system = new T(m_EventBroker, args...);
group.Systems[typeid(T).name()] = system; group.Systems[typeid(T).name()] = system;
if (std::is_base_of<PureSystem, T>::value) { PureSystem* pureSystem = dynamic_cast<PureSystem*>(system);
PureSystem* pureSystem = static_cast<PureSystem*>(system); if (pureSystem != nullptr) {
if (!pureSystem->m_ComponentType.empty()) { if (!pureSystem->m_ComponentType.empty()) {
group.PureSystems[pureSystem->m_ComponentType].push_back(pureSystem); group.PureSystems[pureSystem->m_ComponentType].push_back(pureSystem);
} else { } else {
@@ -41,8 +41,8 @@ public:
} }
} }
if (std::is_base_of<ImpureSystem, T>::value) { ImpureSystem* impureSystem = dynamic_cast<ImpureSystem*>(system);
ImpureSystem* impureSystem = static_cast<ImpureSystem*>(system); if (impureSystem != nullptr) {
group.ImpureSystems.push_back(impureSystem); group.ImpureSystems.push_back(impureSystem);
} }
} }
@@ -56,6 +56,9 @@ public:
} }
// Update // Update
for (auto& system : group.ImpureSystems) {
system->Update(world, dt);
}
for (auto& pair : group.PureSystems) { for (auto& pair : group.PureSystems) {
const std::string& componentName = pair.first; const std::string& componentName = pair.first;
auto& systems = pair.second; auto& systems = pair.second;
@@ -65,13 +68,10 @@ public:
} }
for (auto& component : *pool) { for (auto& component : *pool) {
for (auto& system : systems) { for (auto& system : systems) {
system->UpdateComponent(world, component, dt); system->UpdateComponent(world, EntityWrapper(world, component.EntityID), component, dt);
} }
} }
} }
for (auto& system : group.ImpureSystems) {
system->Update(world, dt);
}
} }
} }
+7 -5
View File
@@ -21,19 +21,21 @@ public:
// 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, const std::string& componentType);
// Check if an entity has a component // Check if an entity has a component
bool HasComponent(EntityID entity, std::string componentType) const; bool HasComponent(EntityID entity, const 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, const std::string& componentType);
// Delete a component off an entity // Delete a component off an entity
void DeleteComponent(EntityID entity, std::string componentType); void DeleteComponent(EntityID entity, const 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(const std::string& componentType);
// Get entity parent // Get entity parent
EntityID GetParent(EntityID entity); EntityID GetParent(EntityID entity);
// Change the parent of an entity // Change the parent of an entity
void SetParent(EntityID entity, EntityID parent); void SetParent(EntityID entity, EntityID parent);
// Get children of an entity
const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> GetChildren(EntityID entity);
// Get all component pools // Get all component pools
const std::unordered_map<std::string, ComponentPool*>& GetComponentPools() const { return m_ComponentPools; } const std::unordered_map<std::string, ComponentPool*>& GetComponentPools() const { return m_ComponentPools; }
// Get the entity children map // Get the entity children map
+1
View File
@@ -1,6 +1,7 @@
#ifndef InputProxy_h__ #ifndef InputProxy_h__
#define InputProxy_h__ #define InputProxy_h__
#include <boost/tokenizer.hpp>
#include "../Common.h" #include "../Common.h"
#include "../Core/ResourceManager.h" #include "../Core/ResourceManager.h"
#include "../Core/ConfigFile.h" #include "../Core/ConfigFile.h"
@@ -0,0 +1,35 @@
#ifndef DirectionalLightJob_h__
#define DirectionalLightJob_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 DirectionalLightJob : RenderJob
{
DirectionalLightJob(ComponentWrapper transformComponent, ComponentWrapper directionalLightComponent, World* m_World)
: RenderJob()
{
Direction = glm::vec4(0,0,-1,0) * glm::inverse(Transform::AbsoluteOrientation(m_World, transformComponent.EntityID));
//Direction = glm::vec4((glm::vec3)directionalLightComponent["Direction"], 0.f);
Color = (glm::vec4)directionalLightComponent["Color"];
Intensity = (double)directionalLightComponent["Intensity"];
};
glm::vec4 Direction;
glm::vec4 Color;
float Intensity;
void CalculateHash() override
{
Hash = 0;
}
};
#endif
+9 -8
View File
@@ -46,8 +46,8 @@ private:
int m_NumberOfTiles = 0; int m_NumberOfTiles = 0;
struct Plane { struct Plane {
glm::vec3 Normal; glm::vec3 Normal = glm::vec3(0.f);
float d; float d = 0;
}; };
struct Frustum { struct Frustum {
@@ -56,20 +56,21 @@ private:
Frustum* m_Frustums; Frustum* m_Frustums;
//This should be a component //This should be a component
struct PointLight { struct LightSource {
glm::vec4 Position = glm::vec4(0.f); glm::vec4 Position = glm::vec4(0.f);
glm::vec4 Direction = glm::vec4(10.f);
glm::vec4 Color = glm::vec4(1.f); glm::vec4 Color = glm::vec4(1.f);
float Radius = 5.f; float Radius = 5.f;
float Intensity = 0.8f; float Intensity = 0.8f;
float Falloff = 0.3f; float Falloff = 0.3f;
float Padding = 1337; enum Type_t { Zero, Point, Directional, Spot } Type;
}; };
std::vector<PointLight> m_PointLights; std::vector<LightSource> m_LightSources;
struct LightGrid { struct LightGrid {
float Start; float Start = 0;
float Amount; float Amount = 0;
glm::vec2 Padding; glm::vec2 Padding = glm::vec2(1.f, 2.f);
}; };
LightGrid* m_LightGrid; LightGrid* m_LightGrid;
+4
View File
@@ -12,6 +12,7 @@
#include "../Core/ResourceManager.h" #include "../Core/ResourceManager.h"
#include "Camera.h" #include "Camera.h"
#include "../Core/World.h" #include "../Core/World.h"
#include "../Core/Transform.h"
struct ModelJob : RenderJob struct ModelJob : RenderJob
{ {
@@ -28,6 +29,9 @@ struct ModelJob : RenderJob
Matrix = matrix; Matrix = matrix;
Color = modelComponent["Color"]; Color = modelComponent["Color"];
Entity = modelComponent.EntityID; Entity = modelComponent.EntityID;
glm::vec3 abspos = Transform::AbsolutePosition(world, modelComponent.EntityID);
glm::vec3 worldpos = glm::vec3(camera->ViewMatrix() * glm::vec4(abspos, 1));
Depth = worldpos.z;
World = world; World = world;
}; };
+3
View File
@@ -12,6 +12,7 @@
#include "RenderJob.h" #include "RenderJob.h"
#include "ModelJob.h" #include "ModelJob.h"
#include "PointLightJob.h" #include "PointLightJob.h"
#include "DirectionalLightJob.h"
/* /*
@@ -53,12 +54,14 @@ struct RenderScene
::Camera* Camera; ::Camera* Camera;
std::list<std::shared_ptr<RenderJob>> ForwardJobs; std::list<std::shared_ptr<RenderJob>> ForwardJobs;
std::list<std::shared_ptr<RenderJob>> PointLightJobs; std::list<std::shared_ptr<RenderJob>> PointLightJobs;
std::list<std::shared_ptr<RenderJob>> DirectionalLightJobs;
Rectangle Viewport; Rectangle Viewport;
void Clear() void Clear()
{ {
ForwardJobs.clear(); ForwardJobs.clear();
PointLightJobs.clear(); PointLightJobs.clear();
DirectionalLightJobs.clear();
} }
}; };
+2 -1
View File
@@ -46,7 +46,8 @@ private:
void updateProjectionMatrix(ComponentWrapper& cameraComponent); void updateProjectionMatrix(ComponentWrapper& cameraComponent);
void fillModels(std::list<std::shared_ptr<RenderJob>>& jobs, World* world); void fillModels(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
void fillLight(std::list<std::shared_ptr<RenderJob>>& jobs, World* world); void fillPointLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
void fillDirectionalLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
EventRelay<RenderSystem, Events::InputCommand> m_EInputCommand; EventRelay<RenderSystem, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e); bool OnInputCommand(const Events::InputCommand& e);
+2 -4
View File
@@ -22,9 +22,8 @@
class Renderer : public IRenderer class Renderer : public IRenderer
{ {
public: public:
Renderer(EventBroker* eventBroker, World* world) Renderer(EventBroker* eventBroker)
: m_EventBroker(eventBroker) : m_EventBroker(eventBroker)
, m_World(world)
{ } { }
virtual void Initialize() override; virtual void Initialize() override;
@@ -36,7 +35,6 @@ public:
private: private:
//----------------------Variables----------------------// //----------------------Variables----------------------//
EventBroker* m_EventBroker; EventBroker* m_EventBroker;
World* m_World;
Texture* m_ErrorTexture; Texture* m_ErrorTexture;
Texture* m_WhiteTexture; Texture* m_WhiteTexture;
@@ -62,7 +60,7 @@ private:
void DrawScreenQuad(GLuint textureToDraw); void DrawScreenQuad(GLuint textureToDraw);
static bool DepthSort(const std::shared_ptr<RenderJob> &i, const std::shared_ptr<RenderJob> &j) { return (i->Depth < j->Depth); } 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 SortRenderJobsByDepth(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;
+18
View File
@@ -0,0 +1,18 @@
#ifndef ESpawnerSpawn_h__
#define ESpawnerSpawn_h__
#include "Core/Event.h"
#include "Core/EntityWrapper.h"
namespace Events
{
struct SpawnerSpawn : Event
{
EntityWrapper Spawner;
EntityWrapper Parent;
};
}
#endif
+3 -2
View File
@@ -14,12 +14,11 @@
#include "Core/EKeyDown.h" #include "Core/EKeyDown.h"
#include "Core/EntityFilePreprocessor.h" #include "Core/EntityFilePreprocessor.h"
#include "Core/SystemPipeline.h" #include "Core/SystemPipeline.h"
#include "RaptorCopterSystem.h"
#include "PlayerSystem.h"
#include "Editor/EditorSystem.h" #include "Editor/EditorSystem.h"
#include "Core/EntityFile.h" #include "Core/EntityFile.h"
#include "Rendering/RenderSystem.h" #include "Rendering/RenderSystem.h"
#include "Core/EntityFileParser.h" #include "Core/EntityFileParser.h"
#include "Core/Octree.h"
// Network // Network
#include <boost/thread.hpp> #include <boost/thread.hpp>
@@ -48,6 +47,8 @@ private:
InputProxy* m_InputProxy; InputProxy* m_InputProxy;
GUI::Frame* m_FrameStack; GUI::Frame* m_FrameStack;
World* m_World; World* m_World;
Octree* m_OctreeCollision;
Octree* m_OctreeFrustrumCulling;
SystemPipeline* m_SystemPipeline; SystemPipeline* m_SystemPipeline;
RenderFrame* m_RenderFrame; RenderFrame* m_RenderFrame;
// Network variables // Network variables
-33
View File
@@ -1,33 +0,0 @@
#ifndef PlayerSystem_h__
#define PlayerSystem_h__
#include <GLFW/glfw3.h>
#include <glm/common.hpp>
#include "Common.h"
#include "Core/System.h"
#include "Collision/ETrigger.h"
class PlayerSystem : public PureSystem
{
public:
PlayerSystem(EventBroker* eventBroker)
: PureSystem(eventBroker, "Player")
{
EVENT_SUBSCRIBE_MEMBER(m_ETouch, &PlayerSystem::OnTouch);
EVENT_SUBSCRIBE_MEMBER(m_EEnter, &PlayerSystem::OnEnter);
EVENT_SUBSCRIBE_MEMBER(m_ELeave, &PlayerSystem::OnLeave);
}
virtual void UpdateComponent(World* world, ComponentWrapper& player, double dt) override;
private:
float m_Speed = 5;
EventRelay<PlayerSystem, Events::TriggerEnter> m_EEnter;
bool OnEnter(const Events::TriggerEnter &event);
EventRelay<PlayerSystem, Events::TriggerTouch> m_ETouch;
bool PlayerSystem::OnTouch(const Events::TriggerTouch &event);
EventRelay<PlayerSystem, Events::TriggerLeave> m_ELeave;
bool PlayerSystem::OnLeave(const Events::TriggerLeave &event);
};
#endif
-16
View File
@@ -1,16 +0,0 @@
#include "Common.h"
#include "Core/System.h"
class RaptorCopterSystem : public PureSystem
{
public:
RaptorCopterSystem(EventBroker* eventBroker)
: PureSystem(eventBroker, "RaptorCopter")
{ }
virtual void UpdateComponent(World* world, ComponentWrapper& raptorCopter, double dt) override
{
ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform");
(glm::vec3&)transform["Orientation"] += (float)(double)raptorCopter["Speed"] * (float)dt * (glm::vec3)raptorCopter["Axis"];
}
};
@@ -6,9 +6,9 @@
#include "Common.h" #include "Common.h"
#include "Core/System.h" #include "Core/System.h"
#include "Core\EPlayerDamage.h"; #include "Core/EPlayerDamage.h"
#include "Core\EPlayerHealthPickup.h"; #include "Core/EPlayerHealthPickup.h"
#include "Core\EPlayerDeath.h"; #include "Core/EPlayerDeath.h"
#include <tuple> #include <tuple>
#include <vector> #include <vector>
@@ -19,7 +19,7 @@ public:
HealthSystem(EventBroker* eventBroker); HealthSystem(EventBroker* eventBroker);
//updatecomponent //updatecomponent
virtual void UpdateComponent(World* world, ComponentWrapper& health, double dt) override; virtual void UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt) override;
private: private:
//methods which will take care of specific events //methods which will take care of specific events
@@ -0,0 +1,14 @@
#include "Common.h"
#include "GLM.h"
#include "Core/System.h"
class PlayerMovementSystem : public PureSystem
{
public:
PlayerMovementSystem(EventBroker* eventBroker)
: System(eventBroker)
, PureSystem("Player")
{ }
virtual void UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt);
};
+18
View File
@@ -0,0 +1,18 @@
#include "Core/System.h"
#include "Input/EInputCommand.h"
#include "Systems/SpawnerSystem.h"
#include "Events/ESpawnerSpawn.h"
class PlayerSpawnSystem : public ImpureSystem
{
public:
PlayerSpawnSystem(EventBroker* eventBroker);
virtual void Update(World* world, double dt) override;
private:
EventRelay<PlayerSpawnSystem, Events::InputCommand> m_OnInputCommand;
bool OnInputCommand(const Events::InputCommand& e);
std::vector<int> m_SpawnRequests;
};
+17
View File
@@ -0,0 +1,17 @@
#include "Common.h"
#include "Core/System.h"
class RaptorCopterSystem : public PureSystem
{
public:
RaptorCopterSystem(EventBroker* eventBroker)
: System(eventBroker)
, PureSystem("RaptorCopter")
{ }
virtual void UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt) override
{
ComponentWrapper& transform = world->GetComponent(component.EntityID, "Transform");
(glm::vec3&)transform["Orientation"] += (float)(double)component["Speed"] * (float)dt * (glm::vec3)component["Axis"];
}
};
+25
View File
@@ -0,0 +1,25 @@
#ifndef SpawnerSystem_h__
#define SpawnerSystem_h__
#include <random>
#include "Common.h"
#include "GLM.h"
#include "Core/System.h"
#include "Events/ESpawnerSpawn.h"
#include "Core/Transform.h"
#include "Core/ResourceManager.h"
#include "Core/EntityFileParser.h"
class SpawnerSystem : public System
{
public:
SpawnerSystem(EventBroker* eventBroker);
static EntityWrapper Spawn(EntityWrapper spawner, EntityWrapper parent = EntityWrapper::Invalid);
private:
EventRelay<SpawnerSystem, Events::SpawnerSpawn> m_OnSpawnerSpawn;
bool OnSpawnerSpawn(Events::SpawnerSpawn& e);
};
#endif
+3 -1
View File
@@ -2,7 +2,9 @@
LogLevel=1 LogLevel=1
LoadMap= LoadMap=
EditorEnabled=false EditorEnabled=false
; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation.
; if false -> Use pool allocation.
DisableMemoryPool=false
[Video] [Video]
Fullscreen=false Fullscreen=false
+4 -4
View File
@@ -6,10 +6,10 @@ InvertPitch=false
MouseLeft=PrimaryFire MouseLeft=PrimaryFire
MouseX=Yaw MouseX=Yaw
MouseY=Pitch MouseY=Pitch
W=+Forward W=Forward,1
S=-Forward S=Forward,-1
D=+Right D=Right,1
A=-Right A=Right,-1
R=Reload R=Reload
Space=Jump Space=Jump
LeftControl=Crouch LeftControl=Crouch
+7 -1
View File
@@ -2,15 +2,21 @@
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="components" elementFormDefault="qualified"> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="components" elementFormDefault="qualified">
<xs:include schemaLocation="Components/Transform.xsd"/> <xs:include schemaLocation="Components/Transform.xsd"/>
<xs:include schemaLocation="Components/Physics.xsd"/>
<xs:include schemaLocation="Components/Model.xsd"/> <xs:include schemaLocation="Components/Model.xsd"/>
<xs:include schemaLocation="Components/Test.xsd"/>
<xs:include schemaLocation="Components/RaptorCopter.xsd"/> <xs:include schemaLocation="Components/RaptorCopter.xsd"/>
<xs:include schemaLocation="Components/Player.xsd"/> <xs:include schemaLocation="Components/Player.xsd"/>
<xs:include schemaLocation="Components/Camera.xsd"/> <xs:include schemaLocation="Components/Camera.xsd"/>
<xs:include schemaLocation="Components/AABB.xsd"/> <xs:include schemaLocation="Components/AABB.xsd"/>
<xs:include schemaLocation="Components/PointLight.xsd"/> <xs:include schemaLocation="Components/PointLight.xsd"/>
<xs:include schemaLocation="Components/DirectionalLight.xsd"/>
<xs:include schemaLocation="Components/Trigger.xsd"/> <xs:include schemaLocation="Components/Trigger.xsd"/>
<xs:include schemaLocation="Components/Health.xsd"/> <xs:include schemaLocation="Components/Health.xsd"/>
<xs:include schemaLocation="Components/Listener.xsd"/> <xs:include schemaLocation="Components/Listener.xsd"/>
<xs:include schemaLocation="Components/SoundEmitter.xsd"/> <xs:include schemaLocation="Components/SoundEmitter.xsd"/>
<xs:include schemaLocation="Components/Collidable.xsd"/>
<xs:include schemaLocation="Components/Spawner.xsd"/>
<xs:include schemaLocation="Components/SpawnPoint.xsd"/>
<xs:include schemaLocation="Components/PlayerSpawn.xsd"/>
<xs:include schemaLocation="Components/Team.xsd"/>
</xs:schema> </xs:schema>
+5 -4
View File
@@ -1,4 +1,5 @@
<c:AABB> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<BoxCenter X="0" Y="0" Z="0"/> <AABB xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="AABB.xsd">
<BoxSize X="1" Y="1" Z="1"/> <Origin X="0" Y="0" Z="0"/>
</c:AABB> <Size X="1" Y="1" Z="1"/>
</AABB>
+6 -2
View File
@@ -6,8 +6,12 @@
<xs:element name="AABB"> <xs:element name="AABB">
<xs:complexType> <xs:complexType>
<xs:all> <xs:all>
<xs:element name="BoxCenter" type="t:Vector" minOccurs="0"/> <xs:element name="Origin" type="t:Vector" minOccurs="0">
<xs:element name="BoxSize" type="t:Vector" minOccurs="0"/> <xs:annotation><xs:documentation>Middle point of the bounding box</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="Size" type="t:Vector" minOccurs="0">
<xs:annotation><xs:documentation>Size of the bounding box</xs:documentation></xs:annotation>
</xs:element>
</xs:all> </xs:all>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
+4 -3
View File
@@ -1,6 +1,7 @@
<c:Camera> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Camera xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Camera.xsd">
<Name>cam</Name> <Name>cam</Name>
<FOV>60.0</FOV> <FOV>45</FOV>
<NearClip>0.01</NearClip> <NearClip>0.01</NearClip>
<FarClip>5000</FarClip> <FarClip>5000</FarClip>
</c:Camera> </Camera>
+3 -1
View File
@@ -10,7 +10,9 @@
<xs:complexType> <xs:complexType>
<xs:all> <xs:all>
<xs:element name="Name" type="t:string" minOccurs="0"/> <xs:element name="Name" type="t:string" minOccurs="0"/>
<xs:element name="FOV" type="t:double" minOccurs="0"/> <xs:element name="FOV" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>Vertical Field of View in degrees</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="NearClip" type="t:double" minOccurs="0"/> <xs:element name="NearClip" type="t:double" minOccurs="0"/>
<xs:element name="FarClip" type="t:double" minOccurs="0"/> <xs:element name="FarClip" type="t:double" minOccurs="0"/>
</xs:all> </xs:all>
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Collidable xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Collidable.xsd">
</Collidable>
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="Collidable">
</xs:element>
</xs:schema>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<DirectionalLight xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="DirectionalLight.xsd">
<Color R="1" G="1" B="1" A="1"/>
<Intensity>0.8</Intensity>
<Visible>true</Visible>
</DirectionalLight>
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="DirectionalLight">
<xs:annotation>
<xs:documentation>A directional light that shines bright like the future.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="Color" type="t:Color" minOccurs="0"/>
<xs:element name="Intensity" type="t:double" minOccurs="0"/>
<xs:element name="Visible" type="t:bool" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
+3 -2
View File
@@ -1,4 +1,5 @@
<c:Health> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Health xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Health.xsd">
<Health>100</Health> <Health>100</Health>
<MaxHealth>100</MaxHealth> <MaxHealth>100</MaxHealth>
</c:Health> </Health>
+2 -3
View File
@@ -1,3 +1,2 @@
<c:Listener> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Listener xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Listener.xsd"/>
</c:Listener>
+3 -2
View File
@@ -1,5 +1,6 @@
<c:Model> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Model.xsd">
<Resource></Resource> <Resource></Resource>
<Color R="1" G="1" B="1" A="1"/> <Color R="1" G="1" B="1" A="1"/>
<Visible>true</Visible> <Visible>true</Visible>
</c:Model> </Model>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Physics xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Physics.xsd">
<Velocity X="0" Y="0" Z="0"/>
</Physics>
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="Physics">
<xs:annotation>
<xs:documentation>Physics stuff</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="Velocity" type="t:Vector" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
+3 -2
View File
@@ -1,7 +1,8 @@
<c:Player> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Player xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Player.xsd">
<Velocity X="0" Y="0" Z="0"/> <Velocity X="0" Y="0" Z="0"/>
<Forward>false</Forward> <Forward>false</Forward>
<Left>false</Left> <Left>false</Left>
<Back>false</Back> <Back>false</Back>
<Right>false</Right> <Right>false</Right>
</c:Player> </Player>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<PlayerSpawn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PlayerSpawn.xsd"/>
@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="PlayerSpawn">
<xs:annotation>
<xs:documentation>Combined with a Spawner and a Team component, defines a spawn point for a player team.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:schema>
+3 -2
View File
@@ -1,7 +1,8 @@
<c:PointLight> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<PointLight xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PointLight.xsd">
<Color R="1" G="1" B="1" A="1"/> <Color R="1" G="1" B="1" A="1"/>
<Radius>1.0</Radius> <Radius>1.0</Radius>
<Intensity>0.8</Intensity> <Intensity>0.8</Intensity>
<Falloff>0.3</Falloff> <Falloff>0.3</Falloff>
<Visible>true</Visible> <Visible>true</Visible>
</c:PointLight> </PointLight>
+8 -1
View File
@@ -12,7 +12,14 @@
<xs:element name="Color" type="t:Color" minOccurs="0"/> <xs:element name="Color" type="t:Color" minOccurs="0"/>
<xs:element name="Radius" type="t:double" minOccurs="0"/> <xs:element name="Radius" type="t:double" minOccurs="0"/>
<xs:element name="Intensity" type="t:double" minOccurs="0"/> <xs:element name="Intensity" type="t:double" minOccurs="0"/>
<xs:element name="Falloff" type="t:double" minOccurs="0" minInclusive="0" maxInclusive="1"/> <xs:element name="Falloff">
<xs:simpleType>
<xs:restriction base="t:double">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Visible" type="t:bool" minOccurs="0"/> <xs:element name="Visible" type="t:bool" minOccurs="0"/>
</xs:all> </xs:all>
</xs:complexType> </xs:complexType>
+3 -2
View File
@@ -1,4 +1,5 @@
<c:RaptorCopter> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<RaptorCopter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="RaptorCopter.xsd">
<Speed>0</Speed> <Speed>0</Speed>
<Axis X="0" Y="0" Z="0"/> <Axis X="0" Y="0" Z="0"/>
</c:RaptorCopter> </RaptorCopter>
+3 -2
View File
@@ -1,4 +1,5 @@
<c:SoundEmitter> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<SoundEmitter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="SoundEmitter.xsd">
<FilePath></FilePath> <FilePath></FilePath>
<Gain>1.0</Gain> <Gain>1.0</Gain>
<Pitch>1.0</Pitch> <Pitch>1.0</Pitch>
@@ -6,4 +7,4 @@
<MaxDistance>20.0</MaxDistance> <MaxDistance>20.0</MaxDistance>
<RollOffFactor>1.0</RollOffFactor> <RollOffFactor>1.0</RollOffFactor>
<ReferenceDistance>1.0</ReferenceDistance> <ReferenceDistance>1.0</ReferenceDistance>
</c:SoundEmitter> </SoundEmitter>
+18 -12
View File
@@ -7,18 +7,24 @@
<xs:complexType> <xs:complexType>
<xs:all> <xs:all>
<xs:element name="FilePath" type="t:string" minOccurs="0"/> <xs:element name="FilePath" type="t:string" minOccurs="0"/>
<xs:element name="Gain" type="t:double" minOccurs="0"/> <xs:element name="Gain" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>The "volume" of the emitter. A value betweeen 0-1</xs:documentation></xs:annotation> <xs:annotation><xs:documentation>The "volume" of the emitter. A value betweeen 0-1</xs:documentation></xs:annotation>
<xs:element name="Pitch" type="t:double" minOccurs="0"/> </xs:element>
<xs:annotation><xs:documentation>The pitch of the emitter. A value betweeen 0-1</xs:documentation></xs:annotation> <xs:element name="Pitch" type="t:double" minOccurs="0">
<xs:element name="Loop" type="t:bool" minOccurs="0"/> <xs:annotation><xs:documentation>The pitch of the emitter. A value betweeen 0-1</xs:documentation></xs:annotation>
<xs:annotation><xs:documentation>If the sound should loop or not.</xs:documentation></xs:annotation> </xs:element>
<xs:element name="MaxDistance" type="t:double" minOccurs="0"/> <xs:element name="Loop" type="t:bool" minOccurs="0">
<xs:annotation><xs:documentation>The distance where there will no longer be any attenuation.</xs:documentation></xs:annotation> <xs:annotation><xs:documentation>If the sound should loop or not.</xs:documentation></xs:annotation>
<xs:element name="RollOffFactor" type="t:double" minOccurs="0"/> </xs:element>
<xs:annotation><xs:documentation>The rolloff rate of the source.</xs:documentation></xs:annotation> <xs:element name="MaxDistance" type="t:double" minOccurs="0">
<xs:element name="ReferenceDistance" type="t:double" minOccurs="0"/> <xs:annotation><xs:documentation>The distance where there will no longer be any attenuation.</xs:documentation></xs:annotation>
<xs:annotation><xs:documentation>The distance that the source will be the loudest.</xs:documentation></xs:annotation> </xs:element>
<xs:element name="RollOffFactor" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>The rolloff rate of the source.</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="ReferenceDistance" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>The distance that the source will be the loudest.</xs:documentation></xs:annotation>
</xs:element>
</xs:all> </xs:all>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<SpawnPoint xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="SpawnPoint.xsd"/>
@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="SpawnPoint">
<xs:annotation>
<xs:documentation>Defines this entity as a spawn point for a parent Spawner</xs:documentation>
</xs:annotation>
</xs:element>
</xs:schema>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Spawner xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Spawner.xsd">
<EntityFile></EntityFile>
</Spawner>
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="Spawner">
<xs:annotation>
<xs:documentation>Randomly selects a child SpawnPoint component and spawns a copy of an entity template when receiving a SpawnerSpawn event. If no SpawnPoint is found it spawns from its own position.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="EntityFile" type="t:string" minOccurs="0">
<xs:annotation><xs:documentation>The entity template to spawn</xs:documentation></xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Team xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Team.xsd">
<Team><Spectator/></Team>
</Team>
+28
View File
@@ -0,0 +1,28 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:complexType name="TeamEnum" mixed="true">
<xs:complexContent>
<xs:extension base="t:enum">
<xs:choice>
<xs:element name="Spectator" type="xs:integer" fixed="1" minOccurs="0"/>
<xs:element name="Red" type="xs:integer" fixed="2" minOccurs="0"/>
<xs:element name="Blue" type="xs:integer" fixed="3" minOccurs="0"/>
</xs:choice>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="Team">
<xs:annotation>
<xs:documentation>Represents entity team affiliation</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="Team" type="TeamEnum" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
+3 -2
View File
@@ -1,5 +1,6 @@
<c:Transform> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Transform xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Transform.xsd">
<Position X="0" Y="0" Z="0"/> <Position X="0" Y="0" Z="0"/>
<Orientation X="0" Y="0" Z="0"/> <Orientation X="0" Y="0" Z="0"/>
<Scale X="1" Y="1" Z="1"/> <Scale X="1" Y="1" Z="1"/>
</c:Transform> </Transform>
+3 -2
View File
@@ -1,2 +1,3 @@
<c:Trigger> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
</c:Trigger> <Trigger xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Trigger.xsd">
</Trigger>
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Transform/>
</Components>
<Children>
<Entity>
<Components>
<c:AABB/>
<c:Collidable>
<Static>false</Static>
</c:Collidable>
<c:Transform>
<Position X="1.5" Y="0" Z="-7"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Collidable>
<Static>false</Static>
</c:Collidable>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Color A="1" B="0" G="1" R="0"/>
</c:Model>
<c:Transform>
<Position X="2" Y="0" Z="-7"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
+52 -2
View File
@@ -13,6 +13,7 @@
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Scale X="100" Y="1" Z="100"/> <Scale X="100" Y="1" Z="100"/>
<Orientation X="0" Y="2.59200001" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children/> <Children/>
@@ -45,9 +46,58 @@
<Entity> <Entity>
<Components> <Components>
<c:Camera/> <c:Camera/>
<c:Listener/>
<c:Transform> <c:Transform>
<Position X="5.85247707" Y="3.8454349" Z="-1.14486957"/> <Position X="1.36896265" Y="4.4259491" Z="10.6640663"/>
<Orientation X="2.51327395" Y="1.23916209" Z="-3.1415925"/> <Orientation X="-0.0349078141" Y="0.157154545" Z="-2.60252193e-07"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:DirectionalLight/>
<c:Model>
<Resource>Models/DirectionalLightWidget.obj</Resource>
</c:Model>
<c:Transform>
<Position X="2.1529963" Y="6.59221172" Z="0.169116676"/>
<Orientation X="4.32000017" Y="4.6340003" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource>Models/Assault.obj</Resource>
</c:Model>
<c:Transform>
<Position X="-2.00568962" Y="0.527161121" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:Model>
<Resource>Models/SecondaryWeapon.fbx</Resource>
</c:Model>
<c:Transform>
<Position X="-0.546139359" Y="0.853016734" Z="0.177482292"/>
<Orientation X="1.47266471" Y="0.524984181" Z="1.243698"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="3.70000029" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children/> <Children/>
+5 -1
View File
@@ -1,6 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd" xmlns:c="components"> <Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components> <Components>
<c:Transform/> <c:Transform/>
</Components> </Components>
<Children/>
</Entity> </Entity>
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Transform/>
</Components>
<Children>
<Entity>
<Components>
<c:Camera/>
<c:Transform/>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:AABB/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Color A="1" B="0.513725519" G="0" R="1"/>
</c:Model>
<c:Transform>
<Position X="0" Y="2" Z="0"/>
<Scale X="5" Y="1" Z="5"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="Player">
<Components>
<c:AABB>
<Origin X="0" Y="0.773000062" Z="0"/>
<Size X="1" Y="1.60000002" Z="1"/>
</c:AABB>
<c:Collidable/>
<c:Physics/>
<c:Model>
<Resource>Models/Assault.obj</Resource>
<Color A="1" B="1" G="0" R="0"/>
</c:Model>
<c:Player/>
<c:Transform>
<Position X="0" Y="2.52699995" Z="0.0542778969"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:AABB/>
<c:Collidable/>
<c:Physics>
<Velocity X="0" Y="-0.0934068039" Z="0"/>
</c:Physics>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Color A="1" B="0" G="1" R="1"/>
</c:Model>
<c:Player/>
<c:Transform>
<Position X="0" Y="4.15580511" Z="0"/>
<Scale X="0.704558551" Y="0.115156889" Z="1"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
+56
View File
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Transform/>
</Components>
<Children>
<Entity>
<Components>
<c:AABB/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Color A="1" B="1" G="0" R="0"/>
</c:Model>
<c:Transform>
<Position X="-2" Y="0" Z="-7"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:AABB/>
<c:Collidable>
<Static>false</Static>
</c:Collidable>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Color A="1" B="0" G="0" R="1"/>
</c:Model>
<c:Transform>
<Position X="1.5" Y="0" Z="-7"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Collidable>
<Static>false</Static>
</c:Collidable>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Color A="1" B="0" G="1" R="0"/>
</c:Model>
<c:Transform>
<Position X="2" Y="0" Z="-7"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity name="Player" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:AABB/>
<c:Physics/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Color A="1" B="1" G="0" R="0"/>
</c:Model>
<c:Player/>
<c:Transform/>
</Components>
<Children/>
</Entity>
+64
View File
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Transform/>
</Components>
<Children>
<Entity>
<Components>
<c:PlayerSpawn/>
<c:Spawner>
<EntityFile>Schema/Entities/Player.xml</EntityFile>
</c:Spawner>
<c:Team>
<Team>2</Team>
</c:Team>
<c:Transform>
<Position X="11.2723322" Y="1.28011799" Z="3.66820574"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:SpawnPoint/>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="0" Z="1.26689196"/>
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:SpawnPoint/>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="0" Z="-1.14786315"/>
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity>
<Components>
<c:Camera/>
<c:Listener/>
<c:Transform>
<Position X="-0.123331964" Y="7.64918661" Z="6.59480286"/>
<Orientation X="-0.500915647" Y="-1.35800648" Z="-7.76194497e-07"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Team>
<Team>3</Team>
</c:Team>
<c:Transform/>
</Components>
<Children/>
</Entity>
+3
View File
@@ -4,6 +4,9 @@
<xs:include schemaLocation="Types/Quaternion.xsd"/> <xs:include schemaLocation="Types/Quaternion.xsd"/>
<xs:include schemaLocation="Types/Vector.xsd"/> <xs:include schemaLocation="Types/Vector.xsd"/>
<xs:include schemaLocation="Types/Color.xsd"/> <xs:include schemaLocation="Types/Color.xsd"/>
<xs:complexType name="enum" mixed="true">
<xs:choice></xs:choice>
</xs:complexType>
<xs:simpleType name="bool"> <xs:simpleType name="bool">
<xs:restriction base="xs:boolean"></xs:restriction> <xs:restriction base="xs:boolean"></xs:restriction>
</xs:simpleType> </xs:simpleType>
+10 -1
View File
@@ -11,14 +11,23 @@
<xs:complexType> <xs:complexType>
<xs:all> <xs:all>
<xs:element ref="c:Transform" minOccurs="0"/> <xs:element ref="c:Transform" minOccurs="0"/>
<xs:element ref="c:Physics" minOccurs="0"/>
<xs:element ref="c:Model" minOccurs="0"/> <xs:element ref="c:Model" minOccurs="0"/>
<xs:element ref="c:Test" minOccurs="0"/>
<xs:element ref="c:RaptorCopter" minOccurs="0"/> <xs:element ref="c:RaptorCopter" minOccurs="0"/>
<xs:element ref="c:Player" minOccurs="0"/> <xs:element ref="c:Player" minOccurs="0"/>
<xs:element ref="c:Camera" minOccurs="0"/>
<xs:element ref="c:AABB" minOccurs="0"/>
<xs:element ref="c:Trigger" minOccurs="0"/>
<xs:element ref="c:Health" minOccurs="0"/> <xs:element ref="c:Health" minOccurs="0"/>
<xs:element ref="c:PointLight" minOccurs="0"/> <xs:element ref="c:PointLight" minOccurs="0"/>
<xs:element ref="c:Listener" minOccurs="0"/> <xs:element ref="c:Listener" minOccurs="0"/>
<xs:element ref="c:SoundEmitter" minOccurs="0"/> <xs:element ref="c:SoundEmitter" minOccurs="0"/>
<xs:element ref="c:Collidable" minOccurs="0"/>
<xs:element ref="c:Spawner" minOccurs="0"/>
<xs:element ref="c:SpawnPoint" minOccurs="0"/>
<xs:element ref="c:PlayerSpawn" minOccurs="0"/>
<xs:element ref="c:Team" minOccurs="0"/>
<xs:element ref="c:DirectionalLight" minOccurs="0"/>
</xs:all> </xs:all>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
+16 -13
View File
@@ -27,19 +27,20 @@ layout (std430, binding = 0) buffer FrustumBuffer
Frustum Data[]; Frustum Data[];
} Frustums; } Frustums;
struct PointLight { struct LightSource {
vec4 Position; vec4 Position;
vec4 Direction;
vec4 Color; vec4 Color;
float Radius; float Radius;
float Intensity; float Intensity;
float Falloff; float Falloff;
float Padding; int Type;
}; };
layout (std430, binding = 1) buffer LightBuffer layout (std430, binding = 1) buffer LightBuffer
{ {
PointLight List[]; LightSource List[];
} PointLights; } LightSources;
struct LightGrid { struct LightGrid {
float Start; float Start;
@@ -106,8 +107,7 @@ layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main () void main ()
{ {
GroupIndex = int(gl_WorkGroupID.x + (gl_WorkGroupID.y * int(ScreenDimensions.x/TILE_SIZE))); GroupIndex = int(gl_WorkGroupID.x + (gl_WorkGroupID.y * int(ScreenDimensions.x/TILE_SIZE)));
if(gl_LocalInvocationIndex == 0) if(gl_LocalInvocationIndex == 0) {
{
GroupLightCount = 0; GroupLightCount = 0;
GroupFrustum = Frustums.Data[GroupIndex]; GroupFrustum = Frustums.Data[GroupIndex];
} }
@@ -115,22 +115,25 @@ void main ()
barrier(); barrier();
memoryBarrierShared(); memoryBarrierShared();
for(int i = int(gl_LocalInvocationIndex); i < PointLights.List.length(); i += TILE_SIZE*TILE_SIZE) for(int i = int(gl_LocalInvocationIndex); i < LightSources.List.length(); i += TILE_SIZE*TILE_SIZE) {
{ LightSource light = LightSources.List[i];
PointLight light = PointLights.List[i];
//if pointlight //if pointlight
//Pos i view antagligen //Pos i view antagligen
if(SphereInsideFrustrum( vec3(V * light.Position), light.Radius, GroupFrustum)) if(light.Type == 1) {
{ if(SphereInsideFrustrum( vec3(V * light.Position), light.Radius, GroupFrustum)) {
//TODO: Fix transparent and opaque list, and depth test. //TODO: Fix transparent and opaque list, and depth test.
AppendLight( i ); AppendLight( i );
}
} }
//if conelight //if conelight
//if directional //if directional
if(light.Type == 2) {
AppendLight( i );
}
} }
+38 -19
View File
@@ -9,19 +9,20 @@ uniform sampler2D texture0;
#define TILE_SIZE 16 #define TILE_SIZE 16
struct PointLight { struct LightSource {
vec4 Position; vec4 Position;
vec4 Direction;
vec4 Color; vec4 Color;
float Radius; float Radius;
float Intensity; float Intensity;
float Falloff; float Falloff;
float Padding; int Type;
}; };
layout (std430, binding = 1) buffer LightBuffer layout (std430, binding = 1) buffer LightBuffer
{ {
PointLight List[]; LightSource List[];
} PointLights; } LightSources;
struct LightGrid { struct LightGrid {
float Start; float Start;
@@ -70,7 +71,7 @@ vec4 CalcDiffuse(vec4 lightColor, vec4 lightVec, vec4 normal) {
return lightColor * power; return lightColor * power;
} }
LightResult CalcPointLight(vec4 lightPos, float lightRadius, vec4 lightColor, float intensity, vec4 viewVec, vec4 position, vec4 normal, float falloff) LightResult CalcPointLightSource(vec4 lightPos, float lightRadius, vec4 lightColor, float intensity, vec4 viewVec, vec4 position, vec4 normal, float falloff)
{ {
vec4 L = lightPos - position; vec4 L = lightPos - position;
float dist = length(L); float dist = length(L);
@@ -84,6 +85,16 @@ LightResult CalcPointLight(vec4 lightPos, float lightRadius, vec4 lightColor, fl
return result; return result;
} }
LightResult CalcDirectionalLightSource(vec4 direction, vec4 color, float intensity, vec4 viewVec, vec4 vertNormal)
{
vec4 L = normalize( -vec4(direction.xyz, 0) );
LightResult result;
result.Diffuse = CalcDiffuse(color, L, vertNormal) * intensity;
result.Specular = CalcSpecular(color, viewVec, L, vertNormal) * intensity;
return result;
}
void main() void main()
{ {
@@ -93,8 +104,8 @@ void main()
vec4 viewVec = normalize(-position); vec4 viewVec = normalize(-position);
vec2 tilePos; vec2 tilePos;
tilePos.x = int(gl_FragCoord.x/16); tilePos.x = int(gl_FragCoord.x/TILE_SIZE);
tilePos.y = int(gl_FragCoord.y/16); tilePos.y = int(gl_FragCoord.y/TILE_SIZE);
LightResult totalLighting; LightResult totalLighting;
totalLighting.Diffuse = scene_ambient; totalLighting.Diffuse = scene_ambient;
@@ -102,29 +113,37 @@ void main()
int start = int(LightGrids.Data[currentTile].Start); int start = int(LightGrids.Data[currentTile].Start);
int amount = int(LightGrids.Data[currentTile].Amount); int amount = int(LightGrids.Data[currentTile].Amount);
//for(int i = 0; i < 3; i++)
for(int i = start; i < start + amount; i++) for(int i = start; i < start + amount; i++) {
{
int l = int(LightIndex[i]); int l = int(LightIndex[i]);
LightSource light = LightSources.List[l];
LightResult result = CalcPointLight(V * PointLights.List[l].Position, PointLights.List[l].Radius, PointLights.List[l].Color, PointLights.List[l].Intensity, viewVec, position, normal, PointLights.List[i].Falloff); LightResult result;
if(light.Type == 1) { // point
result = CalcPointLightSource(V * light.Position, light.Radius, light.Color, light.Intensity, viewVec, position, normal, light.Falloff);
} else if (light.Type == 2) { //Directional
result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal);
}
totalLighting.Diffuse += result.Diffuse; totalLighting.Diffuse += result.Diffuse;
totalLighting.Specular += result.Specular; totalLighting.Specular += result.Specular;
} }
fragmentColor += (totalLighting.Diffuse + totalLighting.Specular) * texel * Color; fragmentColor += (totalLighting.Diffuse + totalLighting.Specular) * texel * Color;
//fragmentColor += Input.DiffuseColor;
//fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse) * texel * Color; //fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse) * texel * Color;
//fragmentColor += vec4(0.0, LightGrids.Data[currentTile].Amount/3.0, 0, 1); //fragmentColor += Input.DiffuseColor + vec4(0.0, LightGrids.Data[currentTile].Amount/3, 0, 1);
//fragmentColor = texel * Input.DiffuseColor * Color; //fragmentColor = texel * Input.DiffuseColor * Color;
if(int(gl_FragCoord.x)%16 == 0 || int(gl_FragCoord.y)%16 == 0 ) //fragmentColor += vec4(currentTile/3600.f, 0, 0, 1);
{
//fragmentColor += vec4(0.5, 0, 0, 0); //Tiled Debug Code
/*
if(int(gl_FragCoord.x)%16 == 0 || int(gl_FragCoord.y)%16 == 0 ) {
fragmentColor += vec4(0.5, 0, 0, 0);
} else { } else {
//fragmentColor += vec4(LightGrids.Data[int(tilePos.x + tilePos.y*80)].Amount/3.0, 0, 0, 1); fragmentColor += vec4(LightGrids.Data[int(tilePos.x + tilePos.y*80)].Amount/LightSources.List.length(), 0, 0, 1);
} }
*/
} }
+1 -1
View File
@@ -24,5 +24,5 @@ void main()
Output.Position = Position; Output.Position = Position;
Output.TextureCoordinate = TextureCoords; Output.TextureCoordinate = TextureCoords;
Output.Normal = Normal; Output.Normal = vec3(M * vec4(Normal, 0.0));
} }
@@ -0,0 +1,18 @@
#include "Collision/CollidableOctreeSystem.h"
void CollidableOctreeSystem::Update(World* world, double dt)
{
m_Octree->ClearDynamicObjects();
}
void CollidableOctreeSystem::UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt)
{
if (entity.HasComponent("AABB")) {
boost::optional<AABB> absoluteAABB = Collision::EntityAbsoluteAABB(entity);
if (absoluteAABB) {
m_Octree->AddDynamicObject(*absoluteAABB);
}
} else if (entity.HasComponent("Model")) {
// TODO: Derive AABB from model
}
}
+56 -38
View File
@@ -13,7 +13,7 @@ bool RayAABBIntr(const Ray& ray, const AABB& box)
{ {
glm::vec3 w = 75.0f * ray.Direction(); glm::vec3 w = 75.0f * ray.Direction();
glm::vec3 v = glm::abs(w); glm::vec3 v = glm::abs(w);
glm::vec3 c = ray.Origin() - box.Center() + w; glm::vec3 c = ray.Origin() - box.Origin() + w;
glm::vec3 half = box.HalfSize(); glm::vec3 half = box.HalfSize();
if (abs(c.x) > v.x + half.x) { if (abs(c.x) > v.x + half.x) {
@@ -68,8 +68,8 @@ bool RayVsAABB(const Ray& ray, const AABB& box, float& outDistance)
bool AABBVsAABB(const AABB& a, const AABB& b) bool AABBVsAABB(const AABB& a, const AABB& b)
{ {
const glm::vec3& aCenter = a.Center(); const glm::vec3& aCenter = a.Origin();
const glm::vec3& bCenter = b.Center(); const glm::vec3& bCenter = b.Origin();
const glm::vec3& aHSize = a.HalfSize(); const glm::vec3& aHSize = a.HalfSize();
const glm::vec3& bHSize = b.HalfSize(); const glm::vec3& bHSize = b.HalfSize();
//Test will probably exit because of the X and Z axes more often, so test them first. //Test will probably exit because of the X and Z axes more often, so test them first.
@@ -199,11 +199,51 @@ bool RayVsModel(const Ray& ray,
return hit; return hit;
} }
bool AABBvsTriangles(const AABB& box, const std::vector<RawModel::Vertex>& modelVertices, const std::vector<unsigned int>& modelIndices, const glm::mat4& modelMatrix, glm::vec3& outResolutionVector)
{
bool hit = false;
const glm::vec3& origin = box.Origin();
const glm::vec3& min = box.MinCorner();
const glm::vec3& max = box.MaxCorner();
outResolutionVector.x = INFINITY;
for (int i = 0; i < modelIndices.size(); ++i) {
glm::vec3 p = modelVertices[i].Position;
p = glm::vec3(modelMatrix * glm::vec4(p.x, p.y, p.z, 1));
float distFromOrigin = glm::abs(origin.x - p.x);
float penetration = box.HalfSize().x - distFromOrigin;
if (penetration > 0 && penetration < glm::abs(outResolutionVector.x)) {
if (p.x > origin.x) {
outResolutionVector.x = -penetration;
} else {
outResolutionVector.x = penetration;
}
hit = true;
}
//glm::vec3 pLocal = origin - p;
//for (int axis = 0; axis < 3; ++axis) {
// if (p[axis] < min[axis] || p[axis] > max[axis]) {
// continue;
// }
// if (glm::abs(pLocal[axis]) < box.HalfSize()[axis]) {
// outResolutionVector[axis] = (glm::sign(pLocal[axis]) * box.HalfSize()[axis]) - pLocal[axis];
// hit = true;
// }
//}
}
return hit;
}
bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon) bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon)
{ {
const glm::vec3& ma1 = first.MaxCorner(); const glm::vec3& ma1 = first.MaxCorner();
const glm::vec3& ma2 = first.MaxCorner(); const glm::vec3& ma2 = second.MaxCorner();
const glm::vec3& mi1 = second.MinCorner(); const glm::vec3& mi1 = first.MinCorner();
const glm::vec3& mi2 = second.MinCorner(); const glm::vec3& mi2 = second.MinCorner();
return (std::abs(ma1.x - ma2.x) < epsilon) && return (std::abs(ma1.x - ma2.x) < epsilon) &&
(std::abs(mi1.x - mi2.x) < epsilon) && (std::abs(mi1.x - mi2.x) < epsilon) &&
@@ -238,45 +278,23 @@ bool attachAABBComponentFromModel(World* world, EntityID id)
mini.y = std::min(wPos.y, mini.y); mini.y = std::min(wPos.y, mini.y);
mini.z = std::min(wPos.z, mini.z); mini.z = std::min(wPos.z, mini.z);
} }
collision["BoxCenter"] = 0.5f * (maxi + mini); collision["Origin"] = 0.5f * (maxi + mini);
collision["BoxSize"] = maxi - mini; collision["Size"] = maxi - mini;
return true; return true;
} }
bool GetEntityBox(World* world, ComponentWrapper& AABBComponent, AABB& outBox) boost::optional<AABB> EntityAbsoluteAABB(EntityWrapper& entity)
{ {
ComponentWrapper& cTrans = world->GetComponent(AABBComponent.EntityID, "Transform"); if (!entity.HasComponent("AABB")) {
ComponentWrapper model = world->GetComponent(AABBComponent.EntityID, "Model"); return boost::none;
Model* modelRes = ResourceManager::Load<Model>(model["Resource"]);
outBox.CreateFromCenter(AABBComponent["BoxCenter"], AABBComponent["BoxSize"]);
glm::vec3 mini = outBox.MinCorner();
glm::vec3 maxi = outBox.MaxCorner();
if (modelRes == nullptr) {
return false;
}
glm::mat4 modelMatrix = modelRes->Matrix() *
glm::translate(glm::mat4(), (glm::vec3)cTrans["Position"]) *
glm::scale((glm::vec3)cTrans["Scale"]);
outBox = AABB(modelMatrix * glm::vec4(mini.x, mini.y, mini.z, 1),
modelMatrix * glm::vec4(maxi.x, maxi.y, maxi.z, 1));
return true;
}
bool GetEntityBox(World* world, EntityID entity, AABB& outBox, bool forceBoxFromModel)
{
if (!world->HasComponent(entity, "AABB")) {
if (forceBoxFromModel) {
if (!attachAABBComponentFromModel(world, entity))
return false;
} else {
return false;
}
} }
ComponentWrapper& cBox = world->GetComponent(entity, "AABB"); ComponentWrapper& cAABB = entity["AABB"];
return GetEntityBox(world, cBox, outBox); glm::vec3 absPosition = Transform::AbsolutePosition(entity.World, entity.ID);
glm::vec3 absScale = Transform::AbsoluteScale(entity.World, entity.ID);
glm::vec3 origin = absPosition + (glm::vec3)cAABB["Origin"];
glm::vec3 size = (glm::vec3)cAABB["Size"] * absScale;
return AABB::FromOriginSize(origin, size);
} }
} }
+43 -16
View File
@@ -2,33 +2,60 @@
#include "Collision/CollisionSystem.h" #include "Collision/CollisionSystem.h"
#include "Core/AABB.h" #include "Core/AABB.h"
void CollisionSystem::UpdateComponent(World * world, ComponentWrapper & cAABB, double dt) void CollisionSystem::UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt)
{ {
//Right now, cAABB is a component attached to any entity that should be collideable. if (!entity.HasComponent("Physics")) {
AABB thisBox;
if (!Collision::GetEntityBox(world, cAABB, thisBox)) {
return; return;
} }
ComponentWrapper& cPhysics = entity["Physics"];
boost::optional<AABB> boundingBox = Collision::EntityAbsoluteAABB(entity);
if (!boundingBox) {
return;
}
ComponentWrapper& cTransform = entity["Transform"];
AABB& boxA = *boundingBox;
//Press 'Z' to enable/disable collision. //Press 'Z' to enable/disable collision.
if (zPress) { if (zPress) {
return; return;
} }
//Here, mover should be an object that moves, currently only players.
for (auto& mover : *world->GetComponents("Player")) { // Collide against octree
if (cAABB.EntityID == mover.EntityID) { std::vector<AABB> octreeResult;
m_Octree->BoxesInSameRegion(*boundingBox, octreeResult);
for (auto& boxB : octreeResult) {
glm::vec3 resolutionVector;
if (Collision::IsSameBoxProbably(boxA, boxB)) {
continue; continue;
} }
AABB otherBox; if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
if (!Collision::GetEntityBox(world, mover.EntityID, otherBox)) { (glm::vec3&)cTransform["Position"] += resolutionVector;
continue; cPhysics["Velocity"] = glm::vec3(0, 0, 0);
}
glm::vec3 resolveTranslation;
if (Collision::AABBVsAABB(otherBox, thisBox, resolveTranslation)) {
ComponentWrapper& trans = world->GetComponent(mover.EntityID, "Transform");
//TODO: Special treatment if both are movers.
trans["Position"] = (glm::vec3)trans["Position"] + resolveTranslation;
} }
} }
// HACK: Temporarily collide against all collidable models since they're not in the octree yet
//auto otherCollidables = world->GetComponents("Model");
//for (auto& cModel : *otherCollidables) {
// if (cModel.EntityID == entity) {
// continue;
// }
// if (!world->HasComponent(cModel.EntityID, "Collidable")) {
// continue;
// }
// auto absPosition = RenderQueueFactory::AbsolutePosition(world, cModel.EntityID);
// auto absOrientation = RenderQueueFactory::AbsoluteOrientation(world, cModel.EntityID);
// auto absScale = RenderQueueFactory::AbsoluteScale(world, cModel.EntityID);
// glm::mat4 modelMatrix = glm::translate(absPosition); // *glm::toMat4(absOrientation) * glm::scale(absScale);
// auto model = ResourceManager::Load<Model>(cModel["Resource"]);
// glm::vec3 resolutionVector;
// if (Collision::AABBvsTriangles(boxA, model->m_Vertices, model->m_Indices, modelMatrix, resolutionVector)) {
// (glm::vec3&)cTransform["Position"] += resolutionVector;
// }
//}
} }
bool CollisionSystem::OnKeyUp(const Events::KeyUp & event) bool CollisionSystem::OnKeyUp(const Events::KeyUp & event)
+27 -11
View File
@@ -3,27 +3,27 @@
#include "Core/AABB.h" #include "Core/AABB.h"
#include "Rendering/Model.h" #include "Rendering/Model.h"
void TriggerSystem::UpdateComponent(World* world, ComponentWrapper& trigger, double dt) void TriggerSystem::UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt)
{ {
//Currently only players can trigger things. //Currently only players can trigger things.
auto players = world->GetComponents("Player"); auto players = world->GetComponents("Player");
if (players == nullptr) { if (players == nullptr) {
return; return;
} }
EntityID tId = trigger.EntityID; EntityID tId = component.EntityID;
AABB triggerBox; boost::optional<AABB> triggerBox = Collision::EntityAbsoluteAABB(entity);
//The trigger *should* have a bounding box, or something, to test against so it can be triggered. //The trigger *should* have a bounding box, or something, to test against so it can be triggered.
if (!Collision::GetEntityBox(world, tId, triggerBox, true)) { if (!triggerBox) {
return; return;
} }
for (auto& pc : *players) { for (auto& pc : *players) {
EntityID pId = pc.EntityID; EntityID pId = pc.EntityID;
AABB playerBox; boost::optional<AABB> playerBox = Collision::EntityAbsoluteAABB(EntityWrapper(world, pId));
//The player can't trigger anything without an AABB. //The player can't trigger anything without an AABB.
if (!Collision::GetEntityBox(world, pId, playerBox, true)) { if (!playerBox) {
continue; continue;
} }
if (!Collision::AABBVsAABB(triggerBox, playerBox)) { if (!Collision::AABBVsAABB(*triggerBox, *playerBox)) {
//Entity is not touching the trigger, //Entity is not touching the trigger,
//Throw event if it was previously. //Throw event if it was previously.
if (throwLeaveIfWasInTrigger(m_EntitiesTouchingTrigger[tId], pId, tId)) { if (throwLeaveIfWasInTrigger(m_EntitiesTouchingTrigger[tId], pId, tId)) {
@@ -34,10 +34,9 @@ void TriggerSystem::UpdateComponent(World* world, ComponentWrapper& trigger, dou
throwLeaveIfWasInTrigger(m_EntitiesCompletelyInTrigger[tId], pId, tId); throwLeaveIfWasInTrigger(m_EntitiesCompletelyInTrigger[tId], pId, tId);
} else { } else {
//Entity is at least touching the trigger. //Entity is at least touching the trigger.
AABB completelyInsideBox; AABB completelyInsideBox = AABB::FromOriginSize((*triggerBox).Origin(), (*triggerBox).Size() - 2.0f * (*playerBox).Size());
completelyInsideBox.CreateFromCenter(triggerBox.Center(), triggerBox.Size() - 2.0f * playerBox.Size()); if (Collision::AABBVsAABB(completelyInsideBox, *playerBox) &&
if (Collision::AABBVsAABB(completelyInsideBox, playerBox) && glm::all(glm::greaterThan((*triggerBox).Size(), (*playerBox).Size()))) {
glm::all(glm::greaterThan(triggerBox.Size(), playerBox.Size()))) {
//Entity is completely inside the trigger. //Entity is completely inside the trigger.
//If it was only touching before, it is erased. //If it was only touching before, it is erased.
m_EntitiesTouchingTrigger[tId].erase(pId); m_EntitiesTouchingTrigger[tId].erase(pId);
@@ -79,3 +78,20 @@ bool TriggerSystem::throwLeaveIfWasInTrigger(std::unordered_set<EntityID>& trigg
return false; return false;
} }
bool TriggerSystem::OnTouch(const Events::TriggerTouch &event)
{
LOG_INFO("Player entity %i touched trigger entity %i.", event.Entity, event.Trigger);
return true;
}
bool TriggerSystem::OnEnter(const Events::TriggerEnter &event)
{
LOG_INFO("Player entity %i entered trigger entity %i.", event.Entity, event.Trigger);
return true;
}
bool TriggerSystem::OnLeave(const Events::TriggerLeave &event)
{
LOG_INFO("Player entity %i left trigger entity %i.", event.Entity, event.Trigger);
return true;
}
+5 -8
View File
@@ -4,7 +4,7 @@
AABB::AABB(const glm::vec3& minPos, const glm::vec3& maxPos) AABB::AABB(const glm::vec3& minPos, const glm::vec3& maxPos)
: m_MinCorner(minPos) : m_MinCorner(minPos)
, m_MaxCorner(maxPos) , m_MaxCorner(maxPos)
, m_Center(0.5f * (maxPos + minPos)) , m_Origin(0.5f * (maxPos + minPos))
, m_HalfSize(0.5f * (maxPos - minPos)) , m_HalfSize(0.5f * (maxPos - minPos))
{ {
DEBUG_IF(glm::any(glm::lessThan(m_MaxCorner, m_MinCorner))) { DEBUG_IF(glm::any(glm::lessThan(m_MaxCorner, m_MinCorner))) {
@@ -20,15 +20,12 @@ AABB::AABB(const glm::vec3& minPos, const glm::vec3& maxPos)
AABB::AABB(const glm::vec4& minPos, const glm::vec4& maxPos) AABB::AABB(const glm::vec4& minPos, const glm::vec4& maxPos)
: AABB(glm::vec3(minPos), glm::vec3(maxPos)) : AABB(glm::vec3(minPos), glm::vec3(maxPos))
{} { }
void AABB::CreateFromCenter(const glm::vec3& center, const glm::vec3& size) AABB AABB::FromOriginSize(const glm::vec3& origin, const glm::vec3& size)
{ {
m_Center = center; return AABB(origin - (size/2.f), origin + (size/2.f));
m_HalfSize = 0.5f * size;
m_MinCorner = m_Center - m_HalfSize;
m_MaxCorner = m_Center + m_HalfSize;
} }
AABB::~AABB() AABB::~AABB()
{} { }
+182 -3
View File
@@ -21,14 +21,24 @@ void EntityFile::Parse(const EntityFileHandler* handler) const
using namespace xercesc; using namespace xercesc;
EntityFileSAXHandler saxHandler(handler, nullptr); EntityFileSAXHandler saxHandler(handler, nullptr);
m_SAX2XMLReader->setFeature(XMLUni::fgXercesCacheGrammarFromParse, true); setReaderFeatures(m_SAX2XMLReader);
m_SAX2XMLReader->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true);
m_SAX2XMLReader->setContentHandler(&saxHandler); m_SAX2XMLReader->setContentHandler(&saxHandler);
m_SAX2XMLReader->setErrorHandler(&saxHandler); m_SAX2XMLReader->setErrorHandler(&saxHandler);
m_SAX2XMLReader->setDeclarationHandler(&saxHandler); m_SAX2XMLReader->setDeclarationHandler(&saxHandler);
m_SAX2XMLReader->parse(m_FilePath.string().c_str()); m_SAX2XMLReader->parse(m_FilePath.string().c_str());
} }
void EntityFile::setReaderFeatures(xercesc::SAX2XMLReader* reader)
{
using namespace xercesc;
reader->setFeature(XMLUni::fgXercesCacheGrammarFromParse, true);
reader->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true);
reader->setFeature(XMLUni::fgSAX2CoreValidation, true);
reader->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
reader->setFeature(XMLUni::fgXercesSchema, true);
reader->setFeature(XMLUni::fgXercesSchemaFullChecking, true);
}
std::size_t EntityFile::GetTypeStride(std::string typeName) std::size_t EntityFile::GetTypeStride(std::string typeName)
{ {
std::map<std::string, size_t> typeStrides{ std::map<std::string, size_t> typeStrides{
@@ -37,6 +47,7 @@ std::size_t EntityFile::GetTypeStride(std::string typeName)
{ "float", sizeof(float) }, { "float", sizeof(float) },
{ "double", sizeof(double) }, { "double", sizeof(double) },
{ "string", sizeof(std::string) }, { "string", sizeof(std::string) },
{ "enum", sizeof(int) },
{ "Vector", sizeof(glm::vec3) }, { "Vector", sizeof(glm::vec3) },
{ "Quaternion", sizeof(glm::quat) }, { "Quaternion", sizeof(glm::quat) },
{ "Color", sizeof(glm::vec4) } { "Color", sizeof(glm::vec4) }
@@ -75,7 +86,7 @@ void EntityFile::WriteAttributeData(char* outData, const ComponentInfo::Field_t&
void EntityFile::WriteValueData(char* outData, const ComponentInfo::Field_t& field, const char* valueData) void EntityFile::WriteValueData(char* outData, const ComponentInfo::Field_t& field, const char* valueData)
{ {
if (field.Type == "int") { if (field.Type == "int" || field.Type == "enum") {
int value = boost::lexical_cast<int>(valueData); int value = boost::lexical_cast<int>(valueData);
memcpy(outData, reinterpret_cast<char*>(&value), field.Stride); memcpy(outData, reinterpret_cast<char*>(&value), field.Stride);
} else if (field.Type == "float") { } else if (field.Type == "float") {
@@ -93,3 +104,171 @@ void EntityFile::WriteValueData(char* outData, const ComponentInfo::Field_t& fie
LOG_WARNING("Unknown value data type: %s", field.Type.c_str()); LOG_WARNING("Unknown value data type: %s", field.Type.c_str());
} }
} }
EntityFileSAXHandler::EntityFileSAXHandler(const EntityFileHandler* handler, xercesc::SAX2XMLReader* reader) : m_Handler(handler)
, m_Reader(reader)
{
// 0 is imaginary base parent
m_EntityStack.push(0);
m_StateStack.push(State::Unknown);
}
void EntityFileSAXHandler::startElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname, const xercesc::Attributes& attrs)
{
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 EntityFileSAXHandler::endElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname)
{
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 EntityFileSAXHandler::characters(const XMLCh* const chars, const XMLSize_t length)
{
if (m_StateStack.top() == State::ComponentField) {
char* transcoded = xercesc::XMLString::transcode(chars);
onFieldData(transcoded);
}
}
void EntityFileSAXHandler::fatalError(const xercesc::SAXParseException& e)
{
XS::ToString s(e.getMessage());
LOG_ERROR("SAXParseException: %s", ((std::string)s).c_str());
//throw e;
}
void EntityFileSAXHandler::error(const xercesc::SAXParseException& e)
{
XS::ToString s(e.getMessage());
LOG_ERROR("SAXParseException: %s", ((std::string)s).c_str());
}
void EntityFileSAXHandler::warning(const xercesc::SAXParseException& e)
{
XS::ToString s(e.getMessage());
LOG_ERROR("SAXParseException: %s", ((std::string)s).c_str());
}
void EntityFileSAXHandler::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 EntityFileSAXHandler::onEndEntity()
{
m_EntityStack.pop();
}
void EntityFileSAXHandler::onStartEntityRef(const xercesc::Attributes& attrs)
{
std::string path = XS::ToString(attrs.getValue(XS::ToXMLCh("file")));
xercesc::SAX2XMLReader* reader = xercesc::XMLReaderFactory::createXMLReader();
EntityFile::setReaderFeatures(reader);
reader->setContentHandler(this);
reader->setErrorHandler(this);
reader->parse(path.c_str());
delete reader;
}
void EntityFileSAXHandler::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 EntityFileSAXHandler::onEndComponent(const std::string& name) { }
void EntityFileSAXHandler::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 EntityFileSAXHandler::onEndComponentField(const std::string& field) { }
void EntityFileSAXHandler::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);
}
+17 -4
View File
@@ -9,17 +9,21 @@ EntityFileParser::EntityFileParser(const EntityFile* entityFile)
m_Handler.SetStartFieldDataCallback(std::bind(&EntityFileParser::onFieldData, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); m_Handler.SetStartFieldDataCallback(std::bind(&EntityFileParser::onFieldData, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
} }
void EntityFileParser::MergeEntities(World* world) EntityID EntityFileParser::MergeEntities(World* world, EntityID baseParent /*= EntityID_Invalid */)
{ {
m_World = world; m_World = world;
m_EntityIDMapper[0] = 0; m_EntityIDMapper[0] = baseParent;
m_EntityFile->Parse(&m_Handler); m_EntityFile->Parse(&m_Handler);
return m_FirstEntity;
} }
void EntityFileParser::onStartEntity(EntityID entity, EntityID parent, const std::string& name) void EntityFileParser::onStartEntity(EntityID entity, EntityID parent, const std::string& name)
{ {
EntityID realParent = m_EntityIDMapper.at(parent); EntityID realParent = m_EntityIDMapper.at(parent);
EntityID realEntity = m_World->CreateEntity(realParent); EntityID realEntity = m_World->CreateEntity(realParent);
if (m_FirstEntity == EntityID_Invalid) {
m_FirstEntity = realEntity;
}
if (!name.empty()) { if (!name.empty()) {
m_World->SetName(realEntity, name); m_World->SetName(realEntity, name);
} }
@@ -38,7 +42,12 @@ void EntityFileParser::onStartComponentField(EntityID entity, const std::string&
{ {
EntityID realEntity = m_EntityIDMapper.at(entity); EntityID realEntity = m_EntityIDMapper.at(entity);
ComponentWrapper component = m_World->GetComponent(realEntity, componentType); ComponentWrapper component = m_World->GetComponent(realEntity, componentType);
auto& field = component.Info.Fields.at(fieldName); auto fieldIt = component.Info.Fields.find(fieldName);
if (fieldIt == component.Info.Fields.end()) {
LOG_ERROR("Tried to set unknown field \"%s\" of component type \"%s\"! Ignoring.", fieldName.c_str(), componentType.c_str());
return;
}
auto& field = fieldIt->second;
LOG_DEBUG("Field \"%s\" type \"%s\"", fieldName.c_str(), field.Type.c_str()); LOG_DEBUG("Field \"%s\" type \"%s\"", fieldName.c_str(), field.Type.c_str());
LOG_DEBUG("Attributes:"); LOG_DEBUG("Attributes:");
@@ -54,7 +63,11 @@ void EntityFileParser::onFieldData(EntityID entity, const std::string& component
{ {
EntityID realEntity = m_EntityIDMapper.at(entity); EntityID realEntity = m_EntityIDMapper.at(entity);
ComponentWrapper component = m_World->GetComponent(realEntity, componentType); ComponentWrapper component = m_World->GetComponent(realEntity, componentType);
auto& field = component.Info.Fields.at(fieldName); auto fieldIt = component.Info.Fields.find(fieldName);
if (fieldIt == component.Info.Fields.end()) {
return;
}
auto& field = fieldIt->second;
char* data = component.Data + field.Offset; char* data = component.Data + field.Offset;
EntityFile::WriteValueData(data, field, fieldData); EntityFile::WriteValueData(data, field, fieldData);
+106 -55
View File
@@ -16,12 +16,12 @@ EntityFilePreprocessor::EntityFilePreprocessor(const EntityFile* entityFile)
for (auto& kv : m_ComponentInfo) { for (auto& kv : m_ComponentInfo) {
auto& info = kv.second; auto& info = kv.second;
LOG_DEBUG("Component: %s (%s)", info.Name.c_str(), info.Meta.Annotation.c_str()); LOG_DEBUG("Component: %s (%s)", info.Name.c_str(), info.Meta->Annotation.c_str());
LOG_DEBUG("Stride: %i", info.Meta.Stride); LOG_DEBUG("Stride: %i", info.Stride);
LOG_DEBUG("Allocation: %i", info.Meta.Allocation); LOG_DEBUG("Allocation: %i", info.Meta->Allocation);
for (auto& kv : info.Fields) { for (auto& kv : info.Fields) {
auto& field = kv.second; auto& field = kv.second;
LOG_DEBUG("\t%i\t%s %s", field.Offset, field.Type, kv.first.c_str()); LOG_DEBUG("\t%i\t%s %s", field.Offset, field.Type.c_str(), kv.first.c_str());
} }
} }
@@ -62,62 +62,36 @@ void EntityFilePreprocessor::parseComponentInfo()
} }
ComponentInfo compInfo; ComponentInfo compInfo;
compInfo.Meta = std::make_shared<ComponentInfo::Meta_t>();
// Name // Name
compInfo.Name = XS::ToString(element->getName()); compInfo.Name = XS::ToString(element->getName());
// Known allocation // Known allocation
compInfo.Meta.Allocation = m_ComponentCounts[compInfo.Name]; compInfo.Meta->Allocation = m_ComponentCounts[compInfo.Name];
// Annotation // Annotation
auto componentAnnotation = element->getAnnotation(); auto componentAnnotation = element->getAnnotation();
if (componentAnnotation != nullptr) { if (componentAnnotation != nullptr) {
// Parse annotation XML compInfo.Meta->Annotation = parseAnnotationXML(componentAnnotation->getAnnotationString());
char* annotationString = XMLString::transcode(componentAnnotation->getAnnotationString());
MemBufInputSource annotationInput(reinterpret_cast<const XMLByte*>(annotationString), strlen(annotationString), "MemBuf: Annotation String");
XercesDOMParser parser(nullptr, XMLPlatformUtils::fgMemoryManager, grammarPool);
parser.setErrorHandler(&errorHandler);
parser.parse(annotationInput);
XMLString::release(&annotationString);
auto doc = parser.getDocument();
// TODO: Add allocation estimations from external file on map-to-map basis
// Add allocation estimation(s)
//auto allocationTags = doc->getElementsByTagName(XSTR("meta:allocation"));
//for (int i = 0; i < allocationTags->getLength(); ++i) {
// auto allocation = dynamic_cast<DOMElement*>(allocationTags->item(i));
// auto child = allocation->getFirstChild();
// if (child == nullptr) {
// continue;
// }
// XSValue::Status status;
// XSValue* val = XSValue::getActualValue(child->getNodeValue(), XSValue::dt_integer, status);
// compInfo.Meta.Allocation += val->fData.fValue.f_int;
//}
// Save documentation string
auto documentationTags = doc->getElementsByTagName(XS::ToXMLCh("xs:documentation"));
if (documentationTags->getLength() != 0) {
auto child = documentationTags->item(0)->getFirstChild();
if (child != nullptr) {
compInfo.Meta.Annotation = XS::ToString(child->getNodeValue());
}
}
} else { } else {
LOG_WARNING("Component is missing an annotation!"); LOG_WARNING("Component \"%s\" is missing an annotation!", compInfo.Name.c_str());
} }
// <xs:complexType> // <xs:complexType>
auto typeDefinition = element->getTypeDefinition(); auto typeDefinition = element->getTypeDefinition();
// Allow empty components
if (typeDefinition == nullptr) {
continue;
}
if (typeDefinition->getTypeCategory() != XSTypeDefinition::COMPLEX_TYPE) { if (typeDefinition->getTypeCategory() != XSTypeDefinition::COMPLEX_TYPE) {
LOG_ERROR("Type definition wasn't COMPLEX_TYPE! Skipping."); LOG_ERROR("Failed to parse component definition for \"%s\": Type definition wasn't COMPLEX_TYPE!", compInfo.Name.c_str());
continue; continue;
} }
auto complexTypeDefinition = dynamic_cast<XSComplexTypeDefinition*>(typeDefinition); auto complexTypeDefinition = dynamic_cast<XSComplexTypeDefinition*>(typeDefinition);
// <xs:all> // <xs:all>
auto modelGroupParticle = complexTypeDefinition->getParticle(); auto modelGroupParticle = complexTypeDefinition->getParticle();
if (modelGroupParticle->getTermType() != XSParticle::TERM_MODELGROUP) { if (modelGroupParticle == nullptr || modelGroupParticle->getTermType() != XSParticle::TERM_MODELGROUP) {
LOG_ERROR("Model group particle wasn't TERM_MODELGROUP! Skipping."); LOG_ERROR("Failed to parse component definition for \"%s\": Model group particle was null or wasn't TERM_MODELGROUP!", compInfo.Name.c_str());
continue; continue;
} }
auto modelGroup = modelGroupParticle->getModelGroupTerm(); auto modelGroup = modelGroupParticle->getModelGroupTerm();
@@ -129,31 +103,65 @@ void EntityFilePreprocessor::parseComponentInfo()
for (unsigned int i = 0; i < particles->size(); ++i) { for (unsigned int i = 0; i < particles->size(); ++i) {
auto particle = particles->elementAt(i); auto particle = particles->elementAt(i);
if (particle->getTermType() != XSParticle::TERM_ELEMENT) { if (particle->getTermType() != XSParticle::TERM_ELEMENT) {
LOG_ERROR("Particle wasn't TERM_ELEMENT! Skipping."); LOG_ERROR("Failed to parse a field definition in component \"%s\": Particle wasn't TERM_ELEMENT! Skipping.", compInfo.Name.c_str());
continue; continue;
} }
auto elementDeclaration = particle->getElementTerm(); auto elementDeclaration = particle->getElementTerm();
std::string name = XS::ToString(elementDeclaration->getName()); std::string name = XS::ToString(elementDeclaration->getName());
std::string type = XS::ToString(elementDeclaration->getTypeDefinition()->getName()); std::string type = XS::ToString(elementDeclaration->getTypeDefinition()->getName());
std::string typeNamespace = XS::ToString(elementDeclaration->getTypeDefinition()->getNamespace());
std::string baseType = XS::ToString(elementDeclaration->getTypeDefinition()->getBaseType()->getName());
std::string effectiveType = type;
size_t stride = EntityFile::GetTypeStride(type); size_t stride = EntityFile::GetTypeStride(type);
if (stride == 0) { if (stride == 0) {
std::cout << "Warning: Field \"" << name << "\" in component \"" << compInfo.Name << "\" uses unexpected field type \"" << type << "\". Skipping." << std::endl; stride = EntityFile::GetTypeStride(baseType);
continue; if (stride == 0) {
LOG_WARNING("Field \"%s\" in component \"%s\" uses unexpected field type \"%s\" with base type \"%s\". Skipping.", name.c_str(), compInfo.Name.c_str(), type.c_str(), baseType.c_str());
continue;
}
effectiveType = baseType;
}
// Annotation
auto fieldAnnotation = elementDeclaration->getAnnotation();
if (fieldAnnotation != nullptr) {
compInfo.Meta->FieldAnnotations[name] = parseAnnotationXML(fieldAnnotation->getAnnotationString());
} else {
LOG_WARNING("Component field \"%s.%s\" is missing an annotation!", compInfo.Name.c_str(), name.c_str());
}
if (effectiveType == "enum") {
// Parse potential enum type definition for field type
if (compInfo.Meta->FieldEnumDefinitions.count(name) == 0) {
auto enumTypeDefinition = xsModel->getTypeDefinition(XS::ToXMLCh(type), XS::ToXMLCh("components"));
auto xsComplexType = dynamic_cast<XSComplexTypeDefinition*>(enumTypeDefinition);
auto xsComplexContent = xsComplexType->getParticle();
auto xsExtension = xsComplexContent->getModelGroupTerm();
auto xsExtensionParticles = xsExtension->getParticles();
auto xsChoice = xsExtensionParticles->elementAt(0)->getModelGroupTerm();
auto xsChoiceParticles = xsChoice->getParticles();
for (int i = 0; i < xsChoiceParticles->size(); ++i) {
auto enumElement = xsChoiceParticles->elementAt(i)->getElementTerm();
std::string enumName = XS::ToString(enumElement->getName());
std::string enumValue = XS::ToString(enumElement->getConstraintValue());
compInfo.Meta->FieldEnumDefinitions[name][enumName] = boost::lexical_cast<int>(enumValue);
LOG_DEBUG("ENUM %s = %s", enumName.c_str(), enumValue.c_str());
}
}
} }
auto& field = compInfo.Fields[name]; auto& field = compInfo.Fields[name];
field.Name = name; field.Name = name;
field.Type = type; field.Type = effectiveType;
field.Offset = fieldOffset; field.Offset = fieldOffset;
field.Stride = stride; field.Stride = stride;
compInfo.FieldsInOrder.push_back(name); compInfo.FieldsInOrder.push_back(name);
fieldOffset += stride; fieldOffset += stride;
} }
compInfo.Meta.Stride = fieldOffset; compInfo.Stride = fieldOffset;
m_ComponentInfo[compInfo.Name] = compInfo; m_ComponentInfo[compInfo.Name] = compInfo;
} }
} }
@@ -166,13 +174,22 @@ void EntityFilePreprocessor::parseDefaults()
for (auto& ci : m_ComponentInfo) { for (auto& ci : m_ComponentInfo) {
// Allocate memory for default values // Allocate memory for default values
ci.second.Defaults = std::shared_ptr<char>(new char[ci.second.Meta.Stride]); ci.second.Defaults = std::shared_ptr<char>(new char[ci.second.Stride]);
memset(ci.second.Defaults.get(), 0, ci.second.Meta.Stride); memset(ci.second.Defaults.get(), 0, ci.second.Stride);
XercesDOMParser parser(nullptr, XMLPlatformUtils::fgMemoryManager);
parser.setErrorHandler(&errorHandler);
std::string componentName = ci.first; std::string componentName = ci.first;
XercesDOMParser parser(nullptr, XMLPlatformUtils::fgMemoryManager);
parser.setDoSchema(true);
parser.setDoNamespaces(true);
parser.setErrorHandler(&errorHandler);
parser.setValidationScheme(XercesDOMParser::Val_Always);
parser.setValidationSchemaFullChecking(true);
//parser.setDoNamespaces(true);
//boost::filesystem::path schemaLocation = "Schema/Components/" + componentName + ".xsd";
//std::string namespaceSchema = schemaLocation.string();
//parser.setExternalNoNamespaceSchemaLocation("Teamasdasdasdasd.xsd");
LOG_DEBUG("Parsing defaults for component %s", componentName.c_str()); LOG_DEBUG("Parsing defaults for component %s", componentName.c_str());
boost::filesystem::path defaultsFile = "Schema/Components/" + componentName + ".xml"; boost::filesystem::path defaultsFile = "Schema/Components/" + componentName + ".xml";
@@ -184,7 +201,7 @@ void EntityFilePreprocessor::parseDefaults()
} }
// Find the node in the components namespace matching the component name // Find the node in the components namespace matching the component name
std::string tagName = "c:" + componentName; std::string tagName = componentName;
auto rootNodes = doc->getElementsByTagName(XS::ToXMLCh(tagName)); auto rootNodes = doc->getElementsByTagName(XS::ToXMLCh(tagName));
if (rootNodes->getLength() == 0) { if (rootNodes->getLength() == 0) {
LOG_ERROR("Couldn't find defaults for component \"%s\"! Skipping.", componentName.c_str()); LOG_ERROR("Couldn't find defaults for component \"%s\"! Skipping.", componentName.c_str());
@@ -217,9 +234,19 @@ void EntityFilePreprocessor::parseDefaults()
EntityFile::WriteAttributeData(data, field, attributes); EntityFile::WriteAttributeData(data, field, attributes);
} }
// Handle potential field values
auto childNode = fieldElement->getFirstChild(); auto childNode = fieldElement->getFirstChild();
if (childNode != nullptr && childNode->getNodeType() == DOMNode::TEXT_NODE) { if (childNode == nullptr) {
continue;
}
// An enum will either have an element node with a text node inside,
// or contain a text node directly.
if (childNode->getNodeType() == DOMNode::ELEMENT_NODE) {
childNode = childNode->getFirstChild();
}
// Handle potential field values
if (childNode->getNodeType() == DOMNode::TEXT_NODE) {
char* cstrValue = XMLString::transcode(childNode->getNodeValue()); char* cstrValue = XMLString::transcode(childNode->getNodeValue());
EntityFile::WriteValueData(data, field, cstrValue); EntityFile::WriteValueData(data, field, cstrValue);
XMLString::release(&cstrValue); XMLString::release(&cstrValue);
@@ -228,3 +255,27 @@ void EntityFilePreprocessor::parseDefaults()
} }
} }
std::string EntityFilePreprocessor::parseAnnotationXML(const XMLCh* xml)
{
using namespace xercesc;
// Parse annotation XML
char* annotationString = XMLString::transcode(xml);
MemBufInputSource annotationInput(reinterpret_cast<const XMLByte*>(annotationString), strlen(annotationString), "MemBuf: Annotation String");
XercesDOMParser parser(nullptr, XMLPlatformUtils::fgMemoryManager);
//parser.setErrorHandler(&errorHandler);
parser.parse(annotationInput);
XMLString::release(&annotationString);
auto doc = parser.getDocument();
// Save documentation string
auto documentationTags = doc->getElementsByTagName(XS::ToXMLCh("xs:documentation"));
if (documentationTags->getLength() != 0) {
auto child = documentationTags->item(0)->getFirstChild();
if (child != nullptr) {
return XS::ToString(child->getNodeValue());
}
}
return std::string();
}
+1 -1
View File
@@ -114,7 +114,7 @@ void EntityFileWriter::appentEntityComponents(xercesc::DOMElement* parentElement
fieldElement->setAttribute(X("Y"), X(boost::lexical_cast<std::string>(q.y))); fieldElement->setAttribute(X("Y"), X(boost::lexical_cast<std::string>(q.y)));
fieldElement->setAttribute(X("Z"), X(boost::lexical_cast<std::string>(q.z))); fieldElement->setAttribute(X("Z"), X(boost::lexical_cast<std::string>(q.z)));
fieldElement->setAttribute(X("W"), X(boost::lexical_cast<std::string>(q.w))); fieldElement->setAttribute(X("W"), X(boost::lexical_cast<std::string>(q.w)));
} else if (field.Type == "int") { } else if (field.Type == "int" || field.Type == "enum") {
const int& value = c[fieldName]; const int& value = c[fieldName];
fieldElement->appendChild(doc->createTextNode(X(boost::lexical_cast<std::string>(value)))); fieldElement->appendChild(doc->createTextNode(X(boost::lexical_cast<std::string>(value))));
} else if (field.Type == "float") { } else if (field.Type == "float") {
+30
View File
@@ -0,0 +1,30 @@
#include "Core/EntityWrapper.h"
#include "Core/World.h"
const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Invalid);
bool EntityWrapper::operator==(const EntityWrapper& e)
{
return (this->World == e.World) && (this->ID == e.ID);
}
bool EntityWrapper::HasComponent(const std::string& componentName)
{
return World->HasComponent(ID, componentName);
}
ComponentWrapper EntityWrapper::operator[](const std::string& componentName)
{
if (World->HasComponent(ID, componentName)) {
return World->GetComponent(ID, componentName);
} else {
LOG_WARNING("EntityWrapper implicitly attached \"%s\" component to #%i as a result of a fetch request!", componentName.c_str(), ID);
return World->AttachComponent(ID, componentName);
}
}
EntityWrapper::operator EntityID()
{
return this->ID;
}
+5
View File
@@ -0,0 +1,5 @@
#include "Core/MemoryPool.h"
namespace DisableMemoryPool
{
bool Value = false;
}
@@ -2,7 +2,7 @@
#include <algorithm> #include <algorithm>
#include <bitset> #include <bitset>
#include "Core/OctTree.h" #include "Core/Octree.h"
#include "Collision/Collision.h" #include "Collision/Collision.h"
namespace namespace
@@ -21,65 +21,61 @@ bool isFirstLower(const ChildInfo& first, const ChildInfo& second)
} }
OctTree::OctTree() Octree::Octree(const AABB& octTreeBounds, int subDivisions)
: OctTree(AABB(), 0) : m_Root(new Child(octTreeBounds, subDivisions, m_StaticObjects, m_DynamicObjects))
{}
OctTree::OctTree(const AABB& octTreeBounds, int subDivisions)
: m_Root(new OctChild(octTreeBounds, subDivisions, m_StaticObjects, m_DynamicObjects))
, m_UpdatedOnce(false) , m_UpdatedOnce(false)
{} { }
OctTree::~OctTree() Octree::~Octree()
{ {
delete m_Root; delete m_Root;
} }
void OctTree::AddDynamicObject(const AABB& box) void Octree::AddDynamicObject(const AABB& box)
{ {
m_Root->AddDynamicObject(box); m_Root->AddDynamicObject(box);
m_DynamicObjects.push_back(box); m_DynamicObjects.push_back(box);
} }
void OctTree::AddStaticObject(const AABB& box) void Octree::AddStaticObject(const AABB& box)
{ {
m_Root->AddStaticObject(box); m_Root->AddStaticObject(box);
m_StaticObjects.push_back(box); m_StaticObjects.push_back(box);
} }
void OctTree::BoxesInSameRegion(const AABB& box, std::vector<AABB>& outBoxes) void Octree::BoxesInSameRegion(const AABB& box, std::vector<AABB>& outBoxes)
{ {
falsifyObjectChecks(); falsifyObjectChecks();
m_Root->BoxesInSameRegion(box, outBoxes); m_Root->BoxesInSameRegion(box, outBoxes);
} }
void OctTree::ClearObjects() void Octree::ClearObjects()
{ {
m_StaticObjects.clear(); m_StaticObjects.clear();
m_DynamicObjects.clear(); m_DynamicObjects.clear();
m_Root->ClearObjects(); m_Root->ClearObjects();
} }
void OctTree::ClearDynamicObjects() void Octree::ClearDynamicObjects()
{ {
m_DynamicObjects.clear(); m_DynamicObjects.clear();
m_Root->ClearDynamicObjects(); m_Root->ClearDynamicObjects();
} }
bool OctTree::RayCollides(const Ray& ray, Output& data) bool Octree::RayCollides(const Ray& ray, Output& data)
{ {
falsifyObjectChecks(); falsifyObjectChecks();
data.CollideDistance = -1; data.CollideDistance = -1;
return m_Root->RayCollides(ray, data); return m_Root->RayCollides(ray, data);
} }
bool OctTree::BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) bool Octree::BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected)
{ {
falsifyObjectChecks(); falsifyObjectChecks();
return m_Root->BoxCollides(boxToTest, outBoxIntersected); return m_Root->BoxCollides(boxToTest, outBoxIntersected);
} }
void OctTree::falsifyObjectChecks() void Octree::falsifyObjectChecks()
{ {
for (auto& obj : m_StaticObjects) { for (auto& obj : m_StaticObjects) {
obj.Checked = false; obj.Checked = false;
@@ -89,7 +85,7 @@ void OctTree::falsifyObjectChecks()
} }
} }
OctTree::OctChild::OctChild(const AABB& octTreeBounds, Octree::Child::Child(const AABB& octTreeBounds,
int subDivisions, int subDivisions,
std::vector<ContainedObject>& staticObjects, std::vector<ContainedObject>& staticObjects,
std::vector<ContainedObject>& dynamicObjects) std::vector<ContainedObject>& dynamicObjects)
@@ -98,7 +94,7 @@ OctTree::OctChild::OctChild(const AABB& octTreeBounds,
, m_DynamicObjectsRef(dynamicObjects) , m_DynamicObjectsRef(dynamicObjects)
{ {
if (subDivisions == 0) { if (subDivisions == 0) {
for (OctChild*& c : m_Children) { for (Child*& c : m_Children) {
c = nullptr; c = nullptr;
} }
} else { } else {
@@ -107,7 +103,7 @@ OctTree::OctChild::OctChild(const AABB& octTreeBounds,
glm::vec3 minPos, maxPos; glm::vec3 minPos, maxPos;
const glm::vec3& parentMin = m_Box.MinCorner(); const glm::vec3& parentMin = m_Box.MinCorner();
const glm::vec3& parentMax = m_Box.MaxCorner(); const glm::vec3& parentMax = m_Box.MaxCorner();
const glm::vec3& parentCenter = m_Box.Center(); const glm::vec3& parentCenter = m_Box.Origin();
std::bitset<3> bits(i); std::bitset<3> bits(i);
//If child is 4,5,6,7. //If child is 4,5,6,7.
if (bits.test(2)) { if (bits.test(2)) {
@@ -134,14 +130,14 @@ OctTree::OctChild::OctChild(const AABB& octTreeBounds,
minPos.z = parentMin.z; minPos.z = parentMin.z;
maxPos.z = parentCenter.z; maxPos.z = parentCenter.z;
} }
m_Children[i] = new OctChild(AABB(minPos, maxPos), subDivisions, m_StaticObjectsRef, m_DynamicObjectsRef); m_Children[i] = new Child(AABB(minPos, maxPos), subDivisions, m_StaticObjectsRef, m_DynamicObjectsRef);
} }
} }
} }
OctTree::OctChild::~OctChild() Octree::Child::~Child()
{ {
for (OctChild*& c : m_Children) { for (Child*& c : m_Children) {
if (c != nullptr) { if (c != nullptr) {
delete c; delete c;
c = nullptr; c = nullptr;
@@ -149,7 +145,7 @@ OctTree::OctChild::~OctChild()
} }
} }
bool OctTree::OctChild::BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) const bool Octree::Child::BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) const
{ {
if (hasChildren()) { if (hasChildren()) {
for (int i : childIndicesContainingBox(boxToTest)) { for (int i : childIndicesContainingBox(boxToTest)) {
@@ -182,7 +178,7 @@ bool OctTree::OctChild::BoxCollides(const AABB& boxToTest, AABB& outBoxIntersect
return false; return false;
} }
bool OctTree::OctChild::RayCollides(const Ray& ray, Output& data) const bool Octree::Child::RayCollides(const Ray& ray, Output& data) const
{ {
//If the node AABB is missed, everything it contains is missed. //If the node AABB is missed, everything it contains is missed.
if (Collision::RayAABBIntr(ray, m_Box)) { if (Collision::RayAABBIntr(ray, m_Box)) {
@@ -192,7 +188,7 @@ bool OctTree::OctChild::RayCollides(const Ray& ray, Output& data) const
std::vector<ChildInfo> childInfos; std::vector<ChildInfo> childInfos;
childInfos.reserve(8); childInfos.reserve(8);
for (int i = 0; i < 8; ++i) { for (int i = 0; i < 8; ++i) {
childInfos.push_back({ i, glm::distance(ray.Origin(), m_Children[i]->m_Box.Center()) }); childInfos.push_back({ i, glm::distance(ray.Origin(), m_Children[i]->m_Box.Origin()) });
} }
std::sort(childInfos.begin(), childInfos.end(), isFirstLower); std::sort(childInfos.begin(), childInfos.end(), isFirstLower);
//Loop through the children, starting with the one closest to the ray origin. I.e the first to be hit. //Loop through the children, starting with the one closest to the ray origin. I.e the first to be hit.
@@ -234,7 +230,7 @@ bool OctTree::OctChild::RayCollides(const Ray& ray, Output& data) const
} }
void OctTree::OctChild::AddDynamicObject(const AABB& box) void Octree::Child::AddDynamicObject(const AABB& box)
{ {
if (hasChildren()) { if (hasChildren()) {
for (auto i : childIndicesContainingBox(box)) { for (auto i : childIndicesContainingBox(box)) {
@@ -246,7 +242,7 @@ void OctTree::OctChild::AddDynamicObject(const AABB& box)
} }
} }
void OctTree::OctChild::AddStaticObject(const AABB& box) void Octree::Child::AddStaticObject(const AABB& box)
{ {
if (hasChildren()) { if (hasChildren()) {
for (auto i : childIndicesContainingBox(box)) { for (auto i : childIndicesContainingBox(box)) {
@@ -258,7 +254,7 @@ void OctTree::OctChild::AddStaticObject(const AABB& box)
} }
} }
void OctTree::OctChild::BoxesInSameRegion(const AABB& box, std::vector<AABB>& outBoxes) const void Octree::Child::BoxesInSameRegion(const AABB& box, std::vector<AABB>& outBoxes) const
{ {
if (hasChildren()) { if (hasChildren()) {
for (auto i : childIndicesContainingBox(box)) { for (auto i : childIndicesContainingBox(box)) {
@@ -292,10 +288,10 @@ void OctTree::OctChild::BoxesInSameRegion(const AABB& box, std::vector<AABB>& ou
} }
} }
void OctTree::OctChild::ClearObjects() void Octree::Child::ClearObjects()
{ {
if (hasChildren()) { if (hasChildren()) {
for (OctChild*& c : m_Children) { for (Child*& c : m_Children) {
c->ClearObjects(); c->ClearObjects();
} }
} else { } else {
@@ -304,10 +300,10 @@ void OctTree::OctChild::ClearObjects()
} }
} }
void OctTree::OctChild::ClearDynamicObjects() void Octree::Child::ClearDynamicObjects()
{ {
if (hasChildren()) { if (hasChildren()) {
for (OctChild*& c : m_Children) { for (Child*& c : m_Children) {
c->ClearObjects(); c->ClearObjects();
} }
} else { } else {
@@ -327,13 +323,13 @@ void OctTree::OctChild::ClearDynamicObjects()
// x : - - - - + + + + // x : - - - - + + + +
// y : - - + + - - + + // y : - - + + - - + +
// z : - + - + - + - + // z : - + - + - + - +
int OctTree::OctChild::childIndexContainingPoint(const glm::vec3& point) const int Octree::Child::childIndexContainingPoint(const glm::vec3& point) const
{ {
const glm::vec3& c = m_Box.Center(); const glm::vec3& c = m_Box.Origin();
return (1 << 2) * (point.x >= c.x) | (1 << 1) * (point.y >= c.y) | (point.z >= c.z); return (1 << 2) * (point.x >= c.x) | (1 << 1) * (point.y >= c.y) | (point.z >= c.z);
} }
std::vector<int> OctTree::OctChild::childIndicesContainingBox(const AABB& box) const std::vector<int> Octree::Child::childIndicesContainingBox(const AABB& box) const
{ {
int minInd = childIndexContainingPoint(box.MinCorner()); int minInd = childIndexContainingPoint(box.MinCorner());
int maxInd = childIndexContainingPoint(box.MaxCorner()); int maxInd = childIndexContainingPoint(box.MaxCorner());
@@ -371,7 +367,7 @@ std::vector<int> OctTree::OctChild::childIndicesContainingBox(const AABB& box) c
} }
} }
inline bool OctTree::OctChild::hasChildren() const inline bool Octree::Child::hasChildren() const
{ {
return m_Children[0] != nullptr; return m_Children[0] != nullptr;
} }
+11 -6
View File
@@ -66,7 +66,7 @@ void World::RegisterComponent(ComponentInfo& ci)
} }
} }
ComponentWrapper World::AttachComponent(EntityID entity, std::string componentType) ComponentWrapper World::AttachComponent(EntityID entity, const std::string& componentType)
{ {
// TODO: Allocate dynamic pool if component isn't registered // TODO: Allocate dynamic pool if component isn't registered
ComponentPool* pool = m_ComponentPools.at(componentType); ComponentPool* pool = m_ComponentPools.at(componentType);
@@ -75,31 +75,31 @@ ComponentWrapper World::AttachComponent(EntityID entity, std::string componentTy
// Allocate space for the component // Allocate space for the component
ComponentWrapper c = pool->Allocate(entity); ComponentWrapper c = pool->Allocate(entity);
// Write default values // Write default values
memcpy(c.Data, ci.Defaults.get(), ci.Meta.Stride); memcpy(c.Data, ci.Defaults.get(), ci.Stride);
return c; return c;
} }
bool World::HasComponent(EntityID entity, std::string componentType) const bool World::HasComponent(EntityID entity, const std::string& componentType) const
{ {
ComponentPool* pool = m_ComponentPools.at(componentType); ComponentPool* pool = m_ComponentPools.at(componentType);
return pool->KnowsEntity(entity); return pool->KnowsEntity(entity);
} }
ComponentWrapper World::GetComponent(EntityID entity, std::string componentType) ComponentWrapper World::GetComponent(EntityID entity, const std::string& componentType)
{ {
ComponentPool* pool = m_ComponentPools.at(componentType); ComponentPool* pool = m_ComponentPools.at(componentType);
return pool->GetByEntity(entity); return pool->GetByEntity(entity);
} }
void World::DeleteComponent(EntityID entity, std::string componentType) void World::DeleteComponent(EntityID entity, const std::string& componentType)
{ {
ComponentPool* pool = m_ComponentPools.at(componentType); ComponentPool* pool = m_ComponentPools.at(componentType);
ComponentWrapper c = pool->GetByEntity(entity); ComponentWrapper c = pool->GetByEntity(entity);
return pool->Delete(c); return pool->Delete(c);
} }
const ComponentPool* World::GetComponents(std::string componentType) const ComponentPool* World::GetComponents(const std::string& componentType)
{ {
auto it = m_ComponentPools.find(componentType); auto it = m_ComponentPools.find(componentType);
return (it != m_ComponentPools.end()) ? it->second : nullptr; return (it != m_ComponentPools.end()) ? it->second : nullptr;
@@ -125,6 +125,11 @@ void World::SetParent(EntityID entity, EntityID parent)
m_EntityChildren.insert(std::make_pair(parent, entity)); m_EntityChildren.insert(std::make_pair(parent, entity));
} }
const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> World::GetChildren(EntityID entity)
{
return m_EntityChildren.equal_range(entity);
}
void World::SetName(EntityID entity, const std::string& name) void World::SetName(EntityID entity, const std::string& name)
{ {
m_EntityNames[entity] = name; m_EntityNames[entity] = name;
+32 -10
View File
@@ -3,7 +3,8 @@
#include <imgui/imgui_internal.h> #include <imgui/imgui_internal.h>
EditorSystem::EditorSystem(EventBroker* eventBroker, IRenderer* renderer) EditorSystem::EditorSystem(EventBroker* eventBroker, IRenderer* renderer)
: ImpureSystem(eventBroker) : System(eventBroker)
, ImpureSystem()
, m_Renderer(renderer) , m_Renderer(renderer)
{ {
auto config = ResourceManager::Load<ConfigFile>("Config.ini"); auto config = ResourceManager::Load<ConfigFile>("Config.ini");
@@ -483,8 +484,8 @@ void EditorSystem::drawUI(World* world, double dt)
} }
if (ImGui::CollapsingHeader(componentType.c_str())) { if (ImGui::CollapsingHeader(componentType.c_str())) {
if (!ci.Meta.Annotation.empty()) { if (!ci.Meta->Annotation.empty()) {
ImGui::Text(ci.Meta.Annotation.c_str()); ImGui::Text(ci.Meta->Annotation.c_str());
} }
auto& component = world->GetComponent(m_Selection, componentType); auto& component = world->GetComponent(m_Selection, componentType);
@@ -492,9 +493,10 @@ void EditorSystem::drawUI(World* world, double dt)
const std::string& fieldName = kv.first; const std::string& fieldName = kv.first;
auto& field = kv.second; auto& field = kv.second;
ImGui::PushID(fieldName.c_str()); std::string uniqueID = componentType + fieldName;
ImGui::PushID(uniqueID.c_str());
if (field.Type == "Vector") { if (field.Type == "Vector") {
auto& val = component.Property<glm::vec3>(fieldName); auto& val = component.Field<glm::vec3>(fieldName);
if (fieldName == "Scale") { if (fieldName == "Scale") {
ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, 0.f, std::numeric_limits<float>::max()); ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, 0.f, std::numeric_limits<float>::max());
} else if (fieldName == "Orientation") { } else if (fieldName == "Orientation") {
@@ -506,10 +508,10 @@ void EditorSystem::drawUI(World* world, double dt)
ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max()); ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max());
} }
} else if (field.Type == "Color") { } else if (field.Type == "Color") {
auto& val = component.Property<glm::vec4>(fieldName); auto& val = component.Field<glm::vec4>(fieldName);
ImGui::ColorEdit4("", glm::value_ptr(val), true); ImGui::ColorEdit4("", glm::value_ptr(val), true);
} else if (field.Type == "string") { } else if (field.Type == "string") {
std::string& val = component.Property<std::string>(fieldName); std::string& val = component.Field<std::string>(fieldName);
char tempString[1024]; char tempString[1024];
memcpy(tempString, val.c_str(), std::min(val.length() + 1, sizeof(tempString))); memcpy(tempString, val.c_str(), std::min(val.length() + 1, sizeof(tempString)));
if (ImGui::InputText("", tempString, sizeof(tempString))) { if (ImGui::InputText("", tempString, sizeof(tempString))) {
@@ -523,12 +525,32 @@ void EditorSystem::drawUI(World* world, double dt)
} }
} else if (field.Type == "double") { } else if (field.Type == "double") {
float tempVal = static_cast<float>(component.Property<double>(fieldName)); float tempVal = static_cast<float>(component.Field<double>(fieldName));
if (ImGui::InputFloat("", &tempVal, 0.01f, 1.f)) { if (ImGui::InputFloat("", &tempVal, 0.01f, 1.f)) {
component.SetProperty(fieldName, static_cast<double>(tempVal)); component.SetField(fieldName, static_cast<double>(tempVal));
}
} else if (field.Type == "int") {
int val = component.Field<int>(fieldName);
ImGui::InputInt("", &val);
} else if (field.Type == "enum") {
int currentValue = component.Field<int>(fieldName);
int item = -1;
std::stringstream enumKeys;
std::vector<int> enumValues;
int i = 0;
for (auto& kv : ci.Meta->FieldEnumDefinitions.at(fieldName)) {
enumKeys << kv.first << " (" << kv.second << ")" << '\0';
enumValues.push_back(kv.second);
if (currentValue == kv.second) {
item = i;
}
i++;
}
if (ImGui::Combo("", &item, enumKeys.str().c_str())) {
component.SetField(fieldName, enumValues.at(item));
} }
} else if (field.Type == "bool") { } else if (field.Type == "bool") {
auto& val = component.Property<bool>(fieldName); auto& val = component.Field<bool>(fieldName);
ImGui::Checkbox("", &val); ImGui::Checkbox("", &val);
} else { } else {
ImGui::TextDisabled(field.Type.c_str()); ImGui::TextDisabled(field.Type.c_str());
+10 -9
View File
@@ -20,15 +20,16 @@ void InputProxy::LoadBindings(std::string file)
for (auto& origin : config->GetAll<std::string>("Bindings")) { for (auto& origin : config->GetAll<std::string>("Bindings")) {
Events::BindOrigin e; Events::BindOrigin e;
e.Origin = origin.first; e.Origin = origin.first;
e.Command = origin.second; const std::string& command = origin.second;
e.Value = 1.f; if (!command.empty()) {
if (!e.Command.empty()) { boost::char_separator<char> separator(", ");
char prefix = e.Command.at(0); boost::tokenizer<decltype(separator)> tokenizer(command, separator);
if (prefix == '+' || prefix == '-') { auto token = tokenizer.begin();
e.Command = e.Command.substr(1); e.Command = *token;
if (prefix == '-') { if (++token != tokenizer.end()) {
e.Value *= -1.f; e.Value = boost::lexical_cast<float>(*token);
} } else {
e.Value = 1.f;
} }
OnBindOrigin(e); OnBindOrigin(e);
} }
+26 -19
View File
@@ -40,15 +40,14 @@ void LightCullingPass::OnResolutionChange()
void LightCullingPass::SetSSBOSizes() void LightCullingPass::SetSSBOSizes()
{ {
m_NumberOfTiles = (int)(m_Renderer->Resolution().Width*m_Renderer->Resolution().Height)/TILE_SIZE; m_NumberOfTiles = (int)(m_Renderer->Resolution().Width/TILE_SIZE) * (int)(m_Renderer->Resolution().Height/TILE_SIZE);
//m_Frustums = new Frustum[s];
//m_LightGrid = new LightGrid[s];
//m_LightIndex = new float[s*200];
m_Frustums = new Frustum[m_NumberOfTiles]; m_Frustums = new Frustum[m_NumberOfTiles];
m_LightGrid = new LightGrid[m_NumberOfTiles]; m_LightGrid = new LightGrid[m_NumberOfTiles];
m_LightIndex = new float[m_NumberOfTiles*MAX_LIGHTS_PER_TILE]; m_LightIndex = new float[m_NumberOfTiles*MAX_LIGHTS_PER_TILE];
for (int i = 0; i < m_NumberOfTiles*MAX_LIGHTS_PER_TILE; i++) {
m_LightIndex[i] = -1;
}
} }
void LightCullingPass::CullLights(RenderScene& scene) void LightCullingPass::CullLights(RenderScene& scene)
@@ -59,8 +58,8 @@ void LightCullingPass::CullLights(RenderScene& scene)
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO);
if (m_PointLights.size() > 0) { if (m_LightSources.size() > 0) {
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(PointLight) * m_PointLights.size(), &(m_PointLights[0]), GL_DYNAMIC_COPY); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(LightSource) * m_LightSources.size(), &(m_LightSources[0]), GL_DYNAMIC_COPY);
} else { } else {
GLfloat zero = 0.f; GLfloat zero = 0.f;
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat), &zero , GL_DYNAMIC_COPY); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat), &zero , GL_DYNAMIC_COPY);
@@ -75,27 +74,38 @@ void LightCullingPass::CullLights(RenderScene& scene)
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO);
glDispatchCompute(m_Renderer->Resolution().Width / TILE_SIZE, m_Renderer->Resolution().Height / TILE_SIZE, 1); glDispatchCompute(glm::ceil(m_Renderer->Resolution().Width / TILE_SIZE), glm::ceil(m_Renderer->Resolution().Height / TILE_SIZE), 1);
GLERROR("CullLights Error: End"); GLERROR("CullLights Error: End");
} }
void LightCullingPass::FillLightList(RenderScene& scene) void LightCullingPass::FillLightList(RenderScene& scene)
{ {
m_PointLights.clear(); m_LightSources.clear();
for(auto &job : scene.PointLightJobs) { for(auto &job : scene.PointLightJobs) {
auto pointLightjob = std::dynamic_pointer_cast<PointLightJob>(job); auto pointLightjob = std::dynamic_pointer_cast<PointLightJob>(job);
if (pointLightjob) { if (pointLightjob) {
PointLight p; LightSource p;
p.Color = pointLightjob->Color; p.Color = pointLightjob->Color;
p.Falloff = pointLightjob->Falloff; p.Falloff = pointLightjob->Falloff;
p.Intensity = pointLightjob->Intensity; p.Intensity = pointLightjob->Intensity;
p.Position = glm::vec4(glm::vec3(pointLightjob->Position), 1.f); p.Position = glm::vec4(glm::vec3(pointLightjob->Position), 1.f);
p.Radius = pointLightjob->Radius; p.Radius = pointLightjob->Radius;
p.Padding = 123.f; //p.Padding = 123.f;
m_PointLights.push_back(p); p.Type = LightSource::Point;
continue; m_LightSources.push_back(p);
}
}
for(auto &job : scene.DirectionalLightJobs) {
auto directionalLightJob = std::dynamic_pointer_cast<DirectionalLightJob>(job);
if(directionalLightJob) {
LightSource p;
p.Direction = directionalLightJob->Direction;
p.Color = directionalLightJob->Color;
p.Intensity = directionalLightJob->Intensity;
p.Type = LightSource::Directional;
m_LightSources.push_back(p);
} }
} }
} }
@@ -104,25 +114,22 @@ void LightCullingPass::InitializeSSBOs()
{ {
glGenBuffers(1, &m_FrustumSSBO); glGenBuffers(1, &m_FrustumSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Frustum)*m_NumberOfTiles, m_Frustums, GL_DYNAMIC_COPY); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Frustum)*m_NumberOfTiles, nullptr, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_FrustumSSBO"); GLERROR("m_FrustumSSBO");
glGenBuffers(1, &m_LightSSBO); glGenBuffers(1, &m_LightSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO);
if(m_PointLights.size() > 0) { glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(LightSource) * 200, nullptr, GL_DYNAMIC_COPY);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(PointLight) * m_PointLights.size(), &(m_PointLights[0]), GL_DYNAMIC_COPY);
}
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightSSBO"); GLERROR("m_LightSSBO");
glGenBuffers(1, &m_LightGridSSBO); glGenBuffers(1, &m_LightGridSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightGridSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightGridSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(LightGrid)*m_NumberOfTiles, m_LightGrid, GL_DYNAMIC_COPY); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(LightGrid)*m_NumberOfTiles, nullptr, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLERROR("m_LightGridSSBO"); GLERROR("m_LightGridSSBO");
glGenBuffers(1, &m_LightOffsetSSBO); glGenBuffers(1, &m_LightOffsetSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY);

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