TDME2  1.9.200
BodyHierarchy.cpp
Go to the documentation of this file.
1 #include <string>
2 #include <vector>
3 
4 #include <tdme/tdme.h>
8 #include <tdme/math/Vector3.h>
10 
11 using std::make_unique;
12 using std::string;
13 using std::to_string;
14 using std::vector;
15 
21 
22 BodyHierarchy::BodyHierarchy(World* world, const string& id, BodyType type, uint16_t collisionTypeId, bool enabled, const Transform& transform, float restitution, float friction, float mass, const Vector3& inertiaTensor)
23  : Body(world, id, type, collisionTypeId, enabled, transform, restitution, friction, mass, inertiaTensor, {})
24 {
25 }
26 
28  //
29  for (auto subBody: bodies) {
30  Body::removeColliders(subBody->colliders, subBody->boundingVolumes);
31  delete subBody;
32  }
33 }
34 
35 
38  //
39  for (auto subBody: bodies) {
40  Body::resetColliders(subBody->colliders, subBody->boundingVolumes, subBody->transform);
41  }
42 }
43 
44 void BodyHierarchy::updateHierarchy(const Transform& parentTransform, BodyHierarchyLevel* bodyHierarchyLevel, int depth) {
45  BoundingBox entityBoundingBox;
46  auto levelParentTransform = parentTransform.clone();
47  levelParentTransform*= bodyHierarchyLevel->transform;
48  for (const auto& [childId, child]: bodyHierarchyLevel->children) {
49  //
50  Body::resetColliders(child->colliders, child->boundingVolumes, levelParentTransform * child->transform);
51  }
52  for (const auto& [childId, child]: bodyHierarchyLevel->children) {
53  updateHierarchy(levelParentTransform, child, depth + 1);
54  }
55 }
56 
57 void BodyHierarchy::addBody(const string& id, const Transform& transform, const vector<BoundingVolume*>& boundingVolumes, const string& parentId) {
58  auto _entity = getBody(id);
59  if (_entity != nullptr) {
60  Console::println("BodyHierarchy::addEntity(): " + id + ": body already added!");
61  return;
62  }
63 
64  //
65  removeBody(id);
66 
67  // add to hierarchy
68  auto parentBodyHierarchyLevel = getBodyHierarchyLevel(parentId);
69  if (parentBodyHierarchyLevel == nullptr) {
70  Console::println("BodyHierarchy::addBody(): parent '" + parentId + "': not found");
71  return;
72  }
73  // clone bounding volumes
74  vector<BoundingVolume*> clonedBoundingVolumes;
75  for (auto boundingVolume: boundingVolumes) {
76  clonedBoundingVolumes.push_back(boundingVolume->clone());
77  }
78  // finally create collision shapes
79  for (auto boundingVolume: clonedBoundingVolumes) {
80  boundingVolume->createCollisionShape(world);
81  }
82 
83  //
84  auto bodyHierarchyLevel = make_unique<BodyHierarchyLevel>(id, parentBodyHierarchyLevel, transform, clonedBoundingVolumes);
85  parentBodyHierarchyLevel->children[id] = bodyHierarchyLevel.get();
86 
87  // and bodies
88  bodies.push_back(bodyHierarchyLevel.get());
89 
90  //
91  bodyHierarchyLevel.release();
92 }
93 
94 void BodyHierarchy::updateBody(const string& id, const Transform& transform) {
95  auto bodyHierarchyLevel = getBodyHierarchyLevel(id);
96  if (bodyHierarchyLevel == nullptr || bodyHierarchyLevel->parent == nullptr) {
97  return;
98  }
99  //
100  bodyHierarchyLevel->transform = transform;
101 }
102 
103 void BodyHierarchy::removeBody(const string& id) {
104  // remove from hierarchy and bodies
105  auto bodyHierarchyLevel = getBodyHierarchyLevel(id);
106  if (bodyHierarchyLevel == nullptr || bodyHierarchyLevel->parent == nullptr) {
107  return;
108  }
109 
110  //
111  vector<string> children;
112  for (const auto& [childId, child]: bodyHierarchyLevel->children) children.push_back(childId);
113  for (auto child: children) removeBody(child);
114 
115  //
116  removeColliders(bodyHierarchyLevel->colliders, bodyHierarchyLevel->boundingVolumes);
117  bodies.erase(remove(bodies.begin(), bodies.end(), bodyHierarchyLevel), bodies.end());
118 
119  //
120  auto bodyHierarchyLevelIt = bodyHierarchyLevel->parent->children.find(id);
121  if (bodyHierarchyLevelIt != bodyHierarchyLevel->parent->children.end()) {
122  delete bodyHierarchyLevelIt->second;
123  bodyHierarchyLevel->parent->children.erase(bodyHierarchyLevelIt);
124  }
125 }
126 
127 const vector<BodyHierarchy::SubBody*> BodyHierarchy::query(const string& parentId) {
128  vector<SubBody*> subBodies;
129  auto parentBodyHierarchyLevel = getBodyHierarchyLevel(parentId);
130  if (parentBodyHierarchyLevel == nullptr) {
131  return subBodies;
132  }
133  for (const auto& [childId, child]: parentBodyHierarchyLevel->children) {
134  subBodies.push_back(child);
135  }
136  return subBodies;
137 }
138 
140  // we need the scale from our body transform to be passed as local transform when resetting colliders
141  Transform scaleTransform;
142  scaleTransform.setScale(transform.getScale());
143  scaleTransform.update();
144  // update hierarchy
145  updateHierarchy(scaleTransform, &bodyRoot, 0);
146  //
147  setTransform(this->transform);
148 }
Transform which contain scale, rotations and translation.
Definition: Transform.h:29
Transform clone() const
Clones the transform.
Definition: Transform.h:204
const Vector3 & getScale() const
Definition: Transform.h:71
void setScale(const Vector3 &scale)
Set scale.
Definition: Transform.h:79
virtual void update()
Computes transform matrix.
Definition: Transform.cpp:33
void updateBody(const string &id, const Transform &transform)
Updates a body from hierarchy by given unique body id.
void removeBody(const string &id)
Removes a body from hierarchy by given unique body id.
const SubBody * getBody(const string &id)
void updateHierarchy(const Transform &parentTransform, BodyHierarchyLevel *bodyHierarchyLevel, int depth)
Update hierarchy from given body hierarchy level ongoing.
BodyHierarchyLevel * getBodyHierarchyLevel(const string &id)
Get body hierarchy level by given body id.
Definition: BodyHierarchy.h:81
void resetColliders() override
Reset colliders.
void update()
Update body hierarchy.
void addBody(const string &id, const Transform &transform, const vector< BoundingVolume * > &boundingVolumes, const string &parentId=string())
Adds a body to the hierarchy.
const vector< SubBody * > query(const string &parentId=string())
Query sub bodies of parent body.
Rigid body class.
Definition: Body.h:41
vector< BoundingVolume * > boundingVolumes
Definition: Body.h:92
void setTransform(const Transform &transform)
Set transform.
Definition: Body.h:383
void removeColliders(vector< reactphysics3d::Collider * > &colliders, vector< BoundingVolume * > &boundingVolumes)
Remove colliders.
Definition: Body.cpp:139
virtual void resetColliders()
Reset body colliders.
Definition: Body.cpp:128
Dynamic physics world class.
Definition: World.h:38
Axis aligned bounding box used for frustum, this is not directly connectable with physics engine.
Definition: BoundingBox.h:26
Vector3 class representing vector3 mathematical structure and operations with x, y,...
Definition: Vector3.h:20
Console class.
Definition: Console.h:29
unordered_map< string, BodyHierarchyLevel * > children
Definition: BodyHierarchy.h:69