6 #include <unordered_map>
36 using std::make_unique;
39 using std::unordered_map;
40 using std::unique_ptr;
69 Model* TMReader::read(
const string& pathName,
const string& fileName,
bool useBC7TextureCompression)
72 FileSystem::getInstance()->getContent(pathName, fileName, data);
73 return read(data, pathName, fileName, useBC7TextureCompression);
76 Model*
TMReader::read(
const vector<uint8_t>& data,
const string& pathName,
const string& fileName,
bool useBC7TextureCompression) {
78 class EmbeddedTexturesRAII {
80 EmbeddedTexturesRAII(
const unordered_map<string, Texture*>& embeddedTextures): embeddedTextures(embeddedTextures) {}
81 ~EmbeddedTexturesRAII() {
82 for (
const auto& [embeddedTextureId, embeddedTexture]: embeddedTextures) embeddedTexture->releaseReference();
85 const unordered_map<string, Texture*>& embeddedTextures;
88 unordered_map<string, Texture*> embeddedTextures;
89 EmbeddedTexturesRAII embeddedTexturesRAII(embeddedTextures);
93 if (fileId.length() == 0 || fileId !=
"TDME Model") {
96 array<uint8_t, 3> version;
100 if ((version[0] != 1 || version[1] != 0 || version[2] != 0) &&
101 (version[0] != 1 || version[1] != 9 || version[2] != 9) &&
102 (version[0] != 1 || version[1] != 9 || version[2] != 10) &&
103 (version[0] != 1 || version[1] != 9 || version[2] != 11) &&
104 (version[0] != 1 || version[1] != 9 || version[2] != 12) &&
105 (version[0] != 1 || version[1] != 9 || version[2] != 13) &&
106 (version[0] != 1 || version[1] != 9 || version[2] != 14) &&
107 (version[0] != 1 || version[1] != 9 || version[2] != 15) &&
108 (version[0] != 1 || version[1] != 9 || version[2] != 16) &&
109 (version[0] != 1 || version[1] != 9 || version[2] != 17) &&
110 (version[0] != 1 || version[1] != 9 || version[2] != 18) &&
111 (version[0] != 1 || version[1] != 9 || version[2] != 19) &&
112 (version[0] != 1 || version[1] != 9 || version[2] != 20)) {
114 "Version mismatch, should be 1.0.0, 1.9.9, 1.9.10, 1.9.11, 1.9.12, 1.9.13, 1.9.14, 1.9.15, 1.9.16, 1.9.17, 1.9.18, 1.9.19, 1.9.20 but is " +
115 to_string(version[0]) +
117 to_string(version[1]) +
119 to_string(version[2])
123 auto upVector = UpVector::valueOf(is.
readString());
124 auto rotationOrder = RotationOrder::valueOf(is.
readString());
125 auto shaderModel = ShaderModel::SPECULAR;
126 if ((version[0] == 1 && version[1] == 9 && version[2] == 14) ||
127 (version[0] == 1 && version[1] == 9 && version[2] == 15) ||
128 (version[0] == 1 && version[1] == 9 && version[2] == 16) ||
129 (version[0] == 1 && version[1] == 9 && version[2] == 17) ||
130 (version[0] == 1 && version[1] == 9 && version[2] == 18) ||
131 (version[0] == 1 && version[1] == 9 && version[2] == 19) ||
132 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
133 shaderModel = ShaderModel::valueOf(is.
readString());
135 auto embedSpecularTextures =
false;
136 auto embedPBRTextures =
false;
137 if ((version[0] == 1 && version[1] == 9 && version[2] == 18) ||
138 (version[0] == 1 && version[1] == 9 && version[2] == 19) ||
139 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
143 array<float, 3> boundingBoxMinXYZ;
145 array<float, 3> boundingBoxMaxXYZ;
147 auto boundingBox = make_unique<BoundingBox>(
Vector3(boundingBoxMinXYZ),
Vector3(boundingBoxMaxXYZ));
148 auto model = make_unique<Model>(
150 fileName.empty() ==
true?name:fileName,
153 boundingBox.release()
155 model->setShaderModel(shaderModel);
156 model->setEmbedSpecularTextures(embedSpecularTextures);
157 model->setEmbedPBRTextures(embedPBRTextures);
159 array<float, 16> importTransformMatrixArray;
161 model->setImportTransformMatrix(importTransformMatrixArray);
162 if ((version[0] == 1 && version[1] == 9 && version[2] == 17) ||
163 (version[0] == 1 && version[1] == 9 && version[2] == 18) ||
164 (version[0] == 1 && version[1] == 9 && version[2] == 19) ||
165 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
168 auto materialCount = is.
readInt();
169 for (
auto i = 0; i < materialCount; i++) {
170 auto material =
readMaterial(pathName, &is, model.get(), embeddedTextures, useBC7TextureCompression, version);
171 model->getMaterials()[material->getId()] = material;
173 readSubNodes(&is, model.get(),
nullptr, model->getSubNodes());
174 auto animationSetupCount = is.
readInt();
175 for (
auto i = 0; i < animationSetupCount; i++) {
178 if (model->getAnimationSetup(Model::ANIMATIONSETUP_DEFAULT) ==
nullptr) {
179 model->addAnimationSetup(Model::ANIMATIONSETUP_DEFAULT, 0, 0,
true);
182 return model.release();
186 if (FileSystem::getInstance()->exists(texturePathName +
"/" + textureFileName) ==
true) {
187 return texturePathName;
189 if (FileSystem::getInstance()->exists(modelPathName +
"/" + textureFileName) ==
true) {
190 return modelPathName;
192 if (FileSystem::getInstance()->exists(FileSystem::getInstance()->getPathName(modelPathName) +
"/" + textureFileName) ==
true) {
193 return FileSystem::getInstance()->getPathName(modelPathName);
195 return texturePathName;
200 auto embeddedTextureCount = is->
readInt();
201 for (
auto i = 0; i < embeddedTextureCount; i++) {
203 auto embeddedTextureType = is->
readByte();
205 if (embeddedTextureType == 1) {
208 if ((version[0] == 1 && version[1] == 9 && version[2] == 19) ||
209 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
213 auto textureSize = is->
readInt();
214 vector<uint8_t> pngData;
215 pngData.resize(textureSize);
216 for (
auto j = 0; j < textureSize; j++) pngData[j] = is->
readByte();
217 auto embeddedTexture =
222 PNGTextureReader::read(embeddedTextureId, pngData,
true)
224 if (embeddedTexture !=
nullptr) {
225 embeddedTexture->acquireReference();
226 if ((version[0] == 1 && version[1] == 9 && version[2] == 19) ||
227 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
228 embeddedTexture->setMinFilter(minFilter);
229 embeddedTexture->setMagFilter(magFilter);
231 embeddedTexture->setUseCompression(
false);
232 embeddedTextures[embeddedTextureId] = embeddedTexture.get();
233 embeddedTexture->acquireReference();
237 if (embeddedTextureType == 2) {
240 auto textureWidth = is->
readInt();
241 auto textureHeight = is->
readInt();
245 if ((version[0] == 1 && version[1] == 9 && version[2] == 19) ||
246 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
250 auto textureSize = is->
readInt();
252 for (
auto j = 0; j < textureSize; j++) bc7Data.
put(is->
readByte());
253 auto embeddedTexture =
270 embeddedTexture->acquireReference();
272 if ((version[0] == 1 && version[1] == 9 && version[2] == 19) ||
273 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
274 embeddedTexture->setMinFilter(minFilter);
275 embeddedTexture->setMagFilter(magFilter);
278 embeddedTexture->setUseCompression(
true);
279 embeddedTextures[embeddedTextureId] = embeddedTexture.get();
280 embeddedTexture->acquireReference();
283 if (embeddedTextureType == 3) {
287 auto textureWidth = is->
readInt();
288 auto textureHeight = is->
readInt();
292 if ((version[0] == 1 && version[1] == 9 && version[2] == 19) ||
293 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
297 auto textureSize = is->
readInt();
299 for (
auto j = 0; j < textureSize; j++) bc7Data.
put(is->
readByte());
300 auto embeddedTexture =
317 embeddedTexture->acquireReference();
319 if ((version[0] == 1 && version[1] == 9 && version[2] == 19) ||
320 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
321 embeddedTexture->setMinFilter(minFilter);
322 embeddedTexture->setMagFilter(magFilter);
325 auto mipMapTextureCount = is->
readByte();
326 embeddedTexture->setUseMipMap(mipMapTextureCount > 0);
327 vector<Texture::MipMapTexture> mipMapTextures;
328 for (
auto j = 0; j < mipMapTextureCount; j++) {
330 auto mipMapWidth =
static_cast<uint16_t
>(is->
readInt());
331 auto mipMapHeight =
static_cast<uint16_t
>(is->
readInt());
332 auto mipMapSize = is->
readInt();
333 mipMapTextures.emplace_back(
339 auto& mipMapBC7Data = mipMapTextures[mipMapTextures.size() - 1].textureData;
340 for (
auto k = 0; k < mipMapSize; k++) {
344 embeddedTexture->setMipMapTextures(mipMapTextures);
346 embeddedTexture->setUseCompression(
true);
347 embeddedTextures[embeddedTextureId] = embeddedTexture.get();
348 embeddedTexture->acquireReference();
357 auto m = make_unique<Material>(
id);
358 auto smp = make_unique<SpecularMaterialProperties>();
360 if (version[0] == 1 && version[1] == 9 && version[2] == 17) {
363 array<float, 4> colorRGBAArray;
365 smp->setAmbientColor(
Color4(colorRGBAArray));
367 smp->setDiffuseColor(
Color4(colorRGBAArray));
369 smp->setSpecularColor(
Color4(colorRGBAArray));
371 smp->setEmissionColor(
Color4(colorRGBAArray));
373 if ((version[0] == 1 && version[1] == 9 && version[2] == 15) ||
374 (version[0] == 1 && version[1] == 9 && version[2] == 16) ||
375 (version[0] == 1 && version[1] == 9 && version[2] == 17) ||
376 (version[0] == 1 && version[1] == 9 && version[2] == 18) ||
377 (version[0] == 1 && version[1] == 9 && version[2] == 19) ||
378 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
379 smp->setTextureAtlasSize(is->
readInt());
381 auto diffuseTexturePathName = is->
readString();
382 auto diffuseTextureFileName = is->
readString();
383 auto diffuseTransparencyTexturePathName = is->
readString();
384 auto diffuseTransparencyTextureFileName = is->
readString();
385 if (smpEmbbededTextures ==
false && diffuseTextureFileName.empty() ==
false) {
386 smp->setDiffuseTexture(
387 getTexturePath(pathName, diffuseTexturePathName, diffuseTextureFileName),
388 diffuseTextureFileName,
389 getTexturePath(pathName, diffuseTransparencyTexturePathName, diffuseTransparencyTextureFileName),
390 diffuseTransparencyTextureFileName
392 if (smp->getDiffuseTexture() !=
nullptr) smp->getDiffuseTexture()->setUseCompression(useBC7TextureCompression);
394 auto specularTexturePathName = is->
readString();
395 auto specularTextureFileName = is->
readString();
396 if (smpEmbbededTextures ==
false && specularTextureFileName.empty() ==
false) {
397 smp->setSpecularTexture(
398 getTexturePath(pathName, specularTexturePathName, specularTextureFileName),
399 specularTextureFileName
401 if (smp->getSpecularTexture() !=
nullptr) smp->getSpecularTexture()->setUseCompression(useBC7TextureCompression);
403 auto normalTexturePathName = is->
readString();
404 auto normalTextureFileName = is->
readString();
405 if (smpEmbbededTextures ==
false && normalTextureFileName.empty() ==
false) {
406 smp->setNormalTexture(
407 getTexturePath(pathName, normalTexturePathName, normalTextureFileName),
408 normalTextureFileName
410 if (smp->getNormalTexture() !=
nullptr) smp->getNormalTexture()->setUseCompression(useBC7TextureCompression);
412 if ((version[0] == 1 && version[1] == 9 && version[2] == 9) ||
413 (version[0] == 1 && version[1] == 9 && version[2] == 10) ||
414 (version[0] == 1 && version[1] == 9 && version[2] == 11)) {
415 auto displacementTexturePathName = is->
readString();
416 auto displacementTextureFileName = is->
readString();
418 if ((version[0] == 1 && version[1] == 9 && version[2] == 15) ||
419 (version[0] == 1 && version[1] == 9 && version[2] == 16) ||
420 (version[0] == 1 && version[1] == 9 && version[2] == 17) ||
421 (version[0] == 1 && version[1] == 9 && version[2] == 18) ||
422 (version[0] == 1 && version[1] == 9 && version[2] == 19) ||
423 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
424 smp->setDiffuseTextureTransparency(is->
readBoolean());
426 smp->setDiffuseTextureMaskedTransparency(is->
readBoolean());
427 if ((version[0] == 1 && version[1] == 9 && version[2] == 9) ||
428 (version[0] == 1 && version[1] == 9 && version[2] == 10) ||
429 (version[0] == 1 && version[1] == 9 && version[2] == 11) ||
430 (version[0] == 1 && version[1] == 9 && version[2] == 12) ||
431 (version[0] == 1 && version[1] == 9 && version[2] == 13) ||
432 (version[0] == 1 && version[1] == 9 && version[2] == 14) ||
433 (version[0] == 1 && version[1] == 9 && version[2] == 15) ||
434 (version[0] == 1 && version[1] == 9 && version[2] == 16) ||
435 (version[0] == 1 && version[1] == 9 && version[2] == 17) ||
436 (version[0] == 1 && version[1] == 9 && version[2] == 18) ||
437 (version[0] == 1 && version[1] == 9 && version[2] == 19) ||
438 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
439 smp->setDiffuseTextureMaskedTransparencyThreshold(is->
readFloat());
441 if ((version[0] == 1 && version[1] == 9 && version[2] == 16) ||
442 (version[0] == 1 && version[1] == 9 && version[2] == 17) ||
443 (version[0] == 1 && version[1] == 9 && version[2] == 18) ||
444 (version[0] == 1 && version[1] == 9 && version[2] == 19) ||
445 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
448 if ((version[0] == 1 && version[1] == 9 && version[2] == 10) ||
449 (version[0] == 1 && version[1] == 9 && version[2] == 11) ||
450 (version[0] == 1 && version[1] == 9 && version[2] == 12) ||
451 (version[0] == 1 && version[1] == 9 && version[2] == 13) ||
452 (version[0] == 1 && version[1] == 9 && version[2] == 14) ||
453 (version[0] == 1 && version[1] == 9 && version[2] == 15) ||
454 (version[0] == 1 && version[1] == 9 && version[2] == 16) ||
455 (version[0] == 1 && version[1] == 9 && version[2] == 17) ||
456 (version[0] == 1 && version[1] == 9 && version[2] == 18) ||
457 (version[0] == 1 && version[1] == 9 && version[2] == 19) ||
458 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
459 array<float, 9> textureMatrix;
461 smp->setTextureMatrix(
Matrix3x3(textureMatrix));
463 if ((version[0] == 1 && version[1] == 9 && version[2] == 17) ||
464 (version[0] == 1 && version[1] == 9 && version[2] == 18) ||
465 (version[0] == 1 && version[1] == 9 && version[2] == 19) ||
466 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
467 if (smpEmbbededTextures ==
true) {
469 if (diffuseTextureFileName.empty() ==
false) {
470 auto diffuseTextureTransparency = smp->getDiffuseTextureTransparency();
471 auto diffuseTextureMaskedTransparency = smp->getDiffuseTextureMaskedTransparencyThreshold();
473 if (diffuseTexture !=
nullptr) smp->setDiffuseTexture(diffuseTexture);
474 smp->setDiffuseTextureTransparency(diffuseTextureTransparency);
475 smp->setDiffuseTextureMaskedTransparency(diffuseTextureMaskedTransparency);
478 if (specularTextureFileName.empty() ==
false) {
480 if (specularTexture !=
nullptr) smp->setSpecularTexture(specularTexture);
483 if (normalTextureFileName.empty() ==
false) {
485 if (normalTexture !=
nullptr) smp->setNormalTexture(normalTexture);
489 m->setSpecularMaterialProperties(smp.release());
490 if ((version[0] == 1 && version[1] == 9 && version[2] == 13) ||
491 (version[0] == 1 && version[1] == 9 && version[2] == 14) ||
492 (version[0] == 1 && version[1] == 9 && version[2] == 15) ||
493 (version[0] == 1 && version[1] == 9 && version[2] == 16) ||
494 (version[0] == 1 && version[1] == 9 && version[2] == 17) ||
495 (version[0] == 1 && version[1] == 9 && version[2] == 18) ||
496 (version[0] == 1 && version[1] == 9 && version[2] == 19) ||
497 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
499 auto pmp = make_unique<PBRMaterialProperties>();
501 if (version[0] == 1 && version[1] == 9 && version[2] == 17) {
505 pmp->setBaseColorFactor(
Color4(colorRGBAArray));
506 auto baseColorTexturePathName = is->
readString();
507 auto baseColorTextureFileName = is->
readString();
508 if (pmpEmbeddedTextures ==
false && baseColorTextureFileName.empty() ==
false) {
509 pmp->setBaseColorTexture(baseColorTexturePathName, baseColorTextureFileName);
510 if (pmp->getBaseColorTexture() !=
nullptr) pmp->getBaseColorTexture()->setUseCompression(useBC7TextureCompression);
512 pmp->setBaseColorTextureMaskedTransparency(is->
readBoolean());
513 pmp->setBaseColorTextureMaskedTransparency(is->
readFloat());
515 pmp->setRoughnessFactor(is->
readFloat());
516 auto metallicRoughnessTexturePathName = is->
readString();
517 auto metallicRoughnessTextureFileName = is->
readString();
518 if (pmpEmbeddedTextures && metallicRoughnessTextureFileName.empty() ==
false) {
519 pmp->setMetallicRoughnessTexture(metallicRoughnessTexturePathName, metallicRoughnessTextureFileName);
520 if (pmp->getMetallicRoughnessTexture() !=
nullptr) pmp->getMetallicRoughnessTexture()->setUseCompression(useBC7TextureCompression);
523 auto pbrNormalTexturePathName = is->
readString();
524 auto pbrNormalTextureFileName = is->
readString();
525 if (pmpEmbeddedTextures ==
false && pbrNormalTextureFileName.empty() ==
false) {
526 pmp->setNormalTexture(pbrNormalTexturePathName, pbrNormalTextureFileName);
527 if (pmp->getNormalTexture() !=
nullptr) pmp->getNormalTexture()->setUseCompression(useBC7TextureCompression);
529 string pbrEmissiveTexturePathName;
530 string pbrEmissiveTextureFileName;
531 if ((version[0] == 1 && version[1] == 9 && version[2] == 20)) {
533 pmp->setEmissiveFactor(
Color4(colorRGBAArray));
534 pbrEmissiveTexturePathName = is->
readString();
535 pbrEmissiveTextureFileName = is->
readString();
536 if (pmpEmbeddedTextures ==
false && pbrEmissiveTextureFileName.empty() ==
false) {
537 pmp->setEmissiveTexture(pbrEmissiveTexturePathName, pbrEmissiveTextureFileName);
538 if (pmp->getEmissiveTexture() !=
nullptr) pmp->getEmissiveTexture()->setUseCompression(useBC7TextureCompression);
542 if ((version[0] == 1 && version[1] == 9 && version[2] == 17) ||
543 (version[0] == 1 && version[1] == 9 && version[2] == 18) ||
544 (version[0] == 1 && version[1] == 9 && version[2] == 19) ||
545 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
546 if (pmpEmbeddedTextures ==
true) {
548 if (baseColorTextureFileName.empty() ==
false) {
549 auto baseColorTextureTransparency = pmp->hasBaseColorTextureTransparency();
550 auto baseColorTextureMaskedTransparency = pmp->hasBaseColorTextureMaskedTransparency();
551 auto baseColorTexture =
getEmbeddedTexture(embeddedTextures, baseColorTextureFileName);
552 if (baseColorTexture !=
nullptr) pmp->setBaseColorTexture(baseColorTexture);
553 pmp->setBaseColorTextureTransparency(baseColorTextureTransparency);
554 pmp->setBaseColorTextureMaskedTransparency(baseColorTextureMaskedTransparency);
557 if (metallicRoughnessTextureFileName.empty() ==
false) {
558 auto metallicRoughnessTexture =
getEmbeddedTexture(embeddedTextures, metallicRoughnessTextureFileName);
559 if (metallicRoughnessTexture !=
nullptr) pmp->setMetallicRoughnessTexture(metallicRoughnessTexture);
562 if (pbrNormalTextureFileName.empty() ==
false) {
563 auto pbrNormalTexture =
getEmbeddedTexture(embeddedTextures, pbrNormalTextureFileName);
564 if (pbrNormalTexture !=
nullptr) pmp->setNormalTexture(pbrNormalTexture);
567 if ((version[0] == 1 && version[1] == 9 && version[2] == 20)) {
568 if (pbrEmissiveTextureFileName.empty() ==
false) {
569 auto pbrEmissiveTexture =
getEmbeddedTexture(embeddedTextures, pbrEmissiveTextureFileName);
570 if (pbrEmissiveTexture !=
nullptr) pmp->setEmissiveTexture(pbrEmissiveTexture);
575 m->setPBRMaterialProperties(pmp.release());
585 auto startFrame = is->
readInt();
589 if ((version[0] == 1 && version[1] == 9 && version[2] == 11) ||
590 (version[0] == 1 && version[1] == 9 && version[2] == 12) ||
591 (version[0] == 1 && version[1] == 9 && version[2] == 13) ||
592 (version[0] == 1 && version[1] == 9 && version[2] == 14) ||
593 (version[0] == 1 && version[1] == 9 && version[2] == 15) ||
594 (version[0] == 1 && version[1] == 9 && version[2] == 16) ||
595 (version[0] == 1 && version[1] == 9 && version[2] == 17) ||
596 (version[0] == 1 && version[1] == 9 && version[2] == 18) ||
597 (version[0] == 1 && version[1] == 9 && version[2] == 19) ||
598 (version[0] == 1 && version[1] == 9 && version[2] == 20)) {
601 if (overlayFromNodeId.length() == 0) {
611 array<float, 3> vXYZ;
614 for (
auto i = 0; i < v.size(); i++) {
624 array<float, 2> tcUV;
628 for (
auto i = 0; i < tc.size(); i++) {
642 if (length != indices->size()) {
645 for (
auto i = 0; i < indices->size(); i++) {
657 array<float, 16> matrixArray;
659 auto animation = make_unique<Animation>();
660 vector<Matrix4x4> transformMatrices;
661 transformMatrices.resize(frames);
662 for (
auto i = 0; i < transformMatrices.size(); i++) {
664 transformMatrices[i].set(matrixArray);
666 animation->setTransformMatrices(transformMatrices);
674 vector<FacesEntity> facesEntities;
675 facesEntities.resize(is->
readInt());
676 for (
auto i = 0; i < facesEntities.size(); i++) {
682 material = materialIt->second;
684 facesEntities[i].setMaterial(material);
688 array<int32_t,3> vertexIndices;
689 array<int32_t,3> normalIndices;
690 array<int32_t,3> textureCoordinateIndices;
691 array<int32_t,3> tangentIndices;
692 array<int32_t,3> bitangentIndices;
693 bool haveTextureCoordinateIndices;
694 bool haveTangentIndices;
695 bool haveBitangentIndices;
696 for (
auto j = 0; j < faces.size(); j++) {
699 haveTextureCoordinateIndices =
readIndices(is, &textureCoordinateIndices);
700 haveTangentIndices =
readIndices(is, &tangentIndices);
701 haveBitangentIndices =
readIndices(is, &bitangentIndices);
703 vertexIndices[0], vertexIndices[1], vertexIndices[2],
704 normalIndices[0], normalIndices[1], normalIndices[2]
706 if (haveTextureCoordinateIndices ==
true) {
707 faces[j].setTextureCoordinateIndices(
708 textureCoordinateIndices[0], textureCoordinateIndices[1], textureCoordinateIndices[2]
711 if (haveTangentIndices ==
true && haveBitangentIndices ==
true) {
712 faces[j].setTangentIndices(tangentIndices[0], tangentIndices[1], tangentIndices[2]);
713 faces[j].setBitangentIndices(bitangentIndices[0], bitangentIndices[1], bitangentIndices[2]);
716 facesEntities[i].setFaces(faces);
723 array<float, 16> matrixArray;
733 int32_t jointIndex = is->
readInt();
734 int32_t weightIndex = is->
readInt();
741 auto skinning = make_unique<Skinning>();
743 vector<Joint> joints;
745 for (
auto i = 0; i < joints.size(); i++) {
748 skinning->setJoints(joints);
749 vector<vector<JointWeight>> verticesJointsWeight;
750 verticesJointsWeight.resize(is->
readInt());
751 for (
auto i = 0; i < verticesJointsWeight.size(); i++) {
752 verticesJointsWeight[i].resize(is->
readInt());
753 for (
auto j = 0; j < verticesJointsWeight[i].size(); j++) {
757 skinning->setVerticesJointsWeights(verticesJointsWeight);
764 auto subNodeCount = is->
readInt();
765 for (
auto i = 0; i < subNodeCount; i++) {
766 auto subNode =
readNode(is, model, parentNode);
767 subNodes[subNode->getId()] = subNode;
768 model->
getNodes()[subNode->getId()] = subNode;
777 auto node = make_unique<Node>(model, parentNode, nodeId, nodeName);
779 array<float, 16> matrixArray;
781 node->setTransformMatrix(
Matrix4x4(matrixArray));
783 node->setVertices(vertices);
785 node->setNormals(normals);
787 node->setTextureCoordinates(textureCoordinates);
789 node->setTangents(tangents);
791 node->setBitangents(bitangents);
796 return node.release();
Color 4 definition class.
static TextureFormat getBC7FormatByPixelBitsPerPixel(int bpp)
Return BC7 RGB/A texture format by bits per pixel.
static TextureDepth getRGBDepthByPixelBitsPerPixel(int bpp)
Return RGB/A texture depth by bits per pixel.
@ TEXTUREFILTER_LINEAR_MIPMAP_LINEAR
static void readSubNodes(TMReaderInputStream *is, Model *model, Node *parentNode, unordered_map< string, Node * > &subNodes)
Read sub nodes.
static Joint readSkinningJoint(TMReaderInputStream *is)
Read skinning joint.
static Material * readMaterial(const string &pathName, TMReaderInputStream *is, Model *model, const unordered_map< string, Texture * > &embeddedTextures, bool useBC7TextureCompression, const array< uint8_t, 3 > &version)
Read material.
static const string getTexturePath(const string &modelPathName, const string &texturePathName, const string &textureFileName)
Get texture path.
static const vector< Vector3 > readVertices(TMReaderInputStream *is)
Read vertices from input stream.
static const vector< Vector2 > readTextureCoordinates(TMReaderInputStream *is)
Read texture coordinates from input stream.
static Animation * readAnimation(TMReaderInputStream *is, Node *g)
Read animation from input stream into node.
static void readFacesEntities(TMReaderInputStream *is, Node *g)
Read faces entities from input stream.
static void readAnimationSetup(TMReaderInputStream *is, Model *model, const array< uint8_t, 3 > &version)
Read animation setup.
static void readSkinning(TMReaderInputStream *is, Node *g)
Read skinning from input stream.
static bool readIndices(TMReaderInputStream *is, array< int32_t, 3 > *indices)
Read indices from input stream.
static void readEmbeddedTextures(TMReaderInputStream *is, unordered_map< string, Texture * > &embeddedTextures, const array< uint8_t, 3 > &version)
Read material.
static JointWeight readSkinningJointWeight(TMReaderInputStream *is)
Read skinning joint weight.
static Texture * getEmbeddedTexture(const unordered_map< string, Texture * > &embeddedTextures, const string &fileName)
Read material.
static Model * read(const string &pathName, const string &fileName, bool useBC7TextureCompression=true)
TDME model format reader.
static Node * readNode(TMReaderInputStream *is, Model *model, Node *parentNode)
Write node to output stream.
PNG texture reader class.
Represents a model face, consisting of vertex, normal, tangent and bitangent vectors,...
Node faces entity A node can have multiple entities containing faces and a applied material.
void setBindMatrix(const Matrix4x4 &bindMatrix)
Bind matrix.
Representation of a 3D model.
unordered_map< string, Material * > & getMaterials()
Returns all object materials.
bool hasEmbeddedPBRTextures() const
unordered_map< string, Node * > & getNodes()
Returns all object's nodes.
AnimationSetup * addAnimationSetup(const string &id, int32_t startFrame, int32_t endFrame, bool loop, float speed=1.0f)
Adds an base animation setup.
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.
bool hasEmbeddedSpecularTextures() const
unordered_map< string, Node * > & getSubNodes()
void setAnimation(Animation *animation)
Sets animation object.
void setFacesEntities(const vector< FacesEntity > &facesEntities)
Set up faces entities.
void setSkinning(Skinning *skinning)
Sets skinning object.
Animation * getAnimation()
Represents specular material properties.
Represents rotation orders of a model.
Skinning definition for nodes.
Represents specular material properties.
Axis aligned bounding box used for frustum, this is not directly connectable with physics engine.
Matrix3x3 class representing matrix3x3 mathematical structure and operations for 2d space.
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
Vector2 class representing vector2 mathematical structure and operations with x, y components.
Vector3 class representing vector3 mathematical structure and operations with x, y,...
File system singleton class.
Buffer * put(uint8_t value)
Put value into buffer.
virtual void releaseReference()
Releases a reference, thus decrementing the counter and delete it if reference counter is zero.