PeriDyno 1.0.0
Loading...
Searching...
No Matches
GltfFunc.cu
Go to the documentation of this file.
1
2#include "GltfFunc.h"
3#include "ImageLoader.h"
4
5#define NULL_POSITION (-959959.9956)
6#define TINYGLTF_IMPLEMENTATION
7
8namespace dyno
9{
10 void loadGLTFTextureMesh(std::shared_ptr<TextureMesh> texMesh,const std::string& filepath)
11 {
12 using namespace tinygltf;
13
14 auto model = new Model;
15
16 TinyGLTF loader;
17 std::string err;
18 std::string warn;
19
20 bool ret = loader.LoadASCIIFromFile(model, &err, &warn, filepath);
21 if (!warn.empty())
22 printf("Warn: %s\n", warn.c_str());
23
24 if (!err.empty())
25 printf("Err: %s\n", err.c_str());
26
27 if (!ret)
28 {
29 printf("Failed to parse glTF\n");
30 return;
31
32 }
33 // import Scenes:
34
35 loadGLTFMaterial(*model, texMesh,filepath);
36
37 DArray<Vec3f> initialPosition;
38 DArray<Vec3f> initialNormal;
39 DArray<Mat4f> d_mesh_Matrix;
40 DArray<int> d_shape_meshId;
41
42 loadGLTFShape(
43 *model,
44 texMesh,
45 filepath,
46 &initialPosition,
47 &initialNormal,
48 &d_mesh_Matrix,
49 &d_shape_meshId
50 );
51
52 //ToCenter
53
54 shapeTransform(initialPosition,
55 texMesh->vertices(),
56 initialNormal,
57 texMesh->normals(),
58 d_mesh_Matrix,
59 texMesh->shapeIds(),
60 d_shape_meshId
61 );
62
63
64 auto shapeNum = texMesh->shapes().size();
65
66 CArray<Vec3f> c_shapeCenter;
67 c_shapeCenter.resize(shapeNum);
68 //counter
69 for (uint i = 0; i < shapeNum; i++)
70 {
71 DArray<int> counter;
72 counter.resize(texMesh->vertices().size());
73
74 Shape_PointCounter(counter,
75 texMesh->shapeIds(),
76 i);
77
78
79 Reduction<int> reduce;
80 int num = reduce.accumulate(counter.begin(), counter.size());
81
82 DArray<Vec3f> targetPoints;
83 targetPoints.resize(num);
84
85 Scan<int> scan;
86 scan.exclusive(counter.begin(), counter.size());
87
88 setupPoints(
89 targetPoints,
90 texMesh->vertices(),
91 counter
92 );
93
94
95
96 Reduction<Vec3f> reduceBounding;
97
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());
101
102 bounding.v0 = lo;
103 bounding.v1 = hi;
104 texMesh->shapes()[i]->boundingTransform.translation() = (lo + hi) / 2;
105
106 c_shapeCenter[i] = (lo + hi) / 2;
107
108 targetPoints.clear();
109
110 counter.clear();
111 }
112
113 DArray<Vec3f> d_ShapeCenter;
114 DArray<Vec3f> unCenterPosition;
115
116 d_ShapeCenter.assign(c_shapeCenter); // Used to "ToCenter"
117 unCenterPosition.assign(texMesh->vertices());
118
119 //ToCenter
120 if (true)//varUseInstanceTransform()->getValue()
121 {
122 shapeToCenter(unCenterPosition,
123 texMesh->vertices(),
124 texMesh->shapeIds(),
125 d_ShapeCenter);
126
127
128 auto& reShapes = texMesh->shapes();
129
130 for (size_t i = 0; i < shapeNum; i++)
131 {
132 reShapes[i]->boundingTransform.translation() = reShapes[i]->boundingTransform.translation() ;//+ this->varLocation()->getValue()
133 }
134 }
135 else
136 {
137 auto& reShapes = texMesh->shapes();
138
139 for (size_t i = 0; i < shapeNum; i++)
140 {
141 reShapes[i]->boundingTransform.translation() = Vec3f(0);
142 }
143 }
144
145 }
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 )
147 {
148 typedef int joint;
149 typedef int shape;
150 typedef int mesh;
151 typedef int primitive;
152 typedef int scene;
153
154 //
155 std::vector<Vec3f> vertices;
156 std::vector<Vec3f> normals;
157 std::vector<Vec3f> texCoord0;
158 std::vector<Vec3f> texCoord1;
159
160 std::vector<TopologyModule::Triangle> trianglesVector;
161 int shapeNum = 0;
162
163 for (auto meshId : model.meshes)
164 {
165 shapeNum += meshId.primitives.size();
166 }
167
168 //materials
169 loadGLTFMaterial(model, texMesh, filepath);
170
171 //shapes
172
173 auto& reShapes = texMesh->shapes();
174 reShapes.clear();
175 reShapes.resize(shapeNum);
176
177 auto& reMats = texMesh->materials();
178
179 std::vector<Vec3f> shapeCenter;
180
181 int primitive_PointOffest;
182 int currentShape = 0;
183 std::map<int, std::vector<Vec2u>> shape2VerticeRange;
184
185 std::map<int, int> shape_meshId;
186 //skin_VerticeRange;
187 {
188 int tempShapeId = 0;
189 int tempSize = 0;
190 for (int mId = 0; mId < model.meshes.size(); mId++)
191 {
192 // import Mesh
193 std::vector<dyno::TopologyModule::Triangle> vertexIndex;
194 std::vector<dyno::TopologyModule::Triangle> normalIndex;
195 std::vector<dyno::TopologyModule::Triangle> texCoordIndex;
196
197 int primNum = model.meshes[mId].primitives.size();
198
199 for (size_t pId = 0; pId < primNum; pId++) //shape
200 {
201
202 primitive_PointOffest = (vertices.size());
203
204 //current primitive
205 const tinygltf::Primitive& primitive = model.meshes[mId].primitives[pId];
206
207 std::map<std::string, int> attributesName = primitive.attributes;
208
209
210 //Set Vertices
211 getVec3fByAttributeName(model, primitive, std::string("POSITION"), vertices);
212 shape2VerticeRange[tempShapeId].push_back(Vec2u(tempSize, vertices.size() - 1));
213 tempShapeId++;
214 tempSize = vertices.size();
215
216 //Set Normal
217 getVec3fByAttributeName(model, primitive, std::string("NORMAL"), normals);
218
219 //Set TexCoord
220
221 getVec3fByAttributeName(model, primitive, std::string("TEXCOORD_0"), texCoord0);
222
223 getVec3fByAttributeName(model, primitive, std::string("TEXCOORD_1"), texCoord1);
224
225
226
227 //Set Triangles
228
229 if (primitive.mode == TINYGLTF_MODE_TRIANGLES)
230 {
231
232 std::vector<TopologyModule::Triangle> tempTriangles;
233
234 getTriangles(model, primitive, tempTriangles, primitive_PointOffest);
235
236 vertexIndex = (tempTriangles);
237 normalIndex = (tempTriangles);
238 texCoordIndex = (tempTriangles);
239
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);
245
246 getBoundingBoxByName(model, primitive, std::string("POSITION"), reShapes[currentShape]->boundingBox, reShapes[currentShape]->boundingTransform);//,Transform3f& transform
247
248 shapeCenter.push_back(reShapes[currentShape]->boundingTransform.translation());
249
250 int matId = primitive.material;
251 if (matId != -1 && matId < reMats.size())//
252 {
253 reShapes[currentShape]->material = reMats[matId];
254 //printf("shape_materialID : %d - %d\n",currentShape,matId);
255
256 //printf("texture size %d - %d:\n", reMats[matId]->texColor.nx(), reMats[matId]->texColor.ny());
257 }
258 else
259 {
260 reShapes[currentShape]->material = NULL;
261 }
262
263 //else //
264 //{
265 // auto newMat = std::make_shared<Material>();
266
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;
272
273 // reMats.push_back(newMat);
274
275 // reShapes[currentShape]->material = reMats[reMats.size() - 1];
276 // printf("shape_materialID : %d - %d\n", currentShape, currentShape);
277 //}
278
279 trianglesVector.insert(trianglesVector.end(), tempTriangles.begin(), tempTriangles.end());
280
281 }
282 currentShape++;
283 }
284 }
285 }
286
287 std::map<uint, uint> vertexId_shapeId;
288
289 texMesh->shapeIds().resize(vertices.size());
290
291 //Import Skin;
292 {
293 //Update ;
294 std::map<int, std::vector<joint>> shape_skinJoint;
295
296 for (size_t i = 0; i < model.skins.size(); i++)
297 {
298 auto joints = model.skins[i].joints;
299 shape_skinJoint[i] = joints;
300 }
301
302
303 std::map<int, std::vector<joint>> skinNode_MeshId;
304 std::map<mesh, std::vector<shape>> meshNode_Primitive;
305
306 for (size_t i = 0; i < model.nodes.size(); i++)
307 {
308 if (model.nodes[i].skin != -1)
309 {
310 skinNode_MeshId[i].push_back(model.nodes[i].mesh);
311 }
312 }
313
314 {
315 int tempShapeId = 0;
316
317 for (int mId = 0; mId < model.meshes.size(); mId++)
318 {
319 int primNum = model.meshes[mId].primitives.size();
320
321 for (size_t pId = 0; pId < primNum; pId++)
322 {
323 meshNode_Primitive[mId].push_back(tempShapeId);
324 tempShapeId++;
325 }
326 }
327 }
328
329
330
331 if (skinData != nullptr)
332 {
333 skinData->clearSkinInfo();
334 {
335 int tempShapeId = 0;
336 for (int mId = 0; mId < model.meshes.size(); mId++)
337 {
338 int primNum = model.meshes[mId].primitives.size();
339
340 for (size_t pId = 0; pId < primNum; pId++)
341 {
342 std::vector<joint> skinJoints;
343
344 if (shape_skinJoint.find(0) != shape_skinJoint.end())
345 skinJoints = shape_skinJoint[tempShapeId];
346
347 if (skinJoints.size())
348 {
349
350 std::vector<Vec4f> weight0;
351 std::vector<Vec4f> weight1;
352
353 std::vector<Vec4f> joint0;
354 std::vector<Vec4f> joint1;
355
356 getVec4ByAttributeName(model, model.meshes[mId].primitives[pId], std::string("WEIGHTS_0"), weight0);//
357
358 getVec4ByAttributeName(model, model.meshes[mId].primitives[pId], std::string("WEIGHTS_1"), weight1);//
359
360 getVertexBindJoint(model, model.meshes[mId].primitives[pId], std::string("JOINTS_0"), joint0, skinJoints);
361
362 getVertexBindJoint(model, model.meshes[mId].primitives[pId], std::string("JOINTS_1"), joint1, skinJoints);
363
364 skinData->pushBack_Data(weight0, weight1, joint0, joint1);
365
366
367 }
368 tempShapeId++;
369 }
370 }
371 }
372
373 for (auto it : shape2VerticeRange)
374 {
375 skinData->skin_VerticeRange[it.first] = it.second;
376 }
377 }
378
379
380 }
381
382
383 for (int i = 0; i < texMesh->shapes().size(); i++)
384 {
385 auto it = texMesh->shapes()[i];
386
387 updateVertexIdShape(texMesh->shapes()[i]->vertexIndex, texMesh->shapeIds(),i, texMesh->shapes()[i]->vertexIndex.size());
388
389 }
390
391 CArray<int> c_shape_meshId;
392
393 c_shape_meshId.resize(shape_meshId.size());
394
395 //getMeshMatrix
396
397 std::vector<int> MeshNodeIDs;
398
399 for (size_t nId = 0; nId < model.nodes.size(); nId++)
400 {
401 int j = 0;
402
403 if (model.nodes[nId].mesh >= 0)
404 {
405 j++;
406 MeshNodeIDs.push_back(nId);
407 }
408
409 }
410 int maxMeshId;
411 CArray<Mat4f> mesh_Matrix;
412
413 getMeshMatrix(model, MeshNodeIDs, maxMeshId, mesh_Matrix);
414
415 for (auto it : shape_meshId)
416 {
417 c_shape_meshId[it.first] = MeshNodeIDs[it.second];
418 }
419
420 if (d_shape_meshId != nullptr)
421 d_shape_meshId->assign(c_shape_meshId);
422
423 if (initialPosition != nullptr)
424 initialPosition->assign(vertices);
425
426 if (initialNormal != nullptr)
427 initialNormal->assign(normals);
428
429 texMesh->vertices().assign(vertices);
430 texMesh->normals().assign(normals);
431
432 if (d_mesh_Matrix != nullptr)
433 d_mesh_Matrix->assign(mesh_Matrix);
434
435
436 texMesh->shapeIds().resize(texMesh->vertices().size());
437
438
439
440 // flip UV
441 {
442 std::vector<Vec2f> tempTexCoord;
443 for (auto uv0 : texCoord0)
444 {
445 tempTexCoord.push_back(Vec2f(uv0[0], 1 - uv0[1])); // uv.v need flip
446 }
447 texMesh->texCoords().assign(tempTexCoord);
448
449
450 tempTexCoord.clear();
451 for (auto uv1 : texCoord1)
452 {
453 tempTexCoord.push_back(Vec2f(uv1[0], 1 - uv1[1]));
454 }
455 texCoord1.clear();
456 tempTexCoord.clear();
457 }
458
459 }
460
461 void loadGLTFMaterial(tinygltf::Model& model, std::shared_ptr<TextureMesh> texMesh, FilePath filename)
462 {
463 const std::vector<tinygltf::Material>& sourceMaterials = model.materials;
464
465 auto& reMats = texMesh->materials();
466 reMats.clear();
467 if (sourceMaterials.size()) //use materials.size()
468 {
469 reMats.resize(sourceMaterials.size());
470 }
471
472
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);
477
478
479 for (int matId = 0; matId < sourceMaterials.size(); matId++)
480 {
481 auto material = sourceMaterials[matId];
482 auto color = material.pbrMetallicRoughness.baseColorFactor;
483 auto roughness = material.pbrMetallicRoughness.roughnessFactor;
484
485 auto metallic = material.pbrMetallicRoughness.metallicFactor;
486
487 auto colorTexId = material.pbrMetallicRoughness.baseColorTexture.index;
488 auto texCoord = material.pbrMetallicRoughness.baseColorTexture.texCoord;
489
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;
495
496 std::string colorUri = getTexUri(textures, images, colorTexId);
497 std::shared_ptr<ImageLoader> loader = std::make_shared<ImageLoader>();
498
499 if (!colorUri.empty())
500 {
501
502 auto root = filename.path().parent_path();
503 colorUri = (root / colorUri).string();
504
505 if (loader->loadImage(colorUri.c_str(), texture))
506 {
507 reMats[matId]->texColor.assign(texture);
508 }
509 }
510 else
511 {
512 if (reMats[matId]->texColor.size())
513 reMats[matId]->texColor.clear();
514 }
515
516 auto bumpTexId = material.normalTexture.index;
517 auto scale = material.normalTexture.scale;
518 std::string bumpUri = getTexUri(textures, images, bumpTexId);
519
520 if (!bumpUri.empty())
521 {
522 auto root = filename.path().parent_path();
523 bumpUri = (root / bumpUri).string();
524
525 if (loader->loadImage(bumpUri.c_str(), texture))
526 {
527 reMats[matId]->texBump.assign(texture);
528 reMats[matId]->bumpScale = scale;
529 }
530 }
531 else
532 {
533 if (reMats[matId]->texBump.size())
534 reMats[matId]->texBump.clear();
535 }
536
537 }
538
539 }
540
541
542 void getBoundingBoxByName(
543 tinygltf::Model& model,
544 const tinygltf::Primitive& primitive,
545 const std::string& attributeName,
546 TAlignedBox3D<Real>& bound,
547 Transform3f& transform
548 )
549 {
550 //assign Attributes for Points
551 std::map<std::string, int>::const_iterator iter;
552 iter = primitive.attributes.find(attributeName);
553
554 if (iter == primitive.attributes.end())
555 {
556 std::cout << attributeName << " : not found !!! \n";
557 return;
558 }
559
560 auto min = model.accessors[iter->second].minValues;
561 auto max = model.accessors[iter->second].maxValues;
562 if (min.size() != 3)
563 {
564 std::cout << attributeName << " : not Vec3f !!! \n";
565 return;
566 }
567
568 Vec3f v0 = Vec3f(min[0], min[1], min[2]);
569 Vec3f v1 = Vec3f(max[0], max[1], max[2]);
570
571 bound = TAlignedBox3D<Real>(v0, v1);
572
573 Vec3f center = (v0 + v1) / 2;
574 transform = Transform3f(Vec3f(center), Mat3f::identityMatrix(), Vec3f(1));
575
576 }
577
578
579 void getVec4ByAttributeName(tinygltf::Model& model,
580 const tinygltf::Primitive& primitive,
581 const std::string& attributeName,
582 std::vector<Vec4f>& vec4Data
583 )
584 {
585 //assign Attributes for Points
586 std::map<std::string, int>::const_iterator iter;
587 iter = primitive.attributes.find(attributeName);
588
589 if (iter == primitive.attributes.end())
590 {
591 std::cout << attributeName << " : not found !!! \n";
592 return;
593 }
594
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];
598
599 if (accessorAttribute.type == TINYGLTF_TYPE_VEC4)
600 {
601 if (accessorAttribute.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT)
602 {
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)
605 {
606
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])));
608 }
609 }
610 else if (accessorAttribute.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT)
611 {
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)
614 {
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])));
616 }
617 }
618 else if (accessorAttribute.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT)
619 {
620 const float* data = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessorAttribute.byteOffset]);
621 for (size_t i = 0; i < accessorAttribute.count; ++i)
622 {
623 vec4Data.push_back(Vec4f(data[i * 4 + 0], data[i * 4 + 1], data[i * 4 + 2], data[i * 4 + 3]));
624 }
625 }
626 }
627
628 }
629
630
631 // ********************************** getVec3f By Attribute Name *************************//
632
633 void getVec3fByAttributeName(
634 tinygltf::Model& model,
635 const tinygltf::Primitive& primitive,
636 const std::string& attributeName,
637 std::vector<Vec3f>& vertices
638 )
639 {
640 //assign Attributes for Points
641 std::map<std::string, int>::const_iterator iter;
642 iter = primitive.attributes.find(attributeName);
643
644 if (iter == primitive.attributes.end())
645 {
646 std::cout << attributeName << " : not found !!! \n";
647 return;
648 }
649
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];
653
654 if (accessorAttribute.type == TINYGLTF_TYPE_VEC3)
655 {
656 const float* positions = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessorAttribute.byteOffset]);
657 for (size_t i = 0; i < accessorAttribute.count; ++i)
658 {
659 vertices.push_back(Vec3f(positions[i * 3 + 0], positions[i * 3 + 1], positions[i * 3 + 2]));
660 }
661 }
662 else if (accessorAttribute.type == TINYGLTF_TYPE_VEC2)
663 {
664 const float* positions = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessorAttribute.byteOffset]);
665 for (size_t i = 0; i < accessorAttribute.count; ++i)
666 {
667 vertices.push_back(Vec3f(positions[i * 2 + 0], positions[i * 2 + 1], 0));
668 }
669 }
670 }
671
672
673 // ***************************** get triangle vertexID *************************** //
674
675 void getTriangles(
676 tinygltf::Model& model,
677 const tinygltf::Primitive& primitive,
678 std::vector<TopologyModule::Triangle>& triangles,
679 int pointOffest
680 )
681 {
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];
685
686 //get Triangle Vertex id
687 if (accessorTriangles.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE)
688 {
689 const byte* elements = reinterpret_cast<const byte*>(&buffer.data[accessorTriangles.byteOffset + bufferView.byteOffset]);
690
691 for (size_t k = 0; k < accessorTriangles.count / 3; k++)
692 {
693 triangles.push_back(TopologyModule::Triangle(int(elements[k * 3]) + pointOffest, int(elements[k * 3 + 1]) + pointOffest, int(elements[k * 3 + 2]) + pointOffest));
694 }
695
696 }
697 else if (accessorTriangles.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT)
698 {
699 const unsigned short* elements = reinterpret_cast<const unsigned short*>(&buffer.data[accessorTriangles.byteOffset + bufferView.byteOffset]);
700
701 for (size_t k = 0; k < accessorTriangles.count / 3; k++)
702 {
703 triangles.push_back(TopologyModule::Triangle(int(elements[k * 3]) + pointOffest, int(elements[k * 3 + 1]) + pointOffest, int(elements[k * 3 + 2]) + pointOffest));
704 }
705
706 }
707 else if (accessorTriangles.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT)
708 {
709 const unsigned int* elements = reinterpret_cast<const unsigned int*>(&buffer.data[accessorTriangles.byteOffset + bufferView.byteOffset]);
710
711 for (size_t k = 0; k < accessorTriangles.count / 3; k++)
712 {
713 triangles.push_back(TopologyModule::Triangle(int(elements[k * 3]) + pointOffest, int(elements[k * 3 + 1]) + pointOffest, int(elements[k * 3 + 2]) + pointOffest));
714 }
715
716 }
717 }
718
719
720
721 void getRealByIndex(tinygltf::Model& model, int index, std::vector<Real>& result)
722 {
723
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];
727
728
729 if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT)
730 {
731 const float* dataPtr = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessor.byteOffset]);
732
733 for (size_t i = 0; i < accessor.count; ++i) {
734 result.push_back(static_cast<Real>(dataPtr[i]));
735 }
736 }
737 else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_DOUBLE)
738 {
739 const double* dataPtr = reinterpret_cast<const double*>(&buffer.data[bufferView.byteOffset + accessor.byteOffset]);
740
741 for (size_t i = 0; i < accessor.count; ++i) {
742 result.push_back(static_cast<Real>(dataPtr[i]));
743 }
744 }
745 else
746 {
747 printf("\n !!!!!!!! Error ComponentType !!!!!!!!\n");
748 }
749
750 return;
751 }
752
753
754 void getVec3fByIndex(tinygltf::Model& model, int index, std::vector<Vec3f>& result)
755 {
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];
759
760
761 if (accessor.type == TINYGLTF_TYPE_VEC3)
762 {
763 const float* dataPtr = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessor.byteOffset]);
764
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]));
767 }
768 }
769
770
771 }
772
773
774 void getQuatByIndex(tinygltf::Model& model, int index, std::vector<Quat<float>>& result)
775 {
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];
779
780 if (accessor.type == TINYGLTF_TYPE_VEC4)
781 {
782 const float* dataPtr = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessor.byteOffset]);
783
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());
786 }
787 }
788
789
790
791 }
792
793
794
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
801 )
802 {
803 //assign Attributes for Points
804 std::map<std::string, int>::const_iterator iter;
805 iter = primitive.attributes.find(attributeName);
806
807 if (iter == primitive.attributes.end())
808 {
809 std::cout << attributeName << " : not found !!! \n";
810 return;
811 }
812
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];
816
817
818 if (accessorAttribute.type == TINYGLTF_TYPE_VEC4)
819 {
820 if (accessorAttribute.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT)
821 {
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)
824 {
825
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])]));
827
828 }
829 }
830 else if (accessorAttribute.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT)
831 {
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)
834 {
835
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])]));
837 }
838 }
839 else if (accessorAttribute.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT)
840 {
841 const float* data = reinterpret_cast<const float*>(&buffer.data[bufferView.byteOffset + accessorAttribute.byteOffset]);
842 for (size_t i = 0; i < accessorAttribute.count; ++i)
843 {
844
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])]));
846 }
847 }
848 }
849 }
850
851
852
853 std::string getTexUri(const std::vector<tinygltf::Texture>& textures, const std::vector<tinygltf::Image>& images, int index)
854 {
855 std::string uri;
856
857 if (index == -1)
858 return uri;
859
860 auto& TexSource = textures[index].source;
861 auto& TexSampler = textures[index].sampler;
862
863 uri = images[TexSource].uri;
864
865 return uri;
866 }
867
868
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)
870 {
871 for (auto it : Scene_JointsNodesId)
872 {
873 scene sceneId = it.first;
874 std::vector<joint> sceneJointRoots = it.second;
875 std::map<joint, int> root_jointNum;
876
877 for (size_t n = 0; n < sceneJointRoots.size(); n++)
878 {
879 int rootNodeId = sceneJointRoots[n];
880
881 std::vector<int> nullvec;
882 traverseNode(model, rootNodeId, all_Nodes, id_Dir, nullvec);
883 }
884
885 }
886 }
887
888 void traverseNode(tinygltf::Model& model, joint id, std::vector<joint>& joint_nodes, std::map<joint, std::vector<int>>& dir, std::vector<joint> currentDir)
889 {
890 const tinygltf::Node& node = model.nodes[id];
891 currentDir.push_back(id);
892 joint_nodes.push_back(id);
893
894 for (int childIndex : node.children) {
895 const tinygltf::Node& childNode = model.nodes[childIndex];
896 traverseNode(model, childIndex, joint_nodes, dir, currentDir);
897 }
898
899 std::reverse(currentDir.begin(), currentDir.end());
900 dir[id] = currentDir;
901 }
902
903
904
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
913 )
914 {
915
916 for (size_t k = 0; k < all_Joints.size(); k++)
917 {
918 joint jId = all_Joints[k];
919 std::vector<int>& children = model.nodes[jId].children; //std::vector<int> children ;
920
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
925
926 joint_child.push_back(children);
927
928 Mat4f tempT = Mat4f::identityMatrix();
929 Mat4f tempR = Mat4f::identityMatrix();
930 Mat4f tempS = Mat4f::identityMatrix();
931
932 if (!rotation.empty())
933 joint_rotation[jId] = (Quat<float>(rotation[0], rotation[1], rotation[2], rotation[3]));
934 else
935 joint_rotation[jId] = (Quat<float>(0, 0, 0, 0));
936
937 if (!scale.empty())
938 joint_scale[jId] = (Vec3f(scale[0], scale[1], scale[2]));
939 else
940 joint_scale[jId] = (Vec3f(1.0f, 1.0f, 1.0f));
941
942 if (!translation.empty())
943 joint_translation[jId] = (Vec3f(translation[0], translation[1], translation[2]));
944 else
945 joint_translation[jId] = (Vec3f(0.0f, 0.0f, 0.0f));
946
947 if (!matrix.empty())
948 {
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]));
953
954 }
955 else
956 {
957 //Translation Matrix
958
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);
961 else
962 tempT = Mat4f::identityMatrix();
963
964
965
966 if (!rotation.empty())
967 tempR = Quat<float>(rotation[0], rotation[1], rotation[2], rotation[3]).toMatrix4x4();
968 else
969 tempR = Mat4f::identityMatrix();
970
971
972 if (!scale.empty())
973 tempS = Mat4f(scale[0], 0, 0, 0, 0, scale[1], 0, 0, 0, 0, scale[2], 0, 0, 0, 0, 1);
974 else
975 tempS = Mat4f::identityMatrix();
976
977 joint_matrix[jId] = (tempT * tempR * tempS);// if jointmatrix not found, build it
978
979 }
980
981 }
982 }
983
984 std::vector<int> getJointDirByJointIndex(int Index, std::map<joint, std::vector<int>> jointId_joint_Dir)
985 {
986 std::vector<int> jointDir;
987 std::map<int, std::vector<int>>::const_iterator iter;
988
989 //get skeletal chain
990 iter = jointId_joint_Dir.find(Index);
991 if (iter == jointId_joint_Dir.end())
992 {
993 std::cout << "Error: not found JointIndex \n";
994 return jointDir;
995 }
996
997 jointDir = iter->second;
998 return jointDir;
999 }
1000
1001
1002
1003
1004
1005
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
1015
1016 )
1017 {
1018
1019 std::map<joint, Mat4f> tempJointMatrix = joint_matrix;
1020 std::vector<Mat4f> temp;
1021
1022 temp.resize(maxJointId + 1);
1023
1024 for (size_t i = 0; i < maxJointId + 1; i++)
1025 {
1026 temp.push_back(Mat4f::identityMatrix());
1027 }
1028
1029
1030
1031 for (size_t i = 0; i < all_Joints.size(); i++)
1032 {
1033 joint jointId = all_Joints[i];
1034
1035 const std::vector<int>& jD = getJointDirByJointIndex(jointId,jointId_joint_Dir);
1036
1037 Mat4f tempMatrix = Mat4f::identityMatrix();
1038
1039
1040 for (int k = 0; k < jD.size(); k++)
1041 {
1042 joint select = jD[k];
1043
1044 Vec3f tempVT = Vec3f(0, 0, 0);
1045 Vec3f tempVS = Vec3f(1, 1, 1);
1046 Quat<float> tempQR = Quat<float>(Mat3f::identityMatrix());
1047
1048 if (model.nodes[select].matrix.empty())
1049 {
1050 tempQR = joint_rotation[select];
1051
1052 tempVT = joint_translation[select];
1053
1054 tempVS = joint_scale[select];
1055
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();
1059 //
1060
1061 tempJointMatrix[select] = mT * mS * mR;
1062 }
1063
1064 tempMatrix *= tempJointMatrix[select].inverse();
1065
1066 }
1067
1068 joint_inverseBindMatrix[jointId] = (tempMatrix);
1069
1070
1071
1072 temp[jointId] = tempMatrix;
1073
1074 }
1075
1076 // this->stateJointInverseBindMatrix()->assign(temp); //!!!
1077
1078 };
1079
1080
1081 void updateJoint_Mesh_Camera_Dir(
1082 tinygltf::Model& model,
1083 int& jointNum,
1084 int& meshNum,
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,
1091 int& maxJointId
1092 )
1093 {
1094 for (auto nId : all_Nodes)
1095 {
1096 if (model.nodes[nId].mesh == -1 && model.nodes[nId].camera == -1)
1097 {
1098 all_Joints.push_back(nId);
1099 jointId_joint_Dir[nId] = nodeId_Dir[nId];
1100 }
1101 if (model.nodes[nId].mesh == 1)
1102 {
1103 meshId_Dir[nId] = nodeId_Dir[nId];
1104 }
1105
1106 }
1107
1108 jointNum = all_Joints.size();
1109 meshNum = all_Meshs.size();
1110
1111
1112 if (all_Joints.size())
1113 maxJointId = *std::max_element(all_Joints.begin(), all_Joints.end());
1114 else
1115 maxJointId = -1;
1116 }
1117
1118
1119 void getMeshMatrix(
1120 tinygltf::Model& model,
1121 const std::vector<int>& all_MeshNodeIDs,
1122 int& maxMeshId,
1123 CArray<Mat4f>& mesh_Matrix
1124 )
1125 {
1126 maxMeshId = *std::max_element(all_MeshNodeIDs.begin(), all_MeshNodeIDs.end());
1127
1128 mesh_Matrix.resize(maxMeshId + 1);
1129
1130 Mat4f tempT;
1131 Mat4f tempR;
1132 Mat4f tempS;
1133
1134 for (size_t k = 0; k < all_MeshNodeIDs.size(); k++)
1135 {
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
1140
1141 if (!matrix.empty())
1142 {
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]));
1147 }
1148
1149 else
1150 {
1151 //Translation Matrix
1152
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);
1155 else
1156 tempT = Mat4f::identityMatrix();
1157
1158
1159 if (!rotation.empty())
1160 tempR = Quat<float>(rotation[0], rotation[1], rotation[2], rotation[3]).toMatrix4x4();
1161 else
1162 tempR = Mat4f::identityMatrix();
1163
1164
1165 if (!scale.empty())
1166 tempS = Mat4f(scale[0], 0, 0, 0, 0, scale[1], 0, 0, 0, 0, scale[2], 0, 0, 0, 0, 1);
1167 else
1168 tempS = Mat4f::identityMatrix();
1169
1170 mesh_Matrix[all_MeshNodeIDs[k]] = (tempT * tempR * tempS);// if jointmatrix not found, build it
1171 }
1172 }
1173
1174 }
1175
1176
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
1187 )
1188 {
1189 using namespace tinygltf;
1190 //input output
1191 for (size_t i = 0; i < model.nodes.size(); i++)
1192 {
1193 joint_output[i] = Vec3i(-1, -1, -1); //
1194 joint_input[i] = Vec3f(NULL_TIME, NULL_TIME, NULL_TIME);
1195 }
1196
1197 //Reset loading animation ;
1198 for (size_t i = 0; i < model.animations.size(); i++)
1199 {
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;
1203
1204 for (size_t j = 0; j < channels.size(); j++) //channels
1205 {
1206 //get sampler info
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"]
1210
1211 //get
1212 int& input = samplers[samplerId].input; //real time
1213 int& output = samplers[samplerId].output; //transform bufferid
1214 std::string& interpolation = samplers[samplerId].interpolation;
1215
1216 //struct AnimationSampler {
1217 // int input; // Time
1218 // int output; // Data
1219 // std::string interpolation; // "LINEAR", "STEP","CUBICSPLINE" or user defined // string. default "LINEAR"
1220 //}
1221
1222 {
1223
1224 if (target_path == "translation")
1225 {
1226 joint_output[joint_nodeId][0] = output;
1227 joint_input[joint_nodeId][0] = input;
1228 }
1229 else if (target_path == "scale")
1230 {
1231 joint_output[joint_nodeId][1] = output;
1232 joint_input[joint_nodeId][0] = input;
1233 }
1234 else if (target_path == "rotation")
1235 {
1236 joint_output[joint_nodeId][2] = output;
1237 joint_input[joint_nodeId][0] = input;
1238 }
1239 }
1240
1241 //Reset
1242 {
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;
1247 //
1248 std::vector<Real> frame_T_Time;
1249 std::vector<Real> frame_R_Time;
1250 std::vector<Real> frame_S_Time;
1251
1252 if (target_path == "translation")
1253 {
1254 getVec3fByIndex(model, output, frame_T_anim);
1255 joint_T_f_anim[joint_nodeId] = frame_T_anim;
1256
1257 getRealByIndex(model, input, frame_T_Time);
1258 joint_T_Time[joint_nodeId] = frame_T_Time;
1259 }
1260 else if (target_path == "scale")
1261 {
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;
1266 }
1267 else if (target_path == "rotation")
1268 {
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;
1273 }
1274 }
1275 }
1276 }
1277 }
1278
1279
1280
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,
1287
1288 DArray<Vec4f> bind_joints_0,
1289 DArray<Vec4f> bind_joints_1,
1290 DArray<Vec4f> weights_0,
1291 DArray<Vec4f> weights_1,
1292
1293 Mat4f transform,
1294 bool isNormal,
1295
1296 Vec2u range
1297 )
1298 {
1299 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
1300 if (pId >= worldPosition.size()) return;
1301
1302 if (pId<range[0] || pId>range[1])
1303 return;
1304
1305 Vec4f result = Vec4f(0, 0, 0, float(!isNormal));
1306
1307 int skinInfoVertexId = pId - range[0];
1308
1309 Coord offest;
1310
1311 bool j0 = bind_joints_0.size();
1312 bool j1 = bind_joints_1.size();
1313
1314 if (j0)
1315 {
1316 for (unsigned int i = 0; i < 4; i++)
1317 {
1318 int jointId = int(bind_joints_0[skinInfoVertexId][i]);
1319 Real weight = weights_0[skinInfoVertexId][i];
1320
1321 offest = intialPosition[pId];
1322 Vec4f v_bone_space = joint_inverseBindMatrix[jointId] * Vec4f(offest[0], offest[1], offest[2], float(!isNormal));//
1323
1324 result += (transform * WorldMatrix[jointId] * v_bone_space) * weight;
1325 }
1326 }
1327 if (j1)
1328 {
1329 for (unsigned int i = 0; i < 4; i++)
1330 {
1331 int jointId = int(bind_joints_1[skinInfoVertexId][i]);
1332 Real weight = weights_1[skinInfoVertexId][i];
1333
1334 offest = intialPosition[pId];
1335 Vec4f v_bone_space = joint_inverseBindMatrix[jointId] * Vec4f(offest[0], offest[1], offest[2], float(!isNormal));//
1336
1337 result += (WorldMatrix[jointId] * v_bone_space) * weight;
1338 }
1339 }
1340
1341 //result = transform * result;
1342
1343 if (j0 | j1)
1344 {
1345 worldPosition[pId][0] = result[0];
1346 worldPosition[pId][1] = result[1];
1347 worldPosition[pId][2] = result[2];
1348 }
1349
1350 if (isNormal)
1351 worldPosition[pId] = worldPosition[pId].normalize();
1352
1353 }
1354
1355 template< typename Vec3f, typename Vec4f, typename Mat4f, typename Vec2u>
1356 void skinAnimation(
1357 DArray<Vec3f>& intialPosition,
1358 DArray<Vec3f>& worldPosition,
1359 DArray<Mat4f>& joint_inverseBindMatrix,
1360 DArray<Mat4f>& WorldMatrix,
1361
1362 DArray<Vec4f>& bind_joints_0,
1363 DArray<Vec4f>& bind_joints_1,
1364 DArray<Vec4f>& weights_0,
1365 DArray<Vec4f>& weights_1,
1366
1367 Mat4f transform,
1368 bool isNormal,
1369
1370 Vec2u range
1371 )
1372 {
1373
1374 cuExecute(intialPosition.size(),
1375 PointsAnimation,
1376 intialPosition,
1377 worldPosition,
1378 joint_inverseBindMatrix,
1379 WorldMatrix,
1380
1381 bind_joints_0,
1382 bind_joints_1,
1383 weights_0,
1384 weights_1,
1385 transform,
1386 isNormal,
1387 range
1388 );
1389
1390 }
1391 template void skinAnimation<Vec3f, Vec4f, Mat4f, Vec2u>(DArray<Vec3f>& intialPosition,
1392 DArray<Vec3f>& worldPosition,
1393 DArray<Mat4f>& joint_inverseBindMatrix,
1394 DArray<Mat4f>& WorldMatrix,
1395
1396 DArray<Vec4f>& bind_joints_0,
1397 DArray<Vec4f>& bind_joints_1,
1398 DArray<Vec4f>& weights_0,
1399 DArray<Vec4f>& weights_1,
1400
1401 Mat4f transform,
1402 bool isNormal,
1403
1404 Vec2u range
1405 );
1406
1407 template<typename Triangle>
1408 __global__ void updateVertexId_Shape(
1409 DArray<Triangle> triangle,
1410 DArray<uint> ID_shapeId,
1411 int shapeId
1412 )
1413 {
1414 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
1415 if (pId >= triangle.size()) return;
1416
1417 ID_shapeId[triangle[pId][0]] = shapeId;
1418 ID_shapeId[triangle[pId][1]] = shapeId;
1419 ID_shapeId[triangle[pId][2]] = shapeId;
1420
1421 }
1422 template< typename Triangle>
1423 void updateVertexIdShape(
1424 DArray<Triangle>& triangle,
1425 DArray<uint>& ID_shapeId,
1426 int& shapeId,
1427 int size
1428 )
1429 {
1430 cuExecute(size,
1431 updateVertexId_Shape,
1432 triangle,
1433 ID_shapeId,
1434 shapeId
1435 );
1436 }
1437
1438 template void updateVertexIdShape<TopologyModule::Triangle>(DArray<TopologyModule::Triangle>& triangle,
1439 DArray<uint>& ID_shapeId,
1440 int& shapeId,
1441 int size
1442 );
1443
1444
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
1454 )
1455 {
1456 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
1457 if (pId >= intialPosition.size()) return;
1458
1459 int shape = vertexId_shape[pId];
1460
1461 int MeshId = shapeId_MeshId[shape];
1462
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);
1465 if (pId == 1)
1466 {
1467 auto iP = intialPosition[pId];
1468 }
1469
1470 tempV = WorldMatrix[MeshId] * tempV;
1471 tempN = WorldMatrix[MeshId] * tempN;
1472
1473 worldPosition[pId] = Vec3f(tempV[0], tempV[1], tempV[2]);
1474 Normal[pId] = Vec3f(tempN[0], tempN[1], tempN[2]);
1475 if (pId == 1)
1476 {
1477 auto iP = worldPosition[pId];
1478 }
1479 }
1480
1481
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
1491 )
1492 {
1493 cuExecute(intialPosition.size(),
1494 ShapeTransform,
1495 intialPosition,
1496 worldPosition,
1497 intialNormal,
1498 Normal,
1499 WorldMatrix,
1500 vertexId_shape,
1501 shapeId_MeshId
1502 );
1503 }
1504
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
1512 );
1513
1514 template<typename Vec3f>
1515 __global__ void C_SetupPoints(
1516 DArray<Vec3f> newPos,
1517 DArray<Vec3f> pos,
1518 DArray<int> radix
1519 )
1520 {
1521 uint tId = threadIdx.x + blockDim.x * blockIdx.x;
1522 if (tId >= pos.size()) return;
1523
1524 if (tId < pos.size() - 1 && radix[tId] != radix[tId + 1])
1525 {
1526 newPos[radix[tId]] = pos[tId];
1527 }
1528 else if (tId == pos.size() - 1 && pos.size() > 2)
1529 {
1530 if (radix[tId] != radix[tId - 1])
1531 newPos[radix[tId]] = pos[tId];
1532 }
1533
1534 }
1535
1536 template<typename Vec3f>
1537 void setupPoints(
1538 DArray<Vec3f>& newPos,
1539 DArray<Vec3f>& pos,
1540 DArray<int>& radix
1541 )
1542 {
1543 cuExecute(pos.size(),
1544 C_SetupPoints,
1545 newPos,
1546 pos,
1547 radix
1548 );
1549 }
1550
1551 template void setupPoints<Vec3f>(DArray<Vec3f>& newPos,
1552 DArray<Vec3f>& pos,
1553 DArray<int>& radix
1554 );
1555
1556 template<typename uint>
1557 __global__ void C_Shape_PointCounter(
1558 DArray<int> counter,
1559 DArray<uint> point_ShapeIds,
1560 uint target
1561 )
1562 {
1563 uint tId = threadIdx.x + blockDim.x * blockIdx.x;
1564 if (tId >= point_ShapeIds.size()) return;
1565
1566 counter[tId] = (point_ShapeIds[tId] == target) ? 1 : 0;
1567 }
1568
1569 template<typename uint>
1570 void Shape_PointCounter(
1571 DArray<int>& counter,
1572 DArray<uint>& point_ShapeIds,
1573 uint& target)
1574 {
1575 cuExecute(point_ShapeIds.size(),
1576 C_Shape_PointCounter,
1577 counter,
1578 point_ShapeIds,
1579 target
1580 );
1581 }
1582
1583 template void Shape_PointCounter <uint>(DArray<int>& counter,
1584 DArray<uint>& point_ShapeIds,
1585 uint& target
1586 );
1587
1588 template< typename Vec3f, typename uint>
1589 __global__ void ShapeToCenter(
1590 DArray<Vec3f> iniPos,
1591 DArray<Vec3f> finalPos,
1592 DArray<uint> shapeId,
1593 DArray<Vec3f> t
1594 )
1595 {
1596 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
1597 if (pId >= iniPos.size()) return;
1598
1599 finalPos[pId] = iniPos[pId] - t[shapeId[pId]];
1600 Vec4f P = Vec4f(finalPos[pId][0], finalPos[pId][1], finalPos[pId][2], 1);
1601
1602 finalPos[pId] = Vec3f(P[0], P[1], P[2]);
1603
1604 }
1605
1606 template< typename Vec3f, typename uint>
1607 void shapeToCenter(
1608 DArray<Vec3f>& iniPos,
1609 DArray<Vec3f>& finalPos,
1610 DArray<uint>& shapeId,
1611 DArray<Vec3f>& t
1612 )
1613 {
1614 cuExecute(finalPos.size(),
1615 ShapeToCenter,
1616 iniPos,
1617 finalPos,
1618 shapeId,
1619 t
1620 );
1621 }
1622
1623 template void shapeToCenter <Vec3f,uint>(DArray<Vec3f>& iniPos,
1624 DArray<Vec3f>& finalPos,
1625 DArray<uint>& shapeId,
1626 DArray<Vec3f>& t
1627 );
1628
1629
1630}