TDME2  1.9.200
EntityHierarchy.cpp
Go to the documentation of this file.
2 
3 #include <string>
4 
5 #include <tdme/tdme.h>
6 #include <tdme/engine/Engine.h>
7 #include <tdme/engine/Object.h>
10 #include <tdme/utilities/Console.h>
11 
12 using std::string;
13 
20 
21 EntityHierarchy::EntityHierarchy(const string& id): id(id)
22 {
23  this->enabled = true;
24  this->pickable = false;
25  this->contributesShadows = false;
26  this->receivesShadows = false;
27  this->effectColorMul.set(1.0f, 1.0f, 1.0f, 1.0f);
28  this->effectColorAdd.set(0.0f, 0.0f, 0.0f, 0.0f);
31 }
32 
34 {
35  for (auto entity: entities) delete entity;
36  for (const auto& [childEntityId, childEntity]: entityRoot.children) deleteHierarchy(childEntity, 0);
37 }
38 
39 void EntityHierarchy::deleteHierarchy(EntityHierarchyLevel* entityHierarchyLevel, int depth) {
40  for (const auto& [childEntityId, childEntity]: entityHierarchyLevel->children) deleteHierarchy(childEntity, depth + 1);
41  delete entityHierarchyLevel;
42 }
43 
45 {
46  if (this->engine != nullptr) this->engine->deregisterEntity(this);
47  this->engine = engine;
48  if (engine != nullptr) engine->registerEntity(this);
49  for (auto entity: entities) entity->setEngine(engine);
50 }
51 
53 {
54  this->renderer = renderer;
55  for (auto entity: entities) entity->setRenderer(renderer);
56 }
57 
58 void EntityHierarchy::addEntity(Entity* entity, const string& parentId) {
59  auto _entity = getEntity(entity->getId());
60  if (_entity == entity) {
61  Console::println("EntityHierarchy::addEntity(): " + entity->getId() + ": entity already added!");
62  return;
63  }
64 
65  //
66  removeEntity(entity->getId());
67 
68  // base properties
69  entity->setParentEntity(this);
70  entity->setEngine(engine);
71  entity->setRenderer(renderer);
72  entity->setPickable(pickable);
77  if (initialized == true) entity->initialize();
78 
79  // add to hierarchy
80  auto parentEntityHierarchyLevel = getEntityHierarchyLevel(parentId);
81  if (parentEntityHierarchyLevel == nullptr) {
82  Console::println("EntityHierarchy::addEntity(): parent '" + parentId + "': not found");
83  return;
84  }
85  parentEntityHierarchyLevel->children[entity->getId()] = new EntityHierarchyLevel(entity->getId(), parentEntityHierarchyLevel, entity);
86 
87  // and entities
88  entities.push_back(entity);
89 }
90 
91 void EntityHierarchy::removeEntity(const string& id) {
92  // remove from hierarchy and entities
93  auto entityHierarchyLevel = getEntityHierarchyLevel(id);
94  if (entityHierarchyLevel == nullptr || entityHierarchyLevel->parent == nullptr) {
95  return;
96  }
97 
98  //
99  vector<string> children;
100  for (const auto& [childEntityId, childEntity]: entityHierarchyLevel->children) children.push_back(childEntityId);
101  for (const auto& child: children) removeEntity(child);
102 
103  //
104  auto entity = entityHierarchyLevel->entity;
105  entities.erase(remove(entities.begin(), entities.end(), entity), entities.end());
106 
107  //
108  auto entityHierarchyLevelIt = entityHierarchyLevel->parent->children.find(id);
109  if (entityHierarchyLevelIt != entityHierarchyLevel->parent->children.end()) {
110  delete entityHierarchyLevelIt->second;
111  entityHierarchyLevel->parent->children.erase(entityHierarchyLevelIt);
112  }
113 
114  //
115  if (engine != nullptr) engine->removeEntityFromLists(entity);
116 
117  // dispose
118  entity->dispose();
119  delete entity;
120 }
121 
122 const vector<Entity*> EntityHierarchy::query(const string& parentId) {
123  vector<Entity*> entities;
124  auto parentEntityHierarchyLevel = getEntityHierarchyLevel(parentId);
125  if (parentEntityHierarchyLevel == nullptr) {
126  return entities;
127  }
128  for (const auto& [childEntityId, childEntity]: parentEntityHierarchyLevel->children) {
129  entities.push_back(childEntity->entity);
130  }
131  return entities;
132 }
133 
134 void EntityHierarchy::updateHierarchy(const Transform& parentTransform, EntityHierarchyLevel* entityHierarchyLevel, int depth, bool& firstEntity) {
135  BoundingBox entityBoundingBox;
136  auto levelParentTransform = parentTransform;
137  if (entityHierarchyLevel->entity != nullptr) levelParentTransform*= entityHierarchyLevel->entity->getTransform();
138  for (const auto& [childEntityId, childEntity]: entityHierarchyLevel->children) {
139  auto entity = childEntity->entity;
140  entity->setParentTransform(levelParentTransform);
141  entityBoundingBox.fromBoundingVolumeWithTransformMatrix(entity->getWorldBoundingBox(), entityTransformMatrixInverted);
142  if (firstEntity == true) {
143  boundingBox = entityBoundingBox;
144  firstEntity = false;
145  } else {
146  boundingBox.extend(&entityBoundingBox);
147  }
148  }
149  for (const auto& [childEntityId, childEntity]: entityHierarchyLevel->children) {
150  updateHierarchy(levelParentTransform, childEntity, depth + 1, firstEntity);
151  }
152  if (depth == 0) {
153  // bounding boxes
156  // update entity
157  if (parentEntity == nullptr && frustumCulling == true && engine != nullptr && enabled == true) engine->partition->updateEntity(this);
158  }
159 }
160 
162 {
163  //
164  Transform::setTransform(transform);
165  //
166  auto entityTransform = parentTransform * (*this);
167  entityTransformMatrix = entityTransform.getTransformMatrix();
168  //
170  // update hierarchy
171  auto firstEntity = true;
172  updateHierarchy(entityTransform, &entityRoot, 0, firstEntity);
173 }
174 
176 {
177  //
179  //
180  auto entityTransform = parentTransform * (*this);
181  entityTransformMatrix = entityTransform.getTransformMatrix();
182  //
184  // update hierarchy
185  auto firstEntity = true;
186  updateHierarchy(entityTransform, &entityRoot, 0, firstEntity);
187 }
188 
189 void EntityHierarchy::setEnabled(bool enabled)
190 {
191  // return if enable state has not changed
192  if (this->enabled == enabled) return;
193  // frustum if root entity
194  if (parentEntity == nullptr) {
195  // frustum culling enabled?
196  if (frustumCulling == true) {
197  // yeo, add or remove from partition
198  if (enabled == true) {
199  if (engine != nullptr) engine->partition->addEntity(this);
200  } else {
201  if (engine != nullptr) engine->partition->removeEntity(this);
202  }
203  }
204  }
205 }
206 
208  return frustumCulling;
209 }
210 
211 void EntityHierarchy::setFrustumCulling(bool frustumCulling) {
212  // check if enabled and engine attached
213  if (enabled == true && engine != nullptr) {
214  // had frustum culling
215  if (this->frustumCulling == true) {
216  // yep, remove if set to false now
217  if (frustumCulling == false) engine->partition->removeEntity(this);
218  } else {
219  // yep, add if set to true now
220  if (frustumCulling == true) engine->partition->addEntity(this);
221  }
222  }
223  this->frustumCulling = frustumCulling;
224  // delegate change to engine
225  if (engine != nullptr) engine->updateEntityRegistration(this);
226 }
227 
229 {
230  //
231  initialized = false;
232  //
233  // delegate to entities
234  for (auto entity: entities) {
235  if (engine != nullptr) engine->removeEntityFromLists(entity);
236  entity->dispose();
237  }
238 }
239 
241 {
242  //
243  initialized = true;
244  // delegate to entities
245  for (auto entity: entities) entity->initialize();
246 }
void set(float r, float g, float b, float a)
Sets this color by its components.
Definition: Color4.h:66
Engine main class.
Definition: Engine.h:131
unique_ptr< Partition > partition
Definition: Engine.h:289
void updateEntityRegistration(Entity *entity)
Updates registration of engine by performing deregisterEntity() and registerEntity()
Definition: Engine.h:1489
void deregisterEntity(Entity *entity)
Removes a entity from internal lists, those entities can also be sub entities from entity hierarchy o...
Definition: Engine.cpp:382
void removeEntityFromLists(Entity *entity)
Remove entity.
Definition: Engine.cpp:674
void registerEntity(Entity *entity)
Adds a entity to internal lists, those entities can also be sub entities from entity hierarchy or par...
Definition: Engine.cpp:437
Entity hierarchy to be used with engine class.
void updateHierarchy(const Transform &parentTransform, EntityHierarchyLevel *entityHierarchyLevel, int depth, bool &firstEntity)
Update hierarchy from given entity hierarchy level ongoing.
void dispose() override
Dispose this entity.
void initialize() override
Initiates this entity.
void update() override
Update transform.
void addEntity(Entity *entity, const string &parentId=string())
Adds a entity to the hierarchy.
void setTransform(const Transform &transform) override
Set transform.
void deleteHierarchy(EntityHierarchyLevel *entityHierarchyLevel, int depth)
Delete hierarchy from given entity hierarchy level ongoing.
EntityHierarchyLevel entityRoot
EntityHierarchyLevel * getEntityHierarchyLevel(const string &id)
Get entity hierarchy level by given entity id.
const vector< Entity * > query(const string &parentId=string())
Query sub entities of parent entity.
void removeEntity(const string &id)
Removes a entity from hierarchy by given unique entity id.
void setFrustumCulling(bool frustumCulling) override
Set frustum culling.
void setEngine(Engine *engine) override
Set up engine.
Entity * getEntity(const string &id)
void setEnabled(bool enabled) override
Enable/disable rendering.
virtual ~EntityHierarchy()
Destructor.
void setRenderer(Renderer *renderer) override
Set up renderer.
Engine entity.
Definition: Entity.h:30
virtual void setRenderer(Renderer *renderer)=0
Set up renderer.
virtual const string & getId()=0
virtual void setEngine(Engine *engine)=0
Set up engine.
virtual void setEffectColorMul(const Color4 &effectColorMul)=0
Set effect color that will be multiplied with fragment color.
virtual const Transform & getTransform() const =0
Entity * parentEntity
Definition: Entity.h:39
virtual void initialize()=0
Initiates this entity.
virtual void setContributesShadows(bool contributesShadows)=0
Enable/disable contributes shadows.
void setParentEntity(Entity *entity)
Set parent entity, needs to be called before adding to engine.
Definition: Entity.h:45
virtual void setPickable(bool pickable)=0
Set this entity pickable.
virtual void setReceivesShadows(bool receivesShadows)=0
Enable/disable receives shadows.
virtual void setEffectColorAdd(const Color4 &effectColorAdd)=0
Set effect color that will be added to fragment color.
Object to be used with engine class.
Definition: Object.h:60
Transform which contain scale, rotations and translation.
Definition: Transform.h:29
virtual void setTransform(const Transform &transform)
Set transform.
Definition: Transform.h:177
virtual void update()
Computes transform matrix.
Definition: Transform.cpp:33
Axis aligned bounding box used for frustum, this is not directly connectable with physics engine.
Definition: BoundingBox.h:26
void extend(BoundingBox *boundingBox)
Extend bounding box with given bounding box.
Definition: BoundingBox.h:158
void fromBoundingVolumeWithTransformMatrix(BoundingBox *original, const Matrix4x4 &transformMatrix)
Create bounding volume from given original(of same type) with applied transform matrix.
Definition: BoundingBox.cpp:79
void update()
Updates this bounding box.
Matrix4x4 clone() const
Clones this matrix.
Definition: Matrix4x4.h:619
Matrix4x4 & identity()
Creates identity matrix.
Definition: Matrix4x4.h:158
Matrix4x4 & invert()
Inverts this matrix.
Definition: Matrix4x4.h:479
Console class.
Definition: Console.h:29
unordered_map< string, EntityHierarchyLevel * > children
Partition interface.
Definition: Partition.h:18