TDME2  1.9.200
ObjectNode.cpp
Go to the documentation of this file.
2 
3 #include <memory>
4 #include <string>
5 #include <unordered_map>
6 #include <vector>
7 
8 #include <tdme/tdme.h>
9 #include <tdme/engine/Texture.h>
10 #include <tdme/engine/model/Face.h>
15 #include <tdme/engine/model/Node.h>
25 #include <tdme/engine/Engine.h>
26 #include <tdme/math/Matrix3x3.h>
27 #include <tdme/math/Matrix4x4.h>
28 
29 using std::make_unique;
30 using std::string;
31 using std::to_string;
32 using std::unique_ptr;
33 using std::unordered_map;
34 using std::vector;
35 
56 
57 int64_t ObjectNode::counter = 0;
58 
59 ObjectNode::ObjectNode()
60 {
61 }
62 
64 {
65 }
66 
68  nodeTransformMatrix = nullptr;
69  auto overriddenTransformationsMatricesIt = object->instanceAnimations[0]->overriddenTransformMatrices.find(node->getId());
70  if (overriddenTransformationsMatricesIt != object->instanceAnimations[0]->overriddenTransformMatrices.end()) {
71  nodeTransformMatrix = overriddenTransformationsMatricesIt->second;
72  } else {
73  auto transformationsMatricesIt = object->instanceAnimations[0]->transformMatrices[0].find(node->getId());
74  if (transformationsMatricesIt != object->instanceAnimations[0]->transformMatrices[0].end()) {
75  nodeTransformMatrix = transformationsMatricesIt->second;
76  }
77  }
78 }
79 
80 void ObjectNode::createNodes(ObjectBase* object, bool useManagers, Engine::AnimationProcessingTarget animationProcessingTarget, vector<ObjectNode*>& objectNodes)
81 {
82  auto model = object->getModel();
83  createNodes(object, model->getSubNodes(), model->hasAnimations(), useManagers, animationProcessingTarget, objectNodes);
84 }
85 
86 void ObjectNode::createNodes(ObjectBase* object, const unordered_map<string, Node*>& nodes, bool animated, bool useManagers, Engine::AnimationProcessingTarget animationProcessingTarget, vector<ObjectNode*>& objectNodes)
87 {
88  for (const auto& [nodeId, node]: nodes) {
89  // skip on joints
90  if (node->isJoint() == true) {
91  continue;
92  }
93  // determine face count
94  auto faceCount = node->getFaceCount();
95  // skip on nodes without faces
96  if (faceCount > 0) {
97  // create node render data
98  auto objectNode = new ObjectNode();
99  // add it to node render data list
100  objectNodes.push_back(objectNode);
101  // determine mesh id
102  objectNode->id =
103  node->getModel()->getId() +
104  ":" +
105  node->getId() +
106  ":" +
107  to_string(animationProcessingTarget) +
108  ":" +
109  to_string(object->instances);
110  if (node->getSkinning() != nullptr || (animationProcessingTarget == Engine::AnimationProcessingTarget::CPU_NORENDERING)) {
111  objectNode->id =
112  objectNode->id +
113  ":" +
114  to_string(counter++);
115  }
116  objectNode->object = object;
117  objectNode->node = node;
118  objectNode->animated = animated;
119  objectNode->renderer = make_unique<ObjectNodeRenderer>(objectNode);
120  vector<unordered_map<string, Matrix4x4*>*> instancesTransformMatrices;
121  vector<unordered_map<string, Matrix4x4*>*> instancesSkinningNodesMatrices;
122  for (auto animation: object->instanceAnimations) {
123  instancesTransformMatrices.push_back(&animation->transformMatrices[0]);
124  instancesSkinningNodesMatrices.push_back(animation->getSkinningNodesTransformMatrices(objectNode->node));
125  }
126  if (useManagers == true) {
127  auto meshManager = Engine::getInstance()->getMeshManager();
128  objectNode->mesh = meshManager->getMesh(objectNode->id);
129  if (objectNode->mesh == nullptr) {
130  objectNode->mesh = new ObjectNodeMesh(
131  objectNode->renderer.get(),
132  animationProcessingTarget,
133  node,
134  instancesTransformMatrices,
135  instancesSkinningNodesMatrices,
137  );
138  meshManager->addMesh(objectNode->id, objectNode->mesh);
139  }
140  } else {
141  objectNode->mesh = new ObjectNodeMesh(
142  objectNode->renderer.get(),
143  animationProcessingTarget,
144  node,
145  instancesTransformMatrices,
146  instancesSkinningNodesMatrices,
148  );
149  }
150  objectNode->textureMatricesByEntities.resize(node->getFacesEntities().size());
151  for (auto j = 0; j < node->getFacesEntities().size(); j++) {
152  auto material = node->getFacesEntities()[j].getMaterial();
153  if (material != nullptr) {
154  objectNode->textureMatricesByEntities[j].set(material->getTextureMatrix());
155  } else {
156  objectNode->textureMatricesByEntities[j].identity();
157  }
158  }
159  objectNode->specularMaterialDiffuseTextureIdsByEntities.resize(node->getFacesEntities().size());
160  objectNode->specularMaterialDynamicDiffuseTextureIdsByEntities.resize(node->getFacesEntities().size());
161  objectNode->specularMaterialSpecularTextureIdsByEntities.resize(node->getFacesEntities().size());
162  objectNode->specularMaterialNormalTextureIdsByEntities.resize(node->getFacesEntities().size());
163  objectNode->pbrMaterialBaseColorTextureIdsByEntities.resize(node->getFacesEntities().size());
164  objectNode->pbrMaterialMetallicRoughnessTextureIdsByEntities.resize(node->getFacesEntities().size());
165  objectNode->pbrMaterialNormalTextureIdsByEntities.resize(node->getFacesEntities().size());
166  objectNode->pbrMaterialEmissiveTextureIdsByEntities.resize(node->getFacesEntities().size());
167  for (auto j = 0; j < node->getFacesEntities().size(); j++) {
168  objectNode->specularMaterialDiffuseTextureIdsByEntities[j] = TEXTUREID_NONE;
169  objectNode->specularMaterialDynamicDiffuseTextureIdsByEntities[j] = TEXTUREID_NONE;
170  objectNode->specularMaterialSpecularTextureIdsByEntities[j] = TEXTUREID_NONE;
171  objectNode->specularMaterialNormalTextureIdsByEntities[j] = TEXTUREID_NONE;
172  objectNode->pbrMaterialBaseColorTextureIdsByEntities[j] = TEXTUREID_NONE;
173  objectNode->pbrMaterialMetallicRoughnessTextureIdsByEntities[j] = TEXTUREID_NONE;
174  objectNode->pbrMaterialNormalTextureIdsByEntities[j] = TEXTUREID_NONE;
175  objectNode->pbrMaterialEmissiveTextureIdsByEntities[j] = TEXTUREID_NONE;
176  }
177  // update node transformations matrix
178  objectNode->updateNodeTransformationsMatrix();
179  }
180  // but still check sub nodes
181  createNodes(object, node->getSubNodes(), animated, useManagers, animationProcessingTarget, objectNodes);
182  }
183 }
184 
185 void ObjectNode::computeAnimation(int contextIdx, vector<ObjectNode*>& objectNodes)
186 {
187  for (auto objectNode : objectNodes) {
188  objectNode->mesh->computeSkinning(contextIdx, objectNode->object);
189  }
190 }
191 
192 void ObjectNode::setupTextures(Renderer* renderer, int contextIdx, ObjectNode* objectNode, int32_t facesEntityIdx)
193 {
194  const auto& facesEntities = objectNode->node->getFacesEntities();
195  auto material = facesEntities[facesEntityIdx].getMaterial();
196  // get material or use default
197  if (material == nullptr) material = Material::getDefaultMaterial();
198  auto specularMaterialProperties = material->getSpecularMaterialProperties();
199  if (specularMaterialProperties != nullptr) {
200  // load specular diffuse texture
201  if (objectNode->specularMaterialDiffuseTextureIdsByEntities[facesEntityIdx] == TEXTUREID_NONE) {
202  if (specularMaterialProperties->getDiffuseTexture() != nullptr) {
203  objectNode->specularMaterialDiffuseTextureIdsByEntities[facesEntityIdx] = Engine::getInstance()->getTextureManager()->addTexture(specularMaterialProperties->getDiffuseTexture(), contextIdx);
204  } else {
206  }
207  }
208  // load specular specular texture
209  if (renderer->isSpecularMappingAvailable() == true && objectNode->specularMaterialSpecularTextureIdsByEntities[facesEntityIdx] == TEXTUREID_NONE) {
210  if (specularMaterialProperties->getSpecularTexture() != nullptr) {
211  objectNode->specularMaterialSpecularTextureIdsByEntities[facesEntityIdx] = Engine::getInstance()->getTextureManager()->addTexture(specularMaterialProperties->getSpecularTexture(), contextIdx);
212  } else {
214  }
215  }
216  // load specular normal texture
217  if (renderer->isNormalMappingAvailable() == true && objectNode->specularMaterialNormalTextureIdsByEntities[facesEntityIdx] == TEXTUREID_NONE) {
218  if (specularMaterialProperties->getNormalTexture() != nullptr) {
219  objectNode->specularMaterialNormalTextureIdsByEntities[facesEntityIdx] = Engine::getInstance()->getTextureManager()->addTexture(specularMaterialProperties->getNormalTexture(), contextIdx);
220  } else {
222  }
223  }
224  }
225  // load PBR textures
226  auto pbrMaterialProperties = material->getPBRMaterialProperties();
227  if (pbrMaterialProperties != nullptr && renderer->isPBRAvailable() == true) {
228  // load PBR base color texture
229  if (objectNode->pbrMaterialBaseColorTextureIdsByEntities[facesEntityIdx] == TEXTUREID_NONE) {
230  if (pbrMaterialProperties->getBaseColorTexture() != nullptr) {
231  objectNode->pbrMaterialBaseColorTextureIdsByEntities[facesEntityIdx] = Engine::getInstance()->getTextureManager()->addTexture(pbrMaterialProperties->getBaseColorTexture(), contextIdx);
232  } else {
233  objectNode->pbrMaterialBaseColorTextureIdsByEntities[facesEntityIdx] = TEXTUREID_NOTUSED;
234  }
235  }
236  // load PBR metallic roughness texture
237  if (objectNode->pbrMaterialMetallicRoughnessTextureIdsByEntities[facesEntityIdx] == TEXTUREID_NONE) {
238  if (pbrMaterialProperties->getMetallicRoughnessTexture() != nullptr) {
239  objectNode->pbrMaterialMetallicRoughnessTextureIdsByEntities[facesEntityIdx] = Engine::getInstance()->getTextureManager()->addTexture(pbrMaterialProperties->getMetallicRoughnessTexture(), contextIdx);
240  } else {
242  }
243  }
244  // load PBR normal texture
245  if (objectNode->pbrMaterialNormalTextureIdsByEntities[facesEntityIdx] == TEXTUREID_NONE) {
246  if (pbrMaterialProperties->getNormalTexture() != nullptr) {
247  objectNode->pbrMaterialNormalTextureIdsByEntities[facesEntityIdx] = Engine::getInstance()->getTextureManager()->addTexture(pbrMaterialProperties->getNormalTexture(), contextIdx);
248  } else {
249  objectNode->pbrMaterialNormalTextureIdsByEntities[facesEntityIdx] = TEXTUREID_NOTUSED;
250  }
251  }
252  // load PBR emissive texture
253  if (objectNode->pbrMaterialEmissiveTextureIdsByEntities[facesEntityIdx] == TEXTUREID_NONE) {
254  if (pbrMaterialProperties->getEmissiveTexture() != nullptr) {
255  objectNode->pbrMaterialEmissiveTextureIdsByEntities[facesEntityIdx] = Engine::getInstance()->getTextureManager()->addTexture(pbrMaterialProperties->getEmissiveTexture(), contextIdx);
256  } else {
257  objectNode->pbrMaterialEmissiveTextureIdsByEntities[facesEntityIdx] = TEXTUREID_NOTUSED;
258  }
259  }
260  }
261 }
262 
264 {
265  auto engine = Engine::getInstance();
266  auto textureManager = engine->getTextureManager();
267  const auto& facesEntities = node->getFacesEntities();
268  // dispose textures
269  for (auto j = 0; j < facesEntities.size(); j++) {
270  // get entity's material
271  auto material = facesEntities[j].getMaterial();
272  // skip if no material was set up
273  auto specularMaterialProperties = material != nullptr?material->getSpecularMaterialProperties():nullptr;
274  if (specularMaterialProperties != nullptr) {
275  // specular diffuse texture
276  auto specularDiffuseTextureId = specularMaterialDiffuseTextureIdsByEntities[j];
277  if (specularDiffuseTextureId != ObjectNode::TEXTUREID_NONE && specularDiffuseTextureId != ObjectNode::TEXTUREID_NOTUSED) {
278  // remove texture from texture manager
279  if (specularMaterialProperties->getDiffuseTexture() != nullptr)
280  textureManager->removeTexture(specularMaterialProperties->getDiffuseTexture()->getId());
281  // mark as removed
283  }
284  // specular specular texture
285  auto specularSpecularTextureId = specularMaterialSpecularTextureIdsByEntities[j];
286  if (specularSpecularTextureId != ObjectNode::TEXTUREID_NONE && specularSpecularTextureId != ObjectNode::TEXTUREID_NOTUSED) {
287  // remove texture from texture manager
288  if (specularMaterialProperties->getSpecularTexture() != nullptr)
289  textureManager->removeTexture(specularMaterialProperties->getSpecularTexture()->getId());
290  // mark as removed
292  }
293  // specular normal texture
294  auto specularNormalTextureId = specularMaterialNormalTextureIdsByEntities[j];
295  if (specularNormalTextureId != ObjectNode::TEXTUREID_NONE && specularNormalTextureId != ObjectNode::TEXTUREID_NOTUSED) {
296  // remove texture from texture manager
297  if (specularMaterialProperties->getNormalTexture() != nullptr)
298  textureManager->removeTexture(specularMaterialProperties->getNormalTexture()->getId());
299  // mark as removed
301  }
302  }
303  // PBR textures
304  auto pbrMaterialProperties = material != nullptr?material->getPBRMaterialProperties():nullptr;
305  if (pbrMaterialProperties != nullptr) {
306  // PBR base color texture
307  auto pbrBaseColorTextureId = pbrMaterialBaseColorTextureIdsByEntities[j];
308  if (pbrBaseColorTextureId != ObjectNode::TEXTUREID_NONE && pbrBaseColorTextureId != ObjectNode::TEXTUREID_NOTUSED) {
309  // remove texture from texture manager
310  if (pbrMaterialProperties->getBaseColorTexture() != nullptr)
311  textureManager->removeTexture(pbrMaterialProperties->getBaseColorTexture()->getId());
312  // mark as removed
314  }
315  auto pbrMetallicRoughnessTextureId = pbrMaterialMetallicRoughnessTextureIdsByEntities[j];
316  if (pbrMetallicRoughnessTextureId != ObjectNode::TEXTUREID_NONE && pbrMetallicRoughnessTextureId != ObjectNode::TEXTUREID_NOTUSED) {
317  // remove texture from texture manager
318  if (pbrMaterialProperties->getMetallicRoughnessTexture() != nullptr)
319  textureManager->removeTexture(pbrMaterialProperties->getMetallicRoughnessTexture()->getId());
320  // mark as removed
322  }
323  // PBR normal texture
324  auto pbrNormalTextureId = pbrMaterialNormalTextureIdsByEntities[j];
325  if (pbrNormalTextureId != ObjectNode::TEXTUREID_NONE && pbrNormalTextureId != ObjectNode::TEXTUREID_NOTUSED) {
326  // remove texture from texture manager
327  if (pbrMaterialProperties->getNormalTexture() != nullptr)
328  textureManager->removeTexture(pbrMaterialProperties->getNormalTexture()->getId());
329  // mark as removed
331  }
332  // PBR emissive texture
333  auto pbrEmissiveTextureId = pbrMaterialEmissiveTextureIdsByEntities[j];
334  if (pbrEmissiveTextureId != ObjectNode::TEXTUREID_NONE && pbrEmissiveTextureId != ObjectNode::TEXTUREID_NOTUSED) {
335  // remove texture from texture manager
336  if (pbrMaterialProperties->getEmissiveTexture() != nullptr)
337  textureManager->removeTexture(pbrMaterialProperties->getEmissiveTexture()->getId());
338  // mark as removed
340  }
341  }
342  }
343 }
Engine main class.
Definition: Engine.h:131
static Engine * getInstance()
Returns engine instance.
Definition: Engine.h:612
static TextureManager * getTextureManager()
Definition: Engine.h:627
static MeshManager * getMeshManager()
Definition: Engine.h:441
Texture entity.
Definition: Texture.h:24
Represents a model face, consisting of vertex, normal, tangent and bitangent vectors,...
Definition: Face.h:18
Node faces entity A node can have multiple entities containing faces and a applied material.
Definition: FacesEntity.h:23
Joint / Bone.
Definition: Joint.h:19
Represents a material.
Definition: Material.h:23
Representation of a 3D model.
Definition: Model.h:35
const string & getId()
Definition: Model.h:128
Model node.
Definition: Node.h:32
int32_t getFaceCount() const
Definition: Node.cpp:105
unordered_map< string, Node * > & getSubNodes()
Definition: Node.h:293
bool isJoint() const
Definition: Node.h:110
Model * getModel()
Definition: Node.h:74
Skinning * getSkinning()
Definition: Node.h:242
const string & getId()
Returns id.
Definition: Node.h:89
const vector< FacesEntity > & getFacesEntities() const
Definition: Node.h:260
Represents specular material properties.
Skinning definition for nodes.
Definition: Skinning.h:25
Represents specular material properties.
ObjectNodeMesh * getMesh(const string &meshId)
Get mesh from managed meshes.
Definition: MeshManager.h:46
TextureManager_TextureManaged * addTexture(const string &id, bool &created)
Adds a texture to manager.
vector< ObjectAnimation * > instanceAnimations
Definition: ObjectBase.h:55
Object node mesh specifically for rendering.
Object node specifically for rendering.
Definition: ObjectNode.h:41
static constexpr int32_t TEXTUREID_NOTUSED
Definition: ObjectNode.h:58
vector< int32_t > pbrMaterialBaseColorTextureIdsByEntities
Definition: ObjectNode.h:69
vector< int32_t > specularMaterialDiffuseTextureIdsByEntities
Definition: ObjectNode.h:65
vector< int32_t > pbrMaterialMetallicRoughnessTextureIdsByEntities
Definition: ObjectNode.h:70
vector< int32_t > specularMaterialNormalTextureIdsByEntities
Definition: ObjectNode.h:68
vector< int32_t > specularMaterialSpecularTextureIdsByEntities
Definition: ObjectNode.h:67
static void computeAnimation(int contextIdx, vector< ObjectNode * > &objectNodes)
Computes animation for given object nodes.
Definition: ObjectNode.cpp:185
static STATIC_DLL_IMPEXT int64_t counter
Definition: ObjectNode.h:55
vector< int32_t > pbrMaterialEmissiveTextureIdsByEntities
Definition: ObjectNode.h:72
static void createNodes(ObjectBase *object, bool useManagers, Engine::AnimationProcessingTarget animationProcessingTarget, vector< ObjectNode * > &objectNodes)
Creates object nodes from given object base object.
Definition: ObjectNode.cpp:80
static void setupTextures(Renderer *renderer, int contextIdx, ObjectNode *objectNode, int32_t facesEntityIdx)
Set up textures for given object node and faces entity.
Definition: ObjectNode.cpp:192
unique_ptr< ObjectNodeRenderer > renderer
Definition: ObjectNode.h:73
void updateNodeTransformationsMatrix()
Update node transformations matrix.
Definition: ObjectNode.cpp:67
Matrix3x3 class representing matrix3x3 mathematical structure and operations for 2d space.
Definition: Matrix3x3.h:20
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
Definition: Matrix4x4.h:23