diff --git a/src/Component.h b/src/Component.h index 21d59f6..05e0628 100755 --- a/src/Component.h +++ b/src/Component.h @@ -7,6 +7,8 @@ struct Component { EntityID Entity; + + virtual Component* Clone() const = 0; }; class ComponentFactory : public Factory { }; diff --git a/src/Components/Box.h b/src/Components/Box.h index b9ddea7..3fe3687 100644 --- a/src/Components/Box.h +++ b/src/Components/Box.h @@ -14,6 +14,8 @@ struct Box : Component float Width; float Height; float Depth; + + virtual Box* Clone() const override { return new Box(*this); } }; } diff --git a/src/Components/Camera.h b/src/Components/Camera.h index 2cd379d..91e55b5 100755 --- a/src/Components/Camera.h +++ b/src/Components/Camera.h @@ -13,6 +13,8 @@ struct Camera : Component float FOV; float NearClip; float FarClip; + + virtual Camera* Clone() const override { return new Camera(*this); } }; } diff --git a/src/Components/DirectionalLight.h b/src/Components/DirectionalLight.h index ee2dd72..1d7de1e 100755 --- a/src/Components/DirectionalLight.h +++ b/src/Components/DirectionalLight.h @@ -13,6 +13,8 @@ struct DirectionalLight : Component float MaxRange; float SpecularIntensity; Color Color; + + virtual DirectionalLight* Clone() const override { return new DirectionalLight(*this); } }; } diff --git a/src/Components/FreeSteering.h b/src/Components/FreeSteering.h index a972eaf..ba40534 100755 --- a/src/Components/FreeSteering.h +++ b/src/Components/FreeSteering.h @@ -9,6 +9,8 @@ struct FreeSteering : Component { FreeSteering() : Speed(35) { } float Speed; + + virtual FreeSteering* Clone() const override { return new FreeSteering(*this); } }; } diff --git a/src/Components/Input.h b/src/Components/Input.h index b1c11b5..15cb286 100755 --- a/src/Components/Input.h +++ b/src/Components/Input.h @@ -18,6 +18,8 @@ struct Input : Component std::array LastMouseState; float dX, dY; float WheelDelta; + + virtual Input* Clone() const override { return new Input(*this); } }; } diff --git a/src/Components/Model.h b/src/Components/Model.h index ad3b4f3..cacfe17 100755 --- a/src/Components/Model.h +++ b/src/Components/Model.h @@ -16,6 +16,8 @@ struct Model : Component Color Color; bool Visible; bool ShadowCaster; + + virtual Model* Clone() const override { return new Model(*this); } }; } diff --git a/src/Components/Particle.h b/src/Components/Particle.h index b169ee2..dfa3075 100644 --- a/src/Components/Particle.h +++ b/src/Components/Particle.h @@ -16,6 +16,8 @@ namespace Components double LifeTime; std::vector VelocitySpectrum; std::vector AngularVelocitySpectrum; + + virtual Particle* Clone() const override { return new Particle(*this); } }; } diff --git a/src/Components/ParticleEmitter.h b/src/Components/ParticleEmitter.h index 46ad8fb..5aafcdc 100755 --- a/src/Components/ParticleEmitter.h +++ b/src/Components/ParticleEmitter.h @@ -24,6 +24,8 @@ struct ParticleEmitter : Component std::vector VelocitySpectrum; std::vector AngularVelocitySpectrum; + virtual ParticleEmitter* Clone() const override { return new ParticleEmitter(*this); } + private: double TimeSinceLastSpawn; }; diff --git a/src/Components/Physics.h b/src/Components/Physics.h index 956ae7a..98a682f 100644 --- a/src/Components/Physics.h +++ b/src/Components/Physics.h @@ -12,6 +12,8 @@ struct Physics : Component : Mass(0.f) { } float Mass; + + virtual Physics* Clone() const override { return new Physics(*this); } }; } diff --git a/src/Components/PointLight.h b/src/Components/PointLight.h index a7a5d4a..248fec6 100755 --- a/src/Components/PointLight.h +++ b/src/Components/PointLight.h @@ -16,6 +16,8 @@ struct PointLight : Component float constantAttenuation, linearAttenuation, quadraticAttenuation; float spotExponent; Color color; + + virtual PointLight* Clone() const override { return new PointLight(*this); } }; } diff --git a/src/Components/SoundEmitter.h b/src/Components/SoundEmitter.h index b4c74ee..05c5f15 100755 --- a/src/Components/SoundEmitter.h +++ b/src/Components/SoundEmitter.h @@ -17,6 +17,8 @@ struct SoundEmitter : Component float Pitch; bool Loop; std::string Path; + + virtual SoundEmitter* Clone() const override { return new SoundEmitter(*this); } }; } diff --git a/src/Components/Sphere.h b/src/Components/Sphere.h index 2d089dd..f92e418 100644 --- a/src/Components/Sphere.h +++ b/src/Components/Sphere.h @@ -12,6 +12,8 @@ struct Sphere : Component : Radius(1.f){ } float Radius; + + virtual Sphere* Clone() const override { return new Sphere(*this); } }; } diff --git a/src/Components/Sprite.h b/src/Components/Sprite.h index f54d3d0..29c930f 100755 --- a/src/Components/Sprite.h +++ b/src/Components/Sprite.h @@ -13,6 +13,8 @@ struct Sprite : Component { std::string SpriteFile; Color Color; + + virtual Sprite* Clone() const override { return new Sprite(*this); } }; } diff --git a/src/Components/Template.h b/src/Components/Template.h index 4bcb25c..613622c 100755 --- a/src/Components/Template.h +++ b/src/Components/Template.h @@ -6,7 +6,12 @@ namespace Components { -struct Template : Component { }; +struct Template + : public Component +{ + virtual Template* Clone() const override { return nullptr; } +}; } + #endif // !Components_Template_h__ \ No newline at end of file diff --git a/src/Components/Transform.h b/src/Components/Transform.h index 2bfd58d..26b701e 100755 --- a/src/Components/Transform.h +++ b/src/Components/Transform.h @@ -6,7 +6,7 @@ namespace Components { -struct Transform : Component +struct Transform : public Component { Transform() : Scale(glm::vec3(1.f)) { } @@ -15,6 +15,8 @@ struct Transform : Component glm::quat Orientation; glm::vec3 Velocity; glm::vec3 Scale; + + virtual Transform* Clone() const override { return new Transform(*this); } }; } diff --git a/src/World.cpp b/src/World.cpp index 78b297d..ef9d236 100755 --- a/src/World.cpp +++ b/src/World.cpp @@ -93,6 +93,7 @@ void World::ProcessEntityRemovals() for (auto entity : m_EntitiesToRemove) { m_EntityParents.erase(entity); + m_EntityChildren.erase(entity); // Remove components for (auto pair : m_EntityComponents[entity]) { @@ -116,7 +117,8 @@ void World::ProcessEntityRemovals() EntityID World::CreateEntity(EntityID parent /*= 0*/) { EntityID newEntity = GenerateEntityID(); - m_EntityParents.insert(std::pair(newEntity, parent)); + m_EntityParents[newEntity] = parent; + m_EntityChildren[parent].push_back(newEntity); return newEntity; } @@ -148,7 +150,58 @@ std::shared_ptr World::AddComponent(EntityID entity, std::string comp return AddComponent(entity, componentType); } +void World::AddComponent(EntityID entity, std::string componentType, std::shared_ptr component) +{ + component->Entity = entity; + m_ComponentsOfType[componentType].push_back(component); + m_EntityComponents[entity][componentType] = component; + for (auto pair : m_Systems) + { + auto system = pair.second; + system->OnComponentCreated(componentType, component); + } +} + void World::AddSystem(std::string systemType) { m_Systems[systemType] = std::shared_ptr(m_SystemFactory.Create(systemType)); } + +EntityID World::CloneEntity(EntityID entity, EntityID parent /* = 0 */) +{ + int clone = CreateEntity(parent); + + for (auto pair : m_EntityComponents[entity]) + { + auto type = pair.first; + auto component = std::shared_ptr(pair.second->Clone()); + if (component != nullptr) + { + AddComponent(clone, type, component); + } + } + + auto itChildren = m_EntityChildren.find(entity); + if (itChildren != m_EntityChildren.end()) + { + for (EntityID child : itChildren->second) + { + CloneEntity(child, clone); + } + } + + return clone; +} + +std::list World::GetEntityChildren(EntityID entity) +{ + auto it = m_EntityChildren.find(entity); + if (it == m_EntityChildren.end()) + { + return std::list(); + } + else + { + return it->second; + } +} diff --git a/src/World.h b/src/World.h index 9deeab9..d0c0692 100755 --- a/src/World.h +++ b/src/World.h @@ -34,6 +34,7 @@ public: std::shared_ptr GetSystem(std::string systemType); EntityID CreateEntity(EntityID parent = 0); + EntityID CloneEntity(EntityID entity, EntityID parent = 0); void RemoveEntity(EntityID entity); @@ -41,6 +42,7 @@ public: EntityID GetEntityParent(EntityID entity); EntityID GetEntityBaseParent(EntityID entity); + std::list GetEntityChildren(EntityID entity); template T GetProperty(EntityID entity, std::string property) @@ -83,13 +85,16 @@ protected: EntityID m_LastEntityID; std::stack m_RecycledEntityIDs; - // A bottom to top tree. A map of child entities to parent entities. - std::unordered_map m_EntityParents; - std::unordered_map> m_EntityProperties; + std::unordered_map m_EntityParents; // child -> parent + std::unordered_map> m_EntityChildren; // parent -> child + std::unordered_map> m_EntityProperties; std::unordered_map>> m_ComponentsOfType; std::unordered_map>> m_EntityComponents; + // Internal: Add a component to an entity + void AddComponent(EntityID entity, std::string componentType, std::shared_ptr component); + std::list m_EntitiesToRemove; void ProcessEntityRemovals(); @@ -121,14 +126,8 @@ std::shared_ptr World::AddComponent(EntityID entity, std::string componentTyp return nullptr; } - component->Entity = entity; - m_ComponentsOfType[componentType].push_back(component); - m_EntityComponents[entity][componentType] = component; - for (auto pair : m_Systems) - { - auto system = pair.second; - system->OnComponentCreated(componentType, component); - } + AddComponent(entity, componentType, component); + return component; } diff --git a/vs11/Returngeance/Returngeance.vcxproj.filters b/vs11/Returngeance/Returngeance.vcxproj.filters index 35f6ce6..2e7f203 100755 --- a/vs11/Returngeance/Returngeance.vcxproj.filters +++ b/vs11/Returngeance/Returngeance.vcxproj.filters @@ -215,14 +215,18 @@ Audio - - Particle System\Systems Particle System\Components + + Physics\Components + + + Physics\Components +