TDME2  1.9.200
Model.cpp
Go to the documentation of this file.
2 
3 #include <algorithm>
4 #include <map>
5 #include <memory>
6 #include <string>
7 
8 #include <tdme/tdme.h>
12 #include <tdme/engine/model/Node.h>
20 #include <tdme/math/Matrix4x4.h>
22 
23 using std::make_unique;
24 using std::map;
25 using std::sort;
26 using std::string;
27 using std::unique_ptr;
28 
43 
44 string Model::ANIMATIONSETUP_DEFAULT = "tdme.default";
45 uint32_t Model::uidCounter = 0;
46 
47 constexpr float Model::FPS_DEFAULT;
48 
49 Model::Model(const string& id, const string& name, UpVector* upVector, RotationOrder* rotationOrder, BoundingBox* boundingBox, AuthoringTool authoringTool)
50 {
51  this->uniqueId = AtomicOperations::increment(uidCounter);
52  this->id = id + ":uid=" + to_string(this->uniqueId);
53  this->name = name;
54  this->upVector = upVector;
55  this->rotationOrder = rotationOrder;
57  skinning = false;
58  fps = FPS_DEFAULT;
60  this->boundingBox = unique_ptr<BoundingBox>(boundingBox);
61  this->authoringTool = authoringTool;
62  this->boundingBoxUpdated = false;
63  this->embedSpecularTextures = false;
64  this->embedPBRTextures = false;
65 }
66 
69  for (const auto& [materialId, material]: materials) delete material;
70  for (const auto& [animationSetupId, animationSetup]: animationSetups) delete animationSetup;
71 }
72 
73 void Model::deleteSubNodes(const unordered_map<string, Node*>& subNodes) {
74  for (const auto& [subNodeId, subNode]: subNodes) {
75  deleteSubNodes(subNode->getSubNodes());
76  delete subNode;
77  }
78 }
79 
80 const vector<string> Model::getMaterialIds() {
81  vector<string> result;
82  for (const auto& [materialId, material]: materials) result.push_back(material->getId());
83  sort(result.begin(), result.end());
84  return result;
85 }
86 
87 const vector<string> Model::getNodeIds() {
88  vector<string> result;
89  for (const auto& [nodeId, node]: nodes) result.push_back(node->getId());
90  sort(result.begin(), result.end());
91  return result;
92 }
93 
94 const vector<string> Model::getAnimationSetupIds() {
95  vector<string> result;
96  for (const auto& [animationSetupId, animationSetup]: animationSetups) result.push_back(animationSetup->getId());
97  sort(result.begin(), result.end());
98  return result;
99 }
100 
101 AnimationSetup* Model::addAnimationSetup(const string& id, int32_t startFrame, int32_t endFrame, bool loop, float speed)
102 {
103  auto animationSetupIt = animationSetups.find(id);
104  if (animationSetupIt != animationSetups.end()) {
105  delete animationSetupIt->second;
106  animationSetups.erase(animationSetupIt);
107  }
108  auto animationSetup = make_unique<AnimationSetup>(this, id, startFrame, endFrame, loop, string(), speed);
109  animationSetups[id] = animationSetup.get();
110  return animationSetup.release();
111 }
112 
113 AnimationSetup* Model::addOverlayAnimationSetup(const string& id, const string& overlayFromNodeId, int32_t startFrame, int32_t endFrame, bool loop, float speed)
114 {
115  auto animationSetupIt = animationSetups.find(id);
116  if (animationSetupIt != animationSetups.end()) {
117  delete animationSetupIt->second;
118  animationSetups.erase(animationSetupIt);
119  }
120  auto animationSetup = make_unique<AnimationSetup>(this, id, startFrame, endFrame, loop, overlayFromNodeId, speed);
121  animationSetups[id] = animationSetup.get();
122  return animationSetup.release();
123 }
124 
125 bool Model::renameAnimationSetup(const string& id, const string& newId) {
126  auto animationSetupIt = animationSetups.find(id);
127  if (animationSetupIt == animationSetups.end()) return false;
128  auto animationSetup = animationSetupIt->second;
129  animationSetups.erase(animationSetupIt);
130  animationSetup->setId(newId);
131  animationSetups[newId] = animationSetup;
132  return true;
133 }
134 
135 bool Model::removeAnimationSetup(const string& id) {
136  auto animationSetupIt = animationSetups.find(id);
137  if (animationSetupIt == animationSetups.end()) return false;
138  delete animationSetupIt->second;
139  animationSetups.erase(animationSetupIt);
140  return true;
141 }
142 
144  for (const auto& [animationSetupId, animationSetup]: animationSetups) {
145  delete animationSetup;
146  }
147  animationSetups.clear();
148 }
149 
151 {
152  // TODO: return const bb
153  if (boundingBox == nullptr) {
154  boundingBox = unique_ptr<BoundingBox>(ModelUtilities::createBoundingBox(this));
155  }
156  return boundingBox.get();
157 }
158 
159 bool Model::computeTransformMatrix(const unordered_map<string, Node*>& nodes, const Matrix4x4& parentTransformMatrix, int32_t frame, const string& nodeId, Matrix4x4& transformMatrix)
160 {
161  // TODO: this should be computed from sub nodes to root node, not the other way around, also it looks broken to me right now, but works for our cases so far
162  // iterate through nodes
163  for (const auto& [subNodeId, subNode]: nodes) {
164  // compute animation matrix if animation setups exist
165  auto animation = subNode->getAnimation();
166  if (animation != nullptr && frame != -1) {
167  const auto& animationMatrices = animation->getTransformMatrices();
168  transformMatrix.set(animationMatrices[frame % animationMatrices.size()]);
169  } else {
170  // no animation matrix, set up local transform matrix up as node matrix
171  transformMatrix.set(subNode->getTransformMatrix());
172  }
173 
174  // apply parent transform matrix
175  transformMatrix.multiply(parentTransformMatrix);
176 
177  // return matrix if node matches
178  if (subNode->getId() == nodeId) return true;
179 
180  // calculate sub nodes
181  const auto& subNodes = subNode->getSubNodes();
182  if (subNodes.size() > 0) {
183  auto haveTransformMatrix = computeTransformMatrix(subNodes, transformMatrix.clone(), frame, nodeId, transformMatrix);
184  if (haveTransformMatrix == true) return true;
185  }
186  }
187 
188  //
189  return false;
190 }
191 
193  boundingBox = nullptr;
194  boundingBoxUpdated = true;
195 }
Represents a material.
Definition: Material.h:23
Representation of a 3D model.
Definition: Model.h:35
const vector< string > getMaterialIds()
Definition: Model.cpp:80
~Model()
Deconstructor.
Definition: Model.cpp:67
void clearAnimationSetups()
Clear animation setups.
Definition: Model.cpp:143
AuthoringTool authoringTool
Definition: Model.h:46
unordered_map< string, Node * > nodes
Definition: Model.h:54
void invalidateBoundingBox()
Invalidates bounding box.
Definition: Model.cpp:192
bool removeAnimationSetup(const string &id)
Remove animation setup.
Definition: Model.cpp:135
unordered_map< string, Node * > subNodes
Definition: Model.h:55
RotationOrder * rotationOrder
Definition: Model.h:51
static constexpr STATIC_DLL_IMPEXT float FPS_DEFAULT
Definition: Model.h:42
static STATIC_DLL_IMPEXT uint32_t uidCounter
Definition: Model.h:43
const vector< string > getNodeIds()
Returns all object's node ids.
Definition: Model.cpp:87
AnimationSetup * addAnimationSetup(const string &id, int32_t startFrame, int32_t endFrame, bool loop, float speed=1.0f)
Adds an base animation setup.
Definition: Model.cpp:101
AnimationSetup * addOverlayAnimationSetup(const string &id, const string &overlayFromNodeId, int32_t startFrame, int32_t endFrame, bool loop, float speed=1.0f)
Adds an overlay animation setup.
Definition: Model.cpp:113
UpVector * upVector
Definition: Model.h:50
ShaderModel * shaderModel
Definition: Model.h:52
unordered_map< string, Material * > materials
Definition: Model.h:53
unique_ptr< BoundingBox > boundingBox
Definition: Model.h:60
void deleteSubNodes(const unordered_map< string, Node * > &subNodes)
Delete sub nodes.
Definition: Model.cpp:73
bool computeTransformMatrix(const unordered_map< string, Node * > &nodes, const Matrix4x4 &parentTransformMatrix, int32_t frame, const string &nodeId, Matrix4x4 &transformMatrix)
Computes a transform matrix at a given frame for a given node id recursivly.
Definition: Model.cpp:159
const vector< string > getAnimationSetupIds()
Definition: Model.cpp:94
bool renameAnimationSetup(const string &id, const string &newId)
Rename animation set up.
Definition: Model.cpp:125
BoundingBox * getBoundingBox()
Definition: Model.cpp:150
Matrix4x4 importTransformMatrix
Definition: Model.h:59
unordered_map< string, AnimationSetup * > animationSetups
Definition: Model.h:58
Model node.
Definition: Node.h:32
Represents rotation orders of a model.
Definition: RotationOrder.h:23
static STATIC_DLL_IMPEXT ShaderModel * SPECULAR
Definition: ShaderModel.h:23
Model up vector.
Definition: UpVector.h:20
Axis aligned bounding box used for frustum, this is not directly connectable with physics engine.
Definition: BoundingBox.h:26
static BoundingBox * createBoundingBox(Model *model, const unordered_map< string, Matrix4x4 * > overriddenNodeTransformMatrices=unordered_map< string, Matrix4x4 * >())
Creates a bounding box from given model.
Object model To be used in non engine context.
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
Definition: Matrix4x4.h:23
Matrix4x4 clone() const
Clones this matrix.
Definition: Matrix4x4.h:619
Matrix4x4 & identity()
Creates identity matrix.
Definition: Matrix4x4.h:158
Vector3 multiply(const Vector3 &vector3) const
Multiplies this matrix with vector3.
Definition: Matrix4x4.h:225
Matrix4x4 & set(float r0c0, float r0c1, float r0c2, float r0c3, float r1c0, float r1c1, float r1c2, float r1c3, float r2c0, float r2c1, float r2c2, float r2c3, float r3c0, float r3c1, float r3c2, float r3c3)
Sets this matrix by its components.
Definition: Matrix4x4.h:108