Fixed so calculating absolute positions, etc. works. Sets the field of all children to dirty if a transform field is altered. Will also set Position to dirty if Scale or Orientation is altered.
Moved some methods in ComponentWrapper to a .cpp.
This commit is contained in:
@@ -43,9 +43,10 @@ public:
|
|||||||
typedef ComponentWrapper* pointer;
|
typedef ComponentWrapper* pointer;
|
||||||
typedef ComponentWrapper& reference;
|
typedef ComponentWrapper& reference;
|
||||||
|
|
||||||
ComponentPool(const ::ComponentInfo& ci)
|
ComponentPool(const ::ComponentInfo& ci, World* world)
|
||||||
: m_ComponentInfo(ci)
|
: m_ComponentInfo(ci)
|
||||||
, m_Pool(ci.Meta->Allocation, ci.GetHeaderSize() + ci.Stride)
|
, m_Pool(ci.Meta->Allocation, ci.GetHeaderSize() + ci.Stride)
|
||||||
|
, m_World(world)
|
||||||
{ }
|
{ }
|
||||||
~ComponentPool();
|
~ComponentPool();
|
||||||
ComponentPool(const ComponentPool& other);
|
ComponentPool(const ComponentPool& other);
|
||||||
@@ -82,6 +83,7 @@ private:
|
|||||||
MemoryPool<char> m_Pool;
|
MemoryPool<char> m_Pool;
|
||||||
std::unordered_map<EntityID, char*> m_EntityToComponent;
|
std::unordered_map<EntityID, char*> m_EntityToComponent;
|
||||||
DirtySet m_DirtySet;
|
DirtySet m_DirtySet;
|
||||||
|
World* m_World;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -10,56 +10,25 @@
|
|||||||
#include "DirtySet.h"
|
#include "DirtySet.h"
|
||||||
#include "Util/Any.h"
|
#include "Util/Any.h"
|
||||||
|
|
||||||
|
class World;
|
||||||
|
|
||||||
struct ComponentWrapper
|
struct ComponentWrapper
|
||||||
{
|
{
|
||||||
ComponentWrapper(const ComponentInfo& componentInfo, char* data, ::DirtyBitField* dirtyBitField)
|
ComponentWrapper(const ComponentInfo& componentInfo, char* data, ::DirtyBitField* dirtyBitField, World* world);
|
||||||
: Info(componentInfo)
|
|
||||||
, EntityID(*reinterpret_cast<::EntityID*>(data))
|
|
||||||
, Data(data + componentInfo.GetHeaderSize())
|
|
||||||
, DirtyBitField(dirtyBitField)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
|
World* m_World;
|
||||||
const ComponentInfo& Info;
|
const ComponentInfo& Info;
|
||||||
const ::EntityID EntityID;
|
const ::EntityID EntityID;
|
||||||
char* Data;
|
char* Data;
|
||||||
::DirtyBitField* DirtyBitField = nullptr;
|
::DirtyBitField* DirtyBitField = nullptr;
|
||||||
|
|
||||||
ComponentInfo::EnumType Enum(const char* fieldName, const char* enumKey)
|
ComponentInfo::EnumType Enum(const char* fieldName, const char* enumKey);
|
||||||
{
|
|
||||||
return Info.Meta->FieldEnumDefinitions.at(fieldName).at(enumKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Dirty(DirtySetType type, const std::string& fieldName)
|
bool Dirty(DirtySetType type, const std::string& fieldName);
|
||||||
{
|
|
||||||
if (DirtyBitField == nullptr) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
auto& field = Info.Fields.at(fieldName);
|
|
||||||
return DirtyBitField->operator[](type).count(field.Index) == 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetDirty(DirtySetType type, const std::string& fieldName, bool dirty = true)
|
void SetDirty(DirtySetType type, const std::string& fieldName, bool dirty = true);
|
||||||
{
|
|
||||||
if (DirtyBitField == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& field = Info.Fields.at(fieldName);
|
void SetAllDirty(const std::string& fieldName, bool dirty = true);
|
||||||
if (dirty) {
|
|
||||||
DirtyBitField->operator[](type).insert(field.Index);
|
|
||||||
} else {
|
|
||||||
DirtyBitField->operator[](type).erase(field.Index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetAllDirty(const std::string& fieldName, bool dirty = true)
|
|
||||||
{
|
|
||||||
for (auto& kv : *DirtyBitField) {
|
|
||||||
SetDirty(kv.first, fieldName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T& Field(const std::string& name)
|
T& Field(const std::string& name)
|
||||||
@@ -271,7 +240,7 @@ struct Field<glm::vec4> : FieldBase<glm::vec4>
|
|||||||
struct SharedComponentWrapper : ComponentWrapper
|
struct SharedComponentWrapper : ComponentWrapper
|
||||||
{
|
{
|
||||||
SharedComponentWrapper(const ComponentInfo& componentInfo, boost::shared_array<char> data)
|
SharedComponentWrapper(const ComponentInfo& componentInfo, boost::shared_array<char> data)
|
||||||
: ComponentWrapper(componentInfo, data.get(), nullptr)
|
: ComponentWrapper(componentInfo, data.get(), nullptr, nullptr)
|
||||||
, m_DataReference(data)
|
, m_DataReference(data)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ ComponentWrapper ComponentPoolForwardIterator::operator*() const
|
|||||||
{
|
{
|
||||||
char* data = &(*m_MemoryPoolIterator);
|
char* data = &(*m_MemoryPoolIterator);
|
||||||
EntityID entity = *reinterpret_cast<EntityID*>(data);
|
EntityID entity = *reinterpret_cast<EntityID*>(data);
|
||||||
ComponentWrapper wrapper(m_ComponentInfo, data, &m_ComponentPool->m_DirtySet[entity]);
|
ComponentWrapper wrapper(m_ComponentInfo, data, &m_ComponentPool->m_DirtySet[entity], m_ComponentPool->m_World);
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ ComponentWrapper ComponentPool::Allocate(EntityID entity)
|
|||||||
memcpy(data, &entity, sizeof(EntityID));
|
memcpy(data, &entity, sizeof(EntityID));
|
||||||
|
|
||||||
m_EntityToComponent[entity] = data;
|
m_EntityToComponent[entity] = data;
|
||||||
ComponentWrapper component(m_ComponentInfo, data, &m_DirtySet[entity]);
|
ComponentWrapper component(m_ComponentInfo, data, &m_DirtySet[entity], m_World);
|
||||||
|
|
||||||
// Copy defaults
|
// Copy defaults
|
||||||
memcpy(component.Data, m_ComponentInfo.Defaults.get(), m_ComponentInfo.Stride);
|
memcpy(component.Data, m_ComponentInfo.Defaults.get(), m_ComponentInfo.Stride);
|
||||||
@@ -92,7 +92,7 @@ ComponentWrapper ComponentPool::GetByEntity(EntityID ent)
|
|||||||
{
|
{
|
||||||
auto data = m_EntityToComponent.at(ent);
|
auto data = m_EntityToComponent.at(ent);
|
||||||
auto bitField = &m_DirtySet[ent];
|
auto bitField = &m_DirtySet[ent];
|
||||||
return ComponentWrapper(m_ComponentInfo, data, bitField);
|
return ComponentWrapper(m_ComponentInfo, data, bitField, m_World);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ComponentPool::KnowsEntity(EntityID ent)
|
bool ComponentPool::KnowsEntity(EntityID ent)
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#include "Core/World.h"
|
||||||
|
#include "Core/ComponentWrapper.h"
|
||||||
|
|
||||||
|
ComponentWrapper::ComponentWrapper(const ComponentInfo& componentInfo, char* data, ::DirtyBitField* dirtyBitField, World* world)
|
||||||
|
: Info(componentInfo)
|
||||||
|
, EntityID(*reinterpret_cast<::EntityID*>(data))
|
||||||
|
, Data(data + componentInfo.GetHeaderSize())
|
||||||
|
, DirtyBitField(dirtyBitField)
|
||||||
|
, m_World(world)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ComponentInfo::EnumType ComponentWrapper::Enum(const char* fieldName, const char* enumKey)
|
||||||
|
{
|
||||||
|
return Info.Meta->FieldEnumDefinitions.at(fieldName).at(enumKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ComponentWrapper::Dirty(DirtySetType type, const std::string& fieldName)
|
||||||
|
{
|
||||||
|
if (DirtyBitField == nullptr) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
auto& field = Info.Fields.at(fieldName);
|
||||||
|
return DirtyBitField->operator[](type).count(field.Index) == 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComponentWrapper::SetDirty(DirtySetType type, const std::string& fieldName, bool dirty /* = true */)
|
||||||
|
{
|
||||||
|
if (DirtyBitField == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& field = Info.Fields.at(fieldName);
|
||||||
|
if (dirty) {
|
||||||
|
DirtyBitField->operator[](type).insert(field.Index);
|
||||||
|
// Because parents affects children when altered, we also need to flag all children as dirty.
|
||||||
|
if (type == DirtySetType::Transform && m_World != nullptr) {
|
||||||
|
auto children = m_World->GetDirectChildren(EntityID);
|
||||||
|
for (auto kv = children.first; kv != children.second; ++kv) {
|
||||||
|
const auto& child = kv->second;
|
||||||
|
if (m_World->HasComponent(child, Info.Name)) {
|
||||||
|
m_World->GetComponent(child, Info.Name).SetDirty(DirtySetType::Transform, fieldName, true);
|
||||||
|
if (fieldName == "Orientation" || fieldName == "Scale") {
|
||||||
|
m_World->GetComponent(child, Info.Name).SetDirty(DirtySetType::Transform, "Position", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DirtyBitField->operator[](type).erase(field.Index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComponentWrapper::SetAllDirty(const std::string& fieldName, bool dirty /* = true */)
|
||||||
|
{
|
||||||
|
for (auto& kv : *DirtyBitField) {
|
||||||
|
SetDirty(kv.first, fieldName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -51,10 +51,6 @@ glm::vec3 Transform::AbsolutePosition(EntityWrapper entity)
|
|||||||
RecalculatedPositions++;
|
RecalculatedPositions++;
|
||||||
// Unset dirty flag
|
// Unset dirty flag
|
||||||
cTransformPosition.SetDirty(DirtySetType::Transform, false);
|
cTransformPosition.SetDirty(DirtySetType::Transform, false);
|
||||||
// Flag children as dirty
|
|
||||||
for (auto& child : entity.ChildrenWithComponent("Transform")) {
|
|
||||||
child["Transform"]["Position"].SetDirty(DirtySetType::Transform, true);
|
|
||||||
}
|
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,10 +93,6 @@ glm::quat Transform::AbsoluteOrientation(EntityWrapper entity)
|
|||||||
RecalculatedOrientations++;
|
RecalculatedOrientations++;
|
||||||
// Unset dirty flag
|
// Unset dirty flag
|
||||||
cTransformOrientation.SetDirty(DirtySetType::Transform, false);
|
cTransformOrientation.SetDirty(DirtySetType::Transform, false);
|
||||||
// Flag children as dirty
|
|
||||||
for (auto& child : entity.ChildrenWithComponent("Transform")) {
|
|
||||||
child["Transform"]["Orientation"].SetDirty(DirtySetType::Transform, true);
|
|
||||||
}
|
|
||||||
return orientation;
|
return orientation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,10 +122,6 @@ glm::vec3 Transform::AbsoluteScale(EntityWrapper entity)
|
|||||||
RecalculatedPositions++;
|
RecalculatedPositions++;
|
||||||
// Unset dirty flag
|
// Unset dirty flag
|
||||||
cTransformScale.SetDirty(DirtySetType::Transform, false);
|
cTransformScale.SetDirty(DirtySetType::Transform, false);
|
||||||
// Flag children as dirty
|
|
||||||
for (auto& child : entity.ChildrenWithComponent("Transform")) {
|
|
||||||
child["Transform"]["Scale"].SetDirty(DirtySetType::Transform, true);
|
|
||||||
}
|
|
||||||
return scale;
|
return scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ bool World::ValidEntity(EntityID entity) const
|
|||||||
void World::RegisterComponent(const ComponentInfo& ci)
|
void World::RegisterComponent(const ComponentInfo& ci)
|
||||||
{
|
{
|
||||||
if (m_ComponentPools.find(ci.Name) == m_ComponentPools.end()) {
|
if (m_ComponentPools.find(ci.Name) == m_ComponentPools.end()) {
|
||||||
m_ComponentPools[ci.Name] = new ComponentPool(ci);
|
m_ComponentPools[ci.Name] = new ComponentPool(ci, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -178,7 +178,6 @@ void RenderSystem::fillSprites(std::list<std::shared_ptr<RenderJob>>& jobs, Worl
|
|||||||
|
|
||||||
bool RenderSystem::isEntityVisible(EntityWrapper& entity)
|
bool RenderSystem::isEntityVisible(EntityWrapper& entity)
|
||||||
{
|
{
|
||||||
return true;
|
|
||||||
// Only render children of a camera if that camera is currently active
|
// Only render children of a camera if that camera is currently active
|
||||||
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user