3#include "ImageLoader.h"
5#define NULL_POSITION (-959959.9956)
6#define TINYGLTF_IMPLEMENTATION
10 void loadGLTFTextureMesh(std::shared_ptr<TextureMesh> texMesh,const std::string& filepath)
12 using namespace tinygltf;
14 auto model = new Model;
20 bool ret = loader.LoadASCIIFromFile(model, &err, &warn, filepath);
22 printf("Warn: %s\n", warn.c_str());
25 printf("Err: %s\n", err.c_str());
29 printf("Failed to parse glTF\n");
35 loadGLTFMaterial(*model, texMesh,filepath);
37 DArray<Vec3f> initialPosition;
38 DArray<Vec3f> initialNormal;
39 DArray<Mat4f> d_mesh_Matrix;
40 DArray<int> d_shape_meshId;
54 shapeTransform(initialPosition,
64 auto shapeNum = texMesh->shapes().size();
66 CArray<Vec3f> c_shapeCenter;
67 c_shapeCenter.resize(shapeNum);
69 for (uint i = 0; i < shapeNum; i++)
72 counter.resize(texMesh->vertices().size());
74 Shape_PointCounter(counter,
79 Reduction<int> reduce;
80 int num = reduce.accumulate(counter.begin(), counter.size());
82 DArray<Vec3f> targetPoints;
83 targetPoints.resize(num);
86 scan.exclusive(counter.begin(), counter.size());
96 Reduction<Vec3f> reduceBounding;
98 auto& bounding = texMesh->shapes()[i]->boundingBox;
99 Vec3f lo = reduceBounding.minimum(targetPoints.begin(), targetPoints.size());
100 Vec3f hi = reduceBounding.maximum(targetPoints.begin(), targetPoints.size());
104 texMesh->shapes()[i]->boundingTransform.translation() = (lo + hi) / 2;
106 c_shapeCenter[i] = (lo + hi) / 2;
108 targetPoints.clear();
113 DArray<Vec3f> d_ShapeCenter;
114 DArray<Vec3f> unCenterPosition;
116 d_ShapeCenter.assign(c_shapeCenter); // Used to "ToCenter"
117 unCenterPosition.assign(texMesh->vertices());
120 if (true)//varUseInstanceTransform()->getValue()
122 shapeToCenter(unCenterPosition,
128 auto& reShapes = texMesh->shapes();
130 for (size_t i = 0; i < shapeNum; i++)
132 reShapes[i]->boundingTransform.translation() = reShapes[i]->boundingTransform.translation() ;//+ this->varLocation()->getValue()
137 auto& reShapes = texMesh->shapes();
139 for (size_t i = 0; i < shapeNum; i++)
141 reShapes[i]->boundingTransform.translation() = Vec3f(0);
146 void loadGLTFShape(tinygltf::Model& model, std::shared_ptr<TextureMesh> texMesh, const std::string& filepath, DArray<Vec3f>* initialPosition, DArray<Vec3f>* initialNormal, DArray<Mat4f>* d_mesh_Matrix,DArray<int>* d_shape_meshId, std::shared_ptr<SkinInfo> skinData )
151 typedef int primitive;
155 std::vector<Vec3f> vertices;
156 std::vector<Vec3f> normals;
157 std::vector<Vec3f> texCoord0;
158 std::vector<Vec3f> texCoord1;
160 std::vector<TopologyModule::Triangle> trianglesVector;
163 for (auto meshId : model.meshes)
165 shapeNum += meshId.primitives.size();
169 loadGLTFMaterial(model, texMesh, filepath);
173 auto& reShapes = texMesh->shapes();
175 reShapes.resize(shapeNum);
177 auto& reMats = texMesh->materials();
179 std::vector<Vec3f> shapeCenter;
181 int primitive_PointOffest;
182 int currentShape = 0;
183 std::map<int, std::vector<Vec2u>> shape2VerticeRange;
185 std::map<int, int> shape_meshId;
190 for (int mId = 0; mId < model.meshes.size(); mId++)
193 std::vector<dyno::TopologyModule::Triangle> vertexIndex;
194 std::vector<dyno::TopologyModule::Triangle> normalIndex;
195 std::vector<dyno::TopologyModule::Triangle> texCoordIndex;
197 int primNum = model.meshes[mId].primitives.size();
199 for (size_t pId = 0; pId < primNum; pId++) //shape
202 primitive_PointOffest = (vertices.size());
205 const tinygltf::Primitive& primitive = model.meshes[mId].primitives[pId];
207 std::map<std::string, int> attributesName = primitive.attributes;
211 getVec3fByAttributeName(model, primitive, std::string("POSITION"), vertices);
212 shape2VerticeRange[tempShapeId].push_back(Vec2u(tempSize, vertices.size() - 1));
214 tempSize = vertices.size();
217 getVec3fByAttributeName(model, primitive, std::string("NORMAL"), normals);
221 getVec3fByAttributeName(model, primitive, std::string("TEXCOORD_0"), texCoord0);
223 getVec3fByAttributeName(model, primitive, std::string("TEXCOORD_1"), texCoord1);
229 if (primitive.mode == TINYGLTF_MODE_TRIANGLES)
232 std::vector<TopologyModule::Triangle> tempTriangles;
234 getTriangles(model, primitive, tempTriangles, primitive_PointOffest);
236 vertexIndex = (tempTriangles);
237 normalIndex = (tempTriangles);
238 texCoordIndex = (tempTriangles);
240 reShapes[currentShape] = std::make_shared<Shape>();
241 shape_meshId[currentShape] = mId; // set shapeId - meshId;
242 reShapes[currentShape]->vertexIndex.assign(vertexIndex);
243 reShapes[currentShape]->normalIndex.assign(normalIndex);
244 reShapes[currentShape]->texCoordIndex.assign(texCoordIndex);
246 getBoundingBoxByName(model, primitive, std::string("POSITION"), reShapes[currentShape]->boundingBox, reShapes[currentShape]->boundingTransform);//,Transform3f& transform
248 shapeCenter.push_back(reShapes[currentShape]->boundingTransform.translation());
250 int matId = primitive.material;
251 if (matId != -1 && matId < reMats.size())//
253 reShapes[currentShape]->material = reMats[matId];
254 //printf("shape_materialID : %d - %d\n",currentShape,matId);
256 //printf("texture size %d - %d:\n", reMats[matId]->texColor.nx(), reMats[matId]->texColor.ny());
260 reShapes[currentShape]->material = NULL;
265 // auto newMat = std::make_shared<Material>();
267 // newMat->ambient = { 0,0,0 };
268 // newMat->diffuse = Vec3f(0.5, 0.5, 0.5);
269 // newMat->alpha = 1;
270 // newMat->specular = Vec3f(1, 1, 1);
271 // newMat->roughness = 0.5;
273 // reMats.push_back(newMat);
275 // reShapes[currentShape]->material = reMats[reMats.size() - 1];
276 // printf("shape_materialID : %d - %d\n", currentShape, currentShape);
279 trianglesVector.insert(trianglesVector.end(), tempTriangles.begin(), tempTriangles.end());
287 std::map<uint, uint> vertexId_shapeId;
289 texMesh->shapeIds().resize(vertices.size());
294 std::map<int, std::vector<joint>> shape_skinJoint;
296 for (size_t i = 0; i < model.skins.size(); i++)
298 auto joints = model.skins[i].joints;
299 shape_skinJoint[i] = joints;
303 std::map<int, std::vector<joint>> skinNode_MeshId;
304 std::map<mesh, std::vector<shape>> meshNode_Primitive;
306 for (size_t i = 0; i < model.nodes.size(); i++)
308 if (model.nodes[i].skin != -1)
310 skinNode_MeshId[i].push_back(model.nodes[i].mesh);
317 for (int mId = 0; mId < model.meshes.size(); mId++)
319 int primNum = model.meshes[mId].primitives.size();
321 for (size_t pId = 0; pId < primNum; pId++)
323 meshNode_Primitive[mId].push_back(tempShapeId);
331 if (skinData != nullptr)
333 skinData->clearSkinInfo();
336 for (int mId = 0; mId < model.meshes.size(); mId++)
338 int primNum = model.meshes[mId].primitives.size();
340 for (size_t pId = 0; pId < primNum; pId++)
342 std::vector<joint> skinJoints;
344 if (shape_skinJoint.find(0) != shape_skinJoint.end())
345 skinJoints = shape_skinJoint[tempShapeId];
347 if (skinJoints.size())
350 std::vector<Vec4f> weight0;
351 std::vector<Vec4f> weight1;
353 std::vector<Vec4f> joint0;
354 std::vector<Vec4f> joint1;
356 getVec4ByAttributeName(model, model.meshes[mId].primitives[pId], std::string("WEIGHTS_0"), weight0);//
358 getVec4ByAttributeName(model, model.meshes[mId].primitives[pId], std::string("WEIGHTS_1"), weight1);//
360 getVertexBindJoint(model, model.meshes[mId].primitives[pId], std::string("JOINTS_0"), joint0, skinJoints);
362 getVertexBindJoint(model, model.meshes[mId].primitives[pId], std::string("JOINTS_1"), joint1, skinJoints);
364 skinData->pushBack_Data(weight0, weight1, joint0, joint1);
373 for (auto it : shape2VerticeRange)
375 skinData->skin_VerticeRange[it.first] = it.second;
383 for (int i = 0; i < texMesh->shapes().size(); i++)
385 auto it = texMesh->shapes()[i];
387 updateVertexIdShape(texMesh->shapes()[i]->vertexIndex, texMesh->shapeIds(),i, texMesh->shapes()[i]->vertexIndex.size());
391 CArray<int> c_shape_meshId;
393 c_shape_meshId.resize(shape_meshId.size());
397 std::vector<int> MeshNodeIDs;
399 for (size_t nId = 0; nId < model.nodes.size(); nId++)
403 if (model.nodes[nId].mesh >= 0)
406 MeshNodeIDs.push_back(nId);
411 CArray<Mat4f> mesh_Matrix;
413 getMeshMatrix(model, MeshNodeIDs, maxMeshId, mesh_Matrix);
415 for (auto it : shape_meshId)
417 c_shape_meshId[it.first] = MeshNodeIDs[it.second];
420 if (d_shape_meshId != nullptr)
421 d_shape_meshId->assign(c_shape_meshId);
423 if (initialPosition != nullptr)
424 initialPosition->assign(vertices);
426 if (initialNormal != nullptr)
427 initialNormal->assign(normals);
429 texMesh->vertices().assign(vertices);
430 texMesh->normals().assign(normals);
432 if (d_mesh_Matrix != nullptr)
433 d_mesh_Matrix->assign(mesh_Matrix);
436 texMesh->shapeIds().resize(texMesh->vertices().size());
442 std::vector<Vec2f> tempTexCoord;
443 for (auto uv0 : texCoord0)
445 tempTexCoord.push_back(Vec2f(uv0[0], 1 - uv0[1])); // uv.v need flip
447 texMesh->texCoords().assign(tempTexCoord);
450 tempTexCoord.clear();
451 for (auto uv1 : texCoord1)
453 tempTexCoord.push_back(Vec2f(uv1[0], 1 - uv1[1]));
456 tempTexCoord.clear();
461 void loadGLTFMaterial(tinygltf::Model& model, std::shared_ptr<TextureMesh> texMesh, FilePath filename)
463 const std::vector<tinygltf::Material>& sourceMaterials = model.materials;
465 auto& reMats = texMesh->materials();
467 if (sourceMaterials.size()) //use materials.size()
469 reMats.resize(sourceMaterials.size());
473 std::vector<tinygltf::Texture>& textures = model.textures;
474 std::vector<tinygltf::Image>& images = model.images;
475 dyno::CArray2D<dyno::Vec4f> texture(1, 1);
476 texture[0, 0] = dyno::Vec4f(1);
479 for (int matId = 0; matId < sourceMaterials.size(); matId++)
481 auto material = sourceMaterials[matId];
482 auto color = material.pbrMetallicRoughness.baseColorFactor;
483 auto roughness = material.pbrMetallicRoughness.roughnessFactor;
485 auto metallic = material.pbrMetallicRoughness.metallicFactor;
487 auto colorTexId = material.pbrMetallicRoughness.baseColorTexture.index;
488 auto texCoord = material.pbrMetallicRoughness.baseColorTexture.texCoord;
490 reMats[matId] = std::make_shared<Material>();
491 reMats[matId]->baseColor = Vec3f(color[0], color[1], color[2]);
492 reMats[matId]->alpha = color[3];
493 reMats[matId]->metallic = metallic;
494 reMats[matId]->roughness = roughness;
496 std::string colorUri = getTexUri(textures, images, colorTexId);
497 std::shared_ptr<ImageLoader> loader = std::make_shared<ImageLoader>();
499 if (!colorUri.empty())
502 auto root = filename.path().parent_path();
503 colorUri = (root / colorUri).string();
505 if (loader->loadImage(colorUri.c_str(), texture))
507 reMats[matId]->texColor.assign(texture);
512 if (reMats[matId]->texColor.size())
513 reMats[matId]->texColor.clear();
516 auto bumpTexId = material.normalTexture.index;
517 auto scale = material.normalTexture.scale;
518 std::string bumpUri = getTexUri(textures, images, bumpTexId);
520 if (!bumpUri.empty())
522 auto root = filename.path().parent_path();
523 bumpUri = (root / bumpUri).string();
525 if (loader->loadImage(bumpUri.c_str(), texture))
527 reMats[matId]->texBump.assign(texture);
528 reMats[matId]->bumpScale = scale;
533 if (reMats[matId]->texBump.size())
534 reMats[matId]->texBump.clear();
542 void getBoundingBoxByName(
543 tinygltf::Model& model,
544 const tinygltf::Primitive& primitive,
545 const std::string& attributeName,
546 TAlignedBox3D<Real>& bound,
547 Transform3f& transform
550 //assign Attributes for Points
551 std::map<std::string, int>::const_iterator iter;
552 iter = primitive.attributes.find(attributeName);
554 if (iter == primitive.attributes.end())
556 std::cout << attributeName << " : not found !!! \n";
560 auto min = model.accessors[iter->second].minValues;
561 auto max = model.accessors[iter->second].maxValues;
564 std::cout << attributeName << " : not Vec3f !!! \n";
568 Vec3f v0 = Vec3f(min[0], min[1], min[2]);
569 Vec3f v1 = Vec3f(max[0], max[1], max[2]);
571 bound = TAlignedBox3D<Real>(v0, v1);
573 Vec3f center = (v0 + v1) / 2;
574 transform = Transform3f(Vec3f(center), Mat3f::identityMatrix(), Vec3f(1));
579 void getVec4ByAttributeName(tinygltf::Model& model,
580 const tinygltf::Primitive& primitive,
581 const std::string& attributeName,
582 std::vector<Vec4f>& vec4Data
585 //assign Attributes for Points
586 std::map<std::string, int>::const_iterator iter;
587 iter = primitive.attributes.find(attributeName);
589 if (iter == primitive.attributes.end())
591 std::cout << attributeName << " : not found !!! \n";
595 const tinygltf::Accessor& accessorAttribute = model.accessors[iter->second];
596 const tinygltf::BufferView& bufferView = model.bufferViews[accessorAttribute.bufferView];
597 const tinygltf::Buffer& buffer = model.buffers[bufferView.buffer];
599 if (accessorAttribute.type == TINYGLTF_TYPE_VEC4)
601 if (accessorAttribute.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT)
603 const unsigned short* data = reinterpret_cast<const unsigned short*>(&buffer.data[bufferView.byteOffset + accessorAttribute.byteOffset]);
604 for (size_t i = 0; i < accessorAttribute.count; ++i)
607 vec4Data.push_back(Vec4f(float(data[i * 4 + 0]), float(data[i * 4 + 1]), float(data[i * 4 + 2]), float(data[i * 4 + 3])));
610 else if (accessorAttribute.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT)
612 const unsigned int* data = reinterpret_cast<const unsigned int*>(&buffer.data[bufferView.byteOffset + accessorAttribute.byteOffset]);
613 for (size_t i = 0; i < accessorAttribute.count; ++i)
615 vec4Data.push_back(Vec4f(float(data[i * 4 + 0]), float(data[i * 4 + 1]), float(data[i * 4 + 2]), float(data[i * 4 + 3])));
618 else if (accessorAttribute.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT)
620 const float* data = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessorAttribute.byteOffset]);
621 for (size_t i = 0; i < accessorAttribute.count; ++i)
623 vec4Data.push_back(Vec4f(data[i * 4 + 0], data[i * 4 + 1], data[i * 4 + 2], data[i * 4 + 3]));
631 // ********************************** getVec3f By Attribute Name *************************//
633 void getVec3fByAttributeName(
634 tinygltf::Model& model,
635 const tinygltf::Primitive& primitive,
636 const std::string& attributeName,
637 std::vector<Vec3f>& vertices
640 //assign Attributes for Points
641 std::map<std::string, int>::const_iterator iter;
642 iter = primitive.attributes.find(attributeName);
644 if (iter == primitive.attributes.end())
646 std::cout << attributeName << " : not found !!! \n";
650 const tinygltf::Accessor& accessorAttribute = model.accessors[iter->second];
651 const tinygltf::BufferView& bufferView = model.bufferViews[accessorAttribute.bufferView];
652 const tinygltf::Buffer& buffer = model.buffers[bufferView.buffer];
654 if (accessorAttribute.type == TINYGLTF_TYPE_VEC3)
656 const float* positions = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessorAttribute.byteOffset]);
657 for (size_t i = 0; i < accessorAttribute.count; ++i)
659 vertices.push_back(Vec3f(positions[i * 3 + 0], positions[i * 3 + 1], positions[i * 3 + 2]));
662 else if (accessorAttribute.type == TINYGLTF_TYPE_VEC2)
664 const float* positions = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessorAttribute.byteOffset]);
665 for (size_t i = 0; i < accessorAttribute.count; ++i)
667 vertices.push_back(Vec3f(positions[i * 2 + 0], positions[i * 2 + 1], 0));
673 // ***************************** get triangle vertexID *************************** //
676 tinygltf::Model& model,
677 const tinygltf::Primitive& primitive,
678 std::vector<TopologyModule::Triangle>& triangles,
682 const tinygltf::Accessor& accessorTriangles = model.accessors[primitive.indices];
683 const tinygltf::BufferView& bufferView = model.bufferViews[accessorTriangles.bufferView];
684 const tinygltf::Buffer& buffer = model.buffers[bufferView.buffer];
686 //get Triangle Vertex id
687 if (accessorTriangles.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE)
689 const byte* elements = reinterpret_cast<const byte*>(&buffer.data[accessorTriangles.byteOffset + bufferView.byteOffset]);
691 for (size_t k = 0; k < accessorTriangles.count / 3; k++)
693 triangles.push_back(TopologyModule::Triangle(int(elements[k * 3]) + pointOffest, int(elements[k * 3 + 1]) + pointOffest, int(elements[k * 3 + 2]) + pointOffest));
697 else if (accessorTriangles.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT)
699 const unsigned short* elements = reinterpret_cast<const unsigned short*>(&buffer.data[accessorTriangles.byteOffset + bufferView.byteOffset]);
701 for (size_t k = 0; k < accessorTriangles.count / 3; k++)
703 triangles.push_back(TopologyModule::Triangle(int(elements[k * 3]) + pointOffest, int(elements[k * 3 + 1]) + pointOffest, int(elements[k * 3 + 2]) + pointOffest));
707 else if (accessorTriangles.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT)
709 const unsigned int* elements = reinterpret_cast<const unsigned int*>(&buffer.data[accessorTriangles.byteOffset + bufferView.byteOffset]);
711 for (size_t k = 0; k < accessorTriangles.count / 3; k++)
713 triangles.push_back(TopologyModule::Triangle(int(elements[k * 3]) + pointOffest, int(elements[k * 3 + 1]) + pointOffest, int(elements[k * 3 + 2]) + pointOffest));
721 void getRealByIndex(tinygltf::Model& model, int index, std::vector<Real>& result)
724 const tinygltf::Accessor& accessor = model.accessors[index];
725 const tinygltf::BufferView& bufferView = model.bufferViews[accessor.bufferView];
726 const tinygltf::Buffer& buffer = model.buffers[bufferView.buffer];
729 if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT)
731 const float* dataPtr = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessor.byteOffset]);
733 for (size_t i = 0; i < accessor.count; ++i) {
734 result.push_back(static_cast<Real>(dataPtr[i]));
737 else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_DOUBLE)
739 const double* dataPtr = reinterpret_cast<const double*>(&buffer.data[bufferView.byteOffset + accessor.byteOffset]);
741 for (size_t i = 0; i < accessor.count; ++i) {
742 result.push_back(static_cast<Real>(dataPtr[i]));
747 printf("\n !!!!!!!! Error ComponentType !!!!!!!!\n");
754 void getVec3fByIndex(tinygltf::Model& model, int index, std::vector<Vec3f>& result)
756 const tinygltf::Accessor& accessor = model.accessors[index];
757 const tinygltf::BufferView& bufferView = model.bufferViews[accessor.bufferView];
758 const tinygltf::Buffer& buffer = model.buffers[bufferView.buffer];
761 if (accessor.type == TINYGLTF_TYPE_VEC3)
763 const float* dataPtr = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessor.byteOffset]);
765 for (size_t i = 0; i < accessor.count; ++i) {
766 result.push_back(Vec3f(dataPtr[i * 3 + 0], dataPtr[i * 3 + 1], dataPtr[i * 3 + 2]));
774 void getQuatByIndex(tinygltf::Model& model, int index, std::vector<Quat<float>>& result)
776 const tinygltf::Accessor& accessor = model.accessors[index];
777 const tinygltf::BufferView& bufferView = model.bufferViews[accessor.bufferView];
778 const tinygltf::Buffer& buffer = model.buffers[bufferView.buffer];
780 if (accessor.type == TINYGLTF_TYPE_VEC4)
782 const float* dataPtr = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessor.byteOffset]);
784 for (size_t i = 0; i < accessor.count; ++i) {
785 result.push_back(Quat<float>(dataPtr[i * 4 + 0], dataPtr[i * 4 + 1], dataPtr[i * 4 + 2], dataPtr[i * 4 + 3]).normalize());
795 void getVertexBindJoint(
796 tinygltf::Model& model,
797 const tinygltf::Primitive& primitive,
798 const std::string& attributeName,
799 std::vector<Vec4f>& vec4Data,
800 const std::vector<int>& skinJoints
803 //assign Attributes for Points
804 std::map<std::string, int>::const_iterator iter;
805 iter = primitive.attributes.find(attributeName);
807 if (iter == primitive.attributes.end())
809 std::cout << attributeName << " : not found !!! \n";
813 const tinygltf::Accessor& accessorAttribute = model.accessors[iter->second];
814 const tinygltf::BufferView& bufferView = model.bufferViews[accessorAttribute.bufferView];
815 const tinygltf::Buffer& buffer = model.buffers[bufferView.buffer];
818 if (accessorAttribute.type == TINYGLTF_TYPE_VEC4)
820 if (accessorAttribute.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT)
822 const unsigned short* data = reinterpret_cast<const unsigned short*>(&buffer.data[bufferView.byteOffset + accessorAttribute.byteOffset]);
823 for (size_t i = 0; i < accessorAttribute.count; ++i)
826 vec4Data.push_back(Vec4f(skinJoints[int(data[i * 4 + 0])], skinJoints[int(data[i * 4 + 1])], skinJoints[int(data[i * 4 + 2])], skinJoints[int(data[i * 4 + 3])]));
830 else if (accessorAttribute.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT)
832 const unsigned int* data = reinterpret_cast<const unsigned int*>(&buffer.data[bufferView.byteOffset + accessorAttribute.byteOffset]);
833 for (size_t i = 0; i < accessorAttribute.count; ++i)
836 vec4Data.push_back(Vec4f(skinJoints[int(data[i * 4 + 0])], skinJoints[int(data[i * 4 + 1])], skinJoints[int(data[i * 4 + 2])], skinJoints[int(data[i * 4 + 3])]));
839 else if (accessorAttribute.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT)
841 const float* data = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessorAttribute.byteOffset]);
842 for (size_t i = 0; i < accessorAttribute.count; ++i)
845 vec4Data.push_back(Vec4f(skinJoints[int(data[i * 4 + 0])], skinJoints[int(data[i * 4 + 1])], skinJoints[int(data[i * 4 + 2])], skinJoints[int(data[i * 4 + 3])]));
853 std::string getTexUri(const std::vector<tinygltf::Texture>& textures, const std::vector<tinygltf::Image>& images, int index)
860 auto& TexSource = textures[index].source;
861 auto& TexSampler = textures[index].sampler;
863 uri = images[TexSource].uri;
869 void getNodesAndHierarchy(tinygltf::Model& model, std::map<scene, std::vector<int>> Scene_JointsNodesId, std::vector<joint>& all_Nodes, std::map<joint, std::vector<int>>& id_Dir)
871 for (auto it : Scene_JointsNodesId)
873 scene sceneId = it.first;
874 std::vector<joint> sceneJointRoots = it.second;
875 std::map<joint, int> root_jointNum;
877 for (size_t n = 0; n < sceneJointRoots.size(); n++)
879 int rootNodeId = sceneJointRoots[n];
881 std::vector<int> nullvec;
882 traverseNode(model, rootNodeId, all_Nodes, id_Dir, nullvec);
888 void traverseNode(tinygltf::Model& model, joint id, std::vector<joint>& joint_nodes, std::map<joint, std::vector<int>>& dir, std::vector<joint> currentDir)
890 const tinygltf::Node& node = model.nodes[id];
891 currentDir.push_back(id);
892 joint_nodes.push_back(id);
894 for (int childIndex : node.children) {
895 const tinygltf::Node& childNode = model.nodes[childIndex];
896 traverseNode(model, childIndex, joint_nodes, dir, currentDir);
899 std::reverse(currentDir.begin(), currentDir.end());
900 dir[id] = currentDir;
905 void getJointsTransformData(
906 const std::vector<int>& all_Joints,
907 std::vector<std::vector<int>>& joint_child,
908 std::map<int, Quat<float>>& joint_rotation,
909 std::map<int, Vec3f>& joint_scale,
910 std::map<int, Vec3f>& joint_translation,
911 std::map<int, Mat4f>& joint_matrix,
912 tinygltf::Model model
916 for (size_t k = 0; k < all_Joints.size(); k++)
918 joint jId = all_Joints[k];
919 std::vector<int>& children = model.nodes[jId].children; //std::vector<int> children ;
921 std::vector<double>& rotation = model.nodes[jId].rotation; //quat length must be 0 or 4
922 std::vector<double>& scale = model.nodes[jId].scale; //length must be 0 or 3
923 std::vector<double>& translation = model.nodes[jId].translation; //length must be 0 or 3
924 std::vector<double>& matrix = model.nodes[jId].matrix; //length must be 0 or 16
926 joint_child.push_back(children);
928 Mat4f tempT = Mat4f::identityMatrix();
929 Mat4f tempR = Mat4f::identityMatrix();
930 Mat4f tempS = Mat4f::identityMatrix();
932 if (!rotation.empty())
933 joint_rotation[jId] = (Quat<float>(rotation[0], rotation[1], rotation[2], rotation[3]));
935 joint_rotation[jId] = (Quat<float>(0, 0, 0, 0));
938 joint_scale[jId] = (Vec3f(scale[0], scale[1], scale[2]));
940 joint_scale[jId] = (Vec3f(1.0f, 1.0f, 1.0f));
942 if (!translation.empty())
943 joint_translation[jId] = (Vec3f(translation[0], translation[1], translation[2]));
945 joint_translation[jId] = (Vec3f(0.0f, 0.0f, 0.0f));
949 joint_matrix[jId] = (Mat4f(matrix[0], matrix[4], matrix[8], matrix[12],
950 matrix[1], matrix[5], matrix[9], matrix[13],
951 matrix[2], matrix[6], matrix[10], matrix[14],
952 matrix[3], matrix[7], matrix[11], matrix[15]));
959 if (!translation.empty())
960 tempT = Mat4f(1, 0, 0, translation[0], 0, 1, 0, translation[1], 0, 0, 1, translation[2], 0, 0, 0, 1);
962 tempT = Mat4f::identityMatrix();
966 if (!rotation.empty())
967 tempR = Quat<float>(rotation[0], rotation[1], rotation[2], rotation[3]).toMatrix4x4();
969 tempR = Mat4f::identityMatrix();
973 tempS = Mat4f(scale[0], 0, 0, 0, 0, scale[1], 0, 0, 0, 0, scale[2], 0, 0, 0, 0, 1);
975 tempS = Mat4f::identityMatrix();
977 joint_matrix[jId] = (tempT * tempR * tempS);// if jointmatrix not found, build it
984 std::vector<int> getJointDirByJointIndex(int Index, std::map<joint, std::vector<int>> jointId_joint_Dir)
986 std::vector<int> jointDir;
987 std::map<int, std::vector<int>>::const_iterator iter;
990 iter = jointId_joint_Dir.find(Index);
991 if (iter == jointId_joint_Dir.end())
993 std::cout << "Error: not found JointIndex \n";
997 jointDir = iter->second;
1006 void buildInverseBindMatrices(
1007 const std::vector<joint>& all_Joints,
1008 std::map<joint, Mat4f>& joint_matrix, int& maxJointId,
1009 tinygltf::Model& model,
1010 std::map<joint, Quat<float>>& joint_rotation,
1011 std::map<joint, Vec3f>& joint_translation,
1012 std::map<joint, Vec3f>& joint_scale,
1013 std::map<joint, Mat4f>& joint_inverseBindMatrix,
1014 std::map<joint, std::vector<int>> jointId_joint_Dir
1019 std::map<joint, Mat4f> tempJointMatrix = joint_matrix;
1020 std::vector<Mat4f> temp;
1022 temp.resize(maxJointId + 1);
1024 for (size_t i = 0; i < maxJointId + 1; i++)
1026 temp.push_back(Mat4f::identityMatrix());
1031 for (size_t i = 0; i < all_Joints.size(); i++)
1033 joint jointId = all_Joints[i];
1035 const std::vector<int>& jD = getJointDirByJointIndex(jointId,jointId_joint_Dir);
1037 Mat4f tempMatrix = Mat4f::identityMatrix();
1040 for (int k = 0; k < jD.size(); k++)
1042 joint select = jD[k];
1044 Vec3f tempVT = Vec3f(0, 0, 0);
1045 Vec3f tempVS = Vec3f(1, 1, 1);
1046 Quat<float> tempQR = Quat<float>(Mat3f::identityMatrix());
1048 if (model.nodes[select].matrix.empty())
1050 tempQR = joint_rotation[select];
1052 tempVT = joint_translation[select];
1054 tempVS = joint_scale[select];
1056 Mat4f mT = Mat4f(1, 0, 0, tempVT[0], 0, 1, 0, tempVT[1], 0, 0, 1, tempVT[2], 0, 0, 0, 1);
1057 Mat4f mS = Mat4f(tempVS[0], 0, 0, 0, 0, tempVS[1], 0, 0, 0, 0, tempVS[2], 0, 0, 0, 0, 1);
1058 Mat4f mR = tempQR.toMatrix4x4();
1061 tempJointMatrix[select] = mT * mS * mR;
1064 tempMatrix *= tempJointMatrix[select].inverse();
1068 joint_inverseBindMatrix[jointId] = (tempMatrix);
1072 temp[jointId] = tempMatrix;
1076 // this->stateJointInverseBindMatrix()->assign(temp); //!!!
1081 void updateJoint_Mesh_Camera_Dir(
1082 tinygltf::Model& model,
1085 std::map<joint, std::vector<int>>& jointId_joint_Dir,
1086 std::vector<joint>& all_Joints,
1087 std::vector<int>& all_Nodes,
1088 std::map<joint, std::vector<int>> nodeId_Dir,
1089 std::map<int, std::vector<int>>& meshId_Dir,
1090 std::vector<int>& all_Meshs,
1094 for (auto nId : all_Nodes)
1096 if (model.nodes[nId].mesh == -1 && model.nodes[nId].camera == -1)
1098 all_Joints.push_back(nId);
1099 jointId_joint_Dir[nId] = nodeId_Dir[nId];
1101 if (model.nodes[nId].mesh == 1)
1103 meshId_Dir[nId] = nodeId_Dir[nId];
1108 jointNum = all_Joints.size();
1109 meshNum = all_Meshs.size();
1112 if (all_Joints.size())
1113 maxJointId = *std::max_element(all_Joints.begin(), all_Joints.end());
1120 tinygltf::Model& model,
1121 const std::vector<int>& all_MeshNodeIDs,
1123 CArray<Mat4f>& mesh_Matrix
1126 maxMeshId = *std::max_element(all_MeshNodeIDs.begin(), all_MeshNodeIDs.end());
1128 mesh_Matrix.resize(maxMeshId + 1);
1134 for (size_t k = 0; k < all_MeshNodeIDs.size(); k++)
1136 std::vector<double>& rotation = model.nodes[all_MeshNodeIDs[k]].rotation; //quat length must be 0 or 4
1137 std::vector<double>& scale = model.nodes[all_MeshNodeIDs[k]].scale; //length must be 0 or 3
1138 std::vector<double>& translation = model.nodes[all_MeshNodeIDs[k]].translation; //length must be 0 or 3
1139 std::vector<double>& matrix = model.nodes[all_MeshNodeIDs[k]].matrix; //length must be 0 or 16
1141 if (!matrix.empty())
1143 mesh_Matrix[all_MeshNodeIDs[k]] = (Mat4f(matrix[0], matrix[4], matrix[8], matrix[12],
1144 matrix[1], matrix[5], matrix[9], matrix[13],
1145 matrix[2], matrix[6], matrix[10], matrix[14],
1146 matrix[3], matrix[7], matrix[11], matrix[15]));
1151 //Translation Matrix
1153 if (!translation.empty())
1154 tempT = Mat4f(1, 0, 0, translation[0], 0, 1, 0, translation[1], 0, 0, 1, translation[2], 0, 0, 0, 1);
1156 tempT = Mat4f::identityMatrix();
1159 if (!rotation.empty())
1160 tempR = Quat<float>(rotation[0], rotation[1], rotation[2], rotation[3]).toMatrix4x4();
1162 tempR = Mat4f::identityMatrix();
1166 tempS = Mat4f(scale[0], 0, 0, 0, 0, scale[1], 0, 0, 0, 0, scale[2], 0, 0, 0, 0, 1);
1168 tempS = Mat4f::identityMatrix();
1170 mesh_Matrix[all_MeshNodeIDs[k]] = (tempT * tempR * tempS);// if jointmatrix not found, build it
1177 void importAnimation(
1178 tinygltf::Model model,
1179 std::map<joint, Vec3i>& joint_output,
1180 std::map<joint, Vec3f>& joint_input,
1181 std::map<joint, std::vector<Vec3f>>& joint_T_f_anim,
1182 std::map<joint, std::vector<Real>>& joint_T_Time,
1183 std::map<joint, std::vector<Vec3f>>& joint_S_f_anim,
1184 std::map<joint, std::vector<Real>>& joint_S_Time,
1185 std::map<joint, std::vector<Quat<float>>>& joint_R_f_anim,
1186 std::map<joint, std::vector<Real>>& joint_R_Time
1189 using namespace tinygltf;
1191 for (size_t i = 0; i < model.nodes.size(); i++)
1193 joint_output[i] = Vec3i(-1, -1, -1); //
1194 joint_input[i] = Vec3f(NULL_TIME, NULL_TIME, NULL_TIME);
1197 //Reset loading animation ;
1198 for (size_t i = 0; i < model.animations.size(); i++)
1200 std::string& name = model.animations[i].name;
1201 std::vector<AnimationChannel>& channels = model.animations[i].channels;
1202 std::vector<AnimationSampler>& samplers = model.animations[i].samplers;
1204 for (size_t j = 0; j < channels.size(); j++) //channels
1207 int& samplerId = channels[j].sampler; // required
1208 joint& joint_nodeId = channels[j].target_node; // required (index of the node to target)
1209 std::string& target_path = channels[j].target_path; // required in ["translation", "rotation", "scale","weights"]
1212 int& input = samplers[samplerId].input; //real time
1213 int& output = samplers[samplerId].output; //transform bufferid
1214 std::string& interpolation = samplers[samplerId].interpolation;
1216 //struct AnimationSampler {
1217 // int input; // Time
1218 // int output; // Data
1219 // std::string interpolation; // "LINEAR", "STEP","CUBICSPLINE" or user defined // string. default "LINEAR"
1224 if (target_path == "translation")
1226 joint_output[joint_nodeId][0] = output;
1227 joint_input[joint_nodeId][0] = input;
1229 else if (target_path == "scale")
1231 joint_output[joint_nodeId][1] = output;
1232 joint_input[joint_nodeId][0] = input;
1234 else if (target_path == "rotation")
1236 joint_output[joint_nodeId][2] = output;
1237 joint_input[joint_nodeId][0] = input;
1243 //out animation data
1244 std::vector<Vec3f> frame_T_anim;
1245 std::vector<Quat<float>> frame_R_anim;
1246 std::vector<Vec3f> frame_S_anim;
1248 std::vector<Real> frame_T_Time;
1249 std::vector<Real> frame_R_Time;
1250 std::vector<Real> frame_S_Time;
1252 if (target_path == "translation")
1254 getVec3fByIndex(model, output, frame_T_anim);
1255 joint_T_f_anim[joint_nodeId] = frame_T_anim;
1257 getRealByIndex(model, input, frame_T_Time);
1258 joint_T_Time[joint_nodeId] = frame_T_Time;
1260 else if (target_path == "scale")
1262 getVec3fByIndex(model, output, frame_S_anim);
1263 joint_S_f_anim[joint_nodeId] = frame_S_anim;
1264 getRealByIndex(model, input, frame_S_Time);
1265 joint_S_Time[joint_nodeId] = frame_S_Time;
1267 else if (target_path == "rotation")
1269 getQuatByIndex(model, output, frame_R_anim);
1270 joint_R_f_anim[joint_nodeId] = frame_R_anim;
1271 getRealByIndex(model, input, frame_R_Time);
1272 joint_R_Time[joint_nodeId] = frame_R_Time;
1281 template< typename Coord, typename Vec4f, typename Mat4f, typename Vec2u>
1282 __global__ void PointsAnimation(
1283 DArray<Coord> intialPosition,
1284 DArray<Coord> worldPosition,
1285 DArray<Mat4f> joint_inverseBindMatrix,
1286 DArray<Mat4f> WorldMatrix,
1288 DArray<Vec4f> bind_joints_0,
1289 DArray<Vec4f> bind_joints_1,
1290 DArray<Vec4f> weights_0,
1291 DArray<Vec4f> weights_1,
1299 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
1300 if (pId >= worldPosition.size()) return;
1302 if (pId<range[0] || pId>range[1])
1305 Vec4f result = Vec4f(0, 0, 0, float(!isNormal));
1307 int skinInfoVertexId = pId - range[0];
1311 bool j0 = bind_joints_0.size();
1312 bool j1 = bind_joints_1.size();
1316 for (unsigned int i = 0; i < 4; i++)
1318 int jointId = int(bind_joints_0[skinInfoVertexId][i]);
1319 Real weight = weights_0[skinInfoVertexId][i];
1321 offest = intialPosition[pId];
1322 Vec4f v_bone_space = joint_inverseBindMatrix[jointId] * Vec4f(offest[0], offest[1], offest[2], float(!isNormal));//
1324 result += (transform * WorldMatrix[jointId] * v_bone_space) * weight;
1329 for (unsigned int i = 0; i < 4; i++)
1331 int jointId = int(bind_joints_1[skinInfoVertexId][i]);
1332 Real weight = weights_1[skinInfoVertexId][i];
1334 offest = intialPosition[pId];
1335 Vec4f v_bone_space = joint_inverseBindMatrix[jointId] * Vec4f(offest[0], offest[1], offest[2], float(!isNormal));//
1337 result += (WorldMatrix[jointId] * v_bone_space) * weight;
1341 //result = transform * result;
1345 worldPosition[pId][0] = result[0];
1346 worldPosition[pId][1] = result[1];
1347 worldPosition[pId][2] = result[2];
1351 worldPosition[pId] = worldPosition[pId].normalize();
1355 template< typename Vec3f, typename Vec4f, typename Mat4f, typename Vec2u>
1357 DArray<Vec3f>& intialPosition,
1358 DArray<Vec3f>& worldPosition,
1359 DArray<Mat4f>& joint_inverseBindMatrix,
1360 DArray<Mat4f>& WorldMatrix,
1362 DArray<Vec4f>& bind_joints_0,
1363 DArray<Vec4f>& bind_joints_1,
1364 DArray<Vec4f>& weights_0,
1365 DArray<Vec4f>& weights_1,
1374 cuExecute(intialPosition.size(),
1378 joint_inverseBindMatrix,
1391 template void skinAnimation<Vec3f, Vec4f, Mat4f, Vec2u>(DArray<Vec3f>& intialPosition,
1392 DArray<Vec3f>& worldPosition,
1393 DArray<Mat4f>& joint_inverseBindMatrix,
1394 DArray<Mat4f>& WorldMatrix,
1396 DArray<Vec4f>& bind_joints_0,
1397 DArray<Vec4f>& bind_joints_1,
1398 DArray<Vec4f>& weights_0,
1399 DArray<Vec4f>& weights_1,
1407 template<typename Triangle>
1408 __global__ void updateVertexId_Shape(
1409 DArray<Triangle> triangle,
1410 DArray<uint> ID_shapeId,
1414 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
1415 if (pId >= triangle.size()) return;
1417 ID_shapeId[triangle[pId][0]] = shapeId;
1418 ID_shapeId[triangle[pId][1]] = shapeId;
1419 ID_shapeId[triangle[pId][2]] = shapeId;
1422 template< typename Triangle>
1423 void updateVertexIdShape(
1424 DArray<Triangle>& triangle,
1425 DArray<uint>& ID_shapeId,
1431 updateVertexId_Shape,
1438 template void updateVertexIdShape<TopologyModule::Triangle>(DArray<TopologyModule::Triangle>& triangle,
1439 DArray<uint>& ID_shapeId,
1445 template<typename Mat4f, typename Vec3f >
1446 __global__ void ShapeTransform(
1447 DArray<Vec3f> intialPosition,
1448 DArray<Vec3f> worldPosition,
1449 DArray<Vec3f> intialNormal,
1450 DArray<Vec3f> Normal,
1451 DArray<Mat4f> WorldMatrix,
1452 DArray<uint> vertexId_shape,
1453 DArray<int> shapeId_MeshId
1456 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
1457 if (pId >= intialPosition.size()) return;
1459 int shape = vertexId_shape[pId];
1461 int MeshId = shapeId_MeshId[shape];
1463 Vec4f tempV = Vec4f(intialPosition[pId][0], intialPosition[pId][1], intialPosition[pId][2], 1);
1464 Vec4f tempN = Vec4f(intialNormal[pId][0], intialNormal[pId][1], intialNormal[pId][2], 0);
1467 auto iP = intialPosition[pId];
1470 tempV = WorldMatrix[MeshId] * tempV;
1471 tempN = WorldMatrix[MeshId] * tempN;
1473 worldPosition[pId] = Vec3f(tempV[0], tempV[1], tempV[2]);
1474 Normal[pId] = Vec3f(tempN[0], tempN[1], tempN[2]);
1477 auto iP = worldPosition[pId];
1482 template<typename Mat4f, typename Vec3f >
1483 void shapeTransform(
1484 DArray<Vec3f>& intialPosition,
1485 DArray<Vec3f>& worldPosition,
1486 DArray<Vec3f>& intialNormal,
1487 DArray<Vec3f>& Normal,
1488 DArray<Mat4f>& WorldMatrix,
1489 DArray<uint>& vertexId_shape,
1490 DArray<int>& shapeId_MeshId
1493 cuExecute(intialPosition.size(),
1505 template void shapeTransform<Mat4f, Vec3f>(DArray<Vec3f>& intialPosition,
1506 DArray<Vec3f>& worldPosition,
1507 DArray<Vec3f>& intialNormal,
1508 DArray<Vec3f>& Normal,
1509 DArray<Mat4f>& WorldMatrix,
1510 DArray<uint>& vertexId_shape,
1511 DArray<int>& shapeId_MeshId
1514 template<typename Vec3f>
1515 __global__ void C_SetupPoints(
1516 DArray<Vec3f> newPos,
1521 uint tId = threadIdx.x + blockDim.x * blockIdx.x;
1522 if (tId >= pos.size()) return;
1524 if (tId < pos.size() - 1 && radix[tId] != radix[tId + 1])
1526 newPos[radix[tId]] = pos[tId];
1528 else if (tId == pos.size() - 1 && pos.size() > 2)
1530 if (radix[tId] != radix[tId - 1])
1531 newPos[radix[tId]] = pos[tId];
1536 template<typename Vec3f>
1538 DArray<Vec3f>& newPos,
1543 cuExecute(pos.size(),
1551 template void setupPoints<Vec3f>(DArray<Vec3f>& newPos,
1556 template<typename uint>
1557 __global__ void C_Shape_PointCounter(
1558 DArray<int> counter,
1559 DArray<uint> point_ShapeIds,
1563 uint tId = threadIdx.x + blockDim.x * blockIdx.x;
1564 if (tId >= point_ShapeIds.size()) return;
1566 counter[tId] = (point_ShapeIds[tId] == target) ? 1 : 0;
1569 template<typename uint>
1570 void Shape_PointCounter(
1571 DArray<int>& counter,
1572 DArray<uint>& point_ShapeIds,
1575 cuExecute(point_ShapeIds.size(),
1576 C_Shape_PointCounter,
1583 template void Shape_PointCounter <uint>(DArray<int>& counter,
1584 DArray<uint>& point_ShapeIds,
1588 template< typename Vec3f, typename uint>
1589 __global__ void ShapeToCenter(
1590 DArray<Vec3f> iniPos,
1591 DArray<Vec3f> finalPos,
1592 DArray<uint> shapeId,
1596 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
1597 if (pId >= iniPos.size()) return;
1599 finalPos[pId] = iniPos[pId] - t[shapeId[pId]];
1600 Vec4f P = Vec4f(finalPos[pId][0], finalPos[pId][1], finalPos[pId][2], 1);
1602 finalPos[pId] = Vec3f(P[0], P[1], P[2]);
1606 template< typename Vec3f, typename uint>
1608 DArray<Vec3f>& iniPos,
1609 DArray<Vec3f>& finalPos,
1610 DArray<uint>& shapeId,
1614 cuExecute(finalPos.size(),
1623 template void shapeToCenter <Vec3f,uint>(DArray<Vec3f>& iniPos,
1624 DArray<Vec3f>& finalPos,
1625 DArray<uint>& shapeId,