123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891 |
- #include "stdafx.h"
- #include "BabylonMesh.h"
- #include <map>
- #include <vector>
- #include <iostream>
- #include <sstream>
- #include "NodeHelpers.h"
- #include "GlobalSettings.h"
- struct BabylonVertex {
- babylon_vector3 position;
- babylon_vector3 normal;
- babylon_vector2 uv;
- babylon_vector2 uv2;
- babylon_vector2 uv3;
- babylon_vector2 uv4;
- babylon_vector2 uv5;
- babylon_vector2 uv6;
- babylon_color color;
- std::uint32_t boneIndices[4];
- float boneWeights[4];
- BabylonVertex() {
- boneIndices[0] = 0;
- boneIndices[1] = 0;
- boneIndices[2] = 0;
- boneIndices[3] = 0;
- boneWeights[0] = 0;
- boneWeights[1] = 0;
- boneWeights[2] = 0;
- boneWeights[3] = 0;
- }
- };
- struct triangle {
- std::uint32_t indices[3];
- };
- inline bool operator <(const triangle& lhs, const triangle& rhs) {
- if (lhs.indices[0] < rhs.indices[0]) {
- return true;
- }
- else if (rhs.indices[0] < lhs.indices[0]) {
- return false;
- }
- if (lhs.indices[1] < rhs.indices[1]) {
- return true;
- }
- else if (rhs.indices[1] < lhs.indices[1]) {
- return false;
- }
- return lhs.indices[2] < rhs.indices[2];
- }
- inline bool operator <(const BabylonVertex& lhs, const BabylonVertex& rhs) {
- if (lhs.position < rhs.position) {
- return true;
- }
- else if (rhs.position < lhs.position) {
- return false;
- }
- if (lhs.normal < rhs.normal) {
- return true;
- }
- else if (rhs.normal < lhs.normal) {
- return false;
- }
- if (lhs.uv < rhs.uv) {
- return true;
- }
- else if (rhs.uv < lhs.uv) {
- return false;
- }
- if (lhs.uv2 < rhs.uv2) {
- return true;
- }
- else if (rhs.uv2 < lhs.uv2) {
- return false;
- }
- if (lhs.uv3 < rhs.uv3) {
- return true;
- }
- else if (rhs.uv3 < lhs.uv3) {
- return false;
- }
- if (lhs.uv4 < rhs.uv4) {
- return true;
- }
- else if (rhs.uv4 < lhs.uv4) {
- return false;
- }
- if (lhs.uv5 < rhs.uv5) {
- return true;
- }
- else if (rhs.uv5 < lhs.uv5) {
- return false;
- }
- if (lhs.uv6 < rhs.uv6) {
- return true;
- }
- else if (rhs.uv6 < lhs.uv6) {
- return false;
- }
- if (lhs.color < rhs.color) {
- return true;
- }
- else if (rhs.color < lhs.color) {
- return false;
- }
- if (lhs.boneIndices[0] < rhs.boneIndices[0]) {
- return true;
- }
- else if (rhs.boneIndices[0] < lhs.boneIndices[0]) {
- return false;
- }
- if (lhs.boneIndices[1] < rhs.boneIndices[1]) {
- return true;
- }
- else if (rhs.boneIndices[1] < lhs.boneIndices[1]) {
- return false;
- }
- if (lhs.boneIndices[2] < rhs.boneIndices[2]) {
- return true;
- }
- else if (rhs.boneIndices[2] < lhs.boneIndices[2]) {
- return false;
- }
- if (lhs.boneIndices[3] < rhs.boneIndices[3]) {
- return true;
- }
- else if (rhs.boneIndices[3] < lhs.boneIndices[3]) {
- return false;
- }
- if (lhs.boneWeights[0] < rhs.boneWeights[0]) {
- return true;
- }
- else if (rhs.boneWeights[0] < lhs.boneWeights[0]) {
- return false;
- }
- if (lhs.boneWeights[1] < rhs.boneWeights[1]) {
- return true;
- }
- else if (rhs.boneWeights[1] < lhs.boneWeights[1]) {
- return false;
- }
- if (lhs.boneWeights[2] < rhs.boneWeights[2]) {
- return true;
- }
- else if (rhs.boneWeights[2] < lhs.boneWeights[2]) {
- return false;
- }
- if (lhs.boneWeights[3] < rhs.boneWeights[3]) {
- return true;
- }
- else if (rhs.boneWeights[3] < lhs.boneWeights[3]) {
- return false;
- }
- return false;
- }
- struct SubmeshData {
- std::map<BabylonVertex, std::uint32_t> knownVertices;
- std::set<triangle> knownTriangles;
- std::vector<BabylonVertex> vertices;
- std::vector<std::uint32_t> indices;
- };
- web::json::value convertToJson(const std::vector<babylon_vector3>& v) {
- auto result = web::json::value::array();
- for (auto ix = 0u;ix < v.size();++ix) {
- result[ix * 3] = web::json::value::number(v[ix].x);
- result[ix * 3 + 1] = web::json::value::number(v[ix].y);
- result[ix * 3 + 2] = web::json::value::number(v[ix].z);
- }
- return result;
- }
- web::json::value convertToJson(const std::vector<babylon_vector2>& v) {
- auto result = web::json::value::array();
- for (auto ix = 0u;ix < v.size();++ix) {
- result[ix * 2] = web::json::value::number(v[ix].x);
- result[ix * 2 + 1] = web::json::value::number(v[ix].y);
- }
- return result;
- }
- web::json::value convertToJson(const std::vector<babylon_color>& v) {
- auto result = web::json::value::array();
- for (auto ix = 0u;ix < v.size();++ix) {
- result[ix * 4] = web::json::value::number(v[ix].r);
- result[ix * 4 + 1] = web::json::value::number(v[ix].g);
- result[ix * 4 + 2] = web::json::value::number(v[ix].b);
- result[ix * 4 + 3] = web::json::value::number(v[ix].a);
- }
- return result;
- }
- web::json::value convertToJson(const std::vector<babylon_vector4>& v) {
- auto result = web::json::value::array();
- for (auto ix = 0u; ix < v.size(); ++ix) {
- result[ix * 4] = web::json::value::number(v[ix].x);
- result[ix * 4 + 1] = web::json::value::number(v[ix].y);
- result[ix * 4 + 2] = web::json::value::number(v[ix].z);
- result[ix * 4 + 3] = web::json::value::number(v[ix].w);
- }
- return result;
- }
- web::json::value convertToJson(const std::vector<std::uint32_t>& v){
- auto result = web::json::value::array();
- for (auto ix = 0u; ix < v.size() ; ++ix) {
- result[ix ] = web::json::value::number(v[ix ]);
- }
- return result;
- }
- web::json::value convertToJson(const std::vector<std::uint32_t>& v, bool changeVertexOrder) {
- if (changeVertexOrder) {
- auto result = web::json::value::array();
- for (auto ix = 0u;ix < v.size() / 3;++ix) {
- result[ix * 3] = web::json::value::number(v[ix * 3]);
- result[ix * 3 + 1] = web::json::value::number(v[ix * 3 + 2]);
- result[ix * 3 + 2] = web::json::value::number(v[ix * 3 + 1]);
- }
- return result;
- }
- else {
- auto result = web::json::value::array();
- for (auto ix = 0u;ix < v.size() / 3;++ix) {
- result[ix * 3] = web::json::value::number(v[ix * 3]);
- result[ix * 3 + 1] = web::json::value::number(v[ix * 3 + 1]);
- result[ix * 3 + 2] = web::json::value::number(v[ix * 3 + 2]);
- }
- return result;
- }
- }
- web::json::value convertToJson(const std::vector<BabylonSubmesh>& v) {
- auto result = web::json::value::array();
- for (auto ix = 0u;ix < v.size();++ix) {
- auto jsubmesh = web::json::value::object();
- jsubmesh[L"materialIndex"] = web::json::value::number(v[ix].materialIndex);
- jsubmesh[L"verticesStart"] = web::json::value::number(v[ix].verticesStart);
- jsubmesh[L"verticesCount"] = web::json::value::number(v[ix].verticesCount);
- jsubmesh[L"indexStart"] = web::json::value::number(v[ix].indexStart);
- jsubmesh[L"indexCount"] = web::json::value::number(v[ix].indexCount);
- result[result.size()] = jsubmesh;
- }
- return result;
- }
- web::json::value BabylonSubmesh::toJson(){
- auto jobj = web::json::value::object();
- jobj[L"materialIndex"] = web::json::value::number(materialIndex);
- jobj[L"verticesStart"] = web::json::value::number(verticesStart);
- jobj[L"verticesCount"] = web::json::value::number(verticesCount);
- jobj[L"indexStart"] = web::json::value::number(indexStart);
- jobj[L"indexCount"] = web::json::value::number(indexCount);
- return jobj;
- }
- web::json::value BabylonMesh::toJson()
- {
- auto jobj = BabylonAbstractMesh::toJson();
- jobj[L"id"] = web::json::value::string(_id);
- jobj[L"name"] = web::json::value::string(_id);
- if (_parentId.size() > 0)
- jobj[L"parentId"] = web::json::value::string(_parentId);
- if (_materialId.size() > 0)
- jobj[L"materialId"] = web::json::value::string(_materialId);
- jobj[L"isEnabled"] = web::json::value::boolean(_isEnabled);
- jobj[L"isVisible"] = web::json::value::boolean(_isVisible);
- jobj[L"pickable"] = web::json::value::boolean(_pickable);
- jobj[L"hasVertexAlpha"] = web::json::value::boolean(_hasVertexAlpha);
- jobj[L"checkCollision"] = web::json::value::boolean(_checkCollision);
- jobj[L"receiveShadows"] = web::json::value::boolean(_receiveShadows);
- jobj[L"infiniteDistance"] = web::json::value::boolean(_infiniteDistance);
- jobj[L"billboardMode"] = web::json::value::number(_billboardMode);
- jobj[L"visibility"] = web::json::value::number(_visibility);
- jobj[L"skeletonId"] = web::json::value::number(_skeletonId);
- auto submeshesArray = web::json::value::array();
- for (auto ix = 0u; ix < submeshes().size(); ++ix){
- submeshesArray[ix] = submeshes()[ix].toJson();
- }
- jobj[L"subMeshes"] = submeshesArray;
- jobj[L"showBoundingBox"] = web::json::value::boolean(_showBoundingBox);
- jobj[L"showSubMeshesBoundingBox"] = web::json::value::boolean(_showSubMeshesBoundingBox);
- jobj[L"applyFog"] = web::json::value::boolean(_applyFog);
- jobj[L"alphaIndex"] = web::json::value::number(_alphaIndex);
- if (_positions.size() > 0)
- jobj[L"positions"] = convertToJson(_positions);
- if (_normals.size() > 0)
- jobj[L"normals"] = convertToJson(_normals);
- if (_uvs.size() > 0)
- jobj[L"uvs"] = convertToJson(_uvs);
- if (_uvs2.size() > 0)
- jobj[L"uvs2"] = convertToJson(_uvs2);
- if (_uvs3.size() > 0)
- jobj[L"uvs3"] = convertToJson(_uvs3);
- if (_uvs4.size() > 0)
- jobj[L"uvs4"] = convertToJson(_uvs4);
- if (_uvs5.size() > 0)
- jobj[L"uvs5"] = convertToJson(_uvs5);
- if (_uvs6.size() > 0)
- jobj[L"uvs6"] = convertToJson(_uvs6);
- if (_colors.size() > 0)
- jobj[L"colors"] = convertToJson(_colors);
- if (_indices.size() > 0)
- jobj[L"indices"] = convertToJson(_indices, false);
- if (_boneIndices.size() > 0){
- jobj[L"matricesIndices"] = convertToJson(_boneIndices);
- }
- if (_boneWeights.size() > 0){
- jobj[L"matricesWeights"] = convertToJson(_boneWeights);
- }
- if (animations.size() == 0 && !associatedSkeleton){
- jobj[L"autoAnimate"] = web::json::value::boolean(false);
- jobj[L"autoAnimateLoop"] = web::json::value::boolean(false);
- jobj[L"autoAnimateFrom"] = web::json::value::number(0);
- jobj[L"autoAnimateTo"] = web::json::value::number(0);
- }
- else if (animations.size()>0){
- jobj[L"autoAnimate"] = web::json::value::boolean(animations[0]->autoAnimate);
- jobj[L"autoAnimateLoop"] = web::json::value::boolean(animations[0]->autoAnimateLoop);
- jobj[L"autoAnimateFrom"] = web::json::value::number(animations[0]->autoAnimateFrom);
- jobj[L"autoAnimateTo"] = web::json::value::number(animations[0]->autoAnimateTo);
- }
-
- else{
- jobj[L"autoAnimate"] = web::json::value::boolean(associatedSkeleton->bones[0].animation->autoAnimate);
- jobj[L"autoAnimateLoop"] = web::json::value::boolean(associatedSkeleton->bones[0].animation->autoAnimateLoop);
- jobj[L"autoAnimateFrom"] = web::json::value::number(associatedSkeleton->bones[0].animation->autoAnimateFrom);
- jobj[L"autoAnimateTo"] = web::json::value::number(associatedSkeleton->bones[0].animation->autoAnimateTo);
- }
- auto janimations = web::json::value::array();
- for (const auto& anim : animations){
- janimations[janimations.size()] = anim->toJson();
- }
- jobj[L"animations"] = janimations;
- FbxMatrix identity;
- identity.SetIdentity();
- if (pivotMatrix != identity){
- auto jpivot = web::json::value::array();
- for (auto x = 0; x < 4; ++x){
- for (auto y = 0; y < 4; ++y){
- jpivot[x * 4 + y] = web::json::value::number( pivotMatrix[x][y]);
- }
- }
- jobj[L"pivotMatrix"] = jpivot;
- }
- auto jinstances = web::json::value::array();
- for (auto& instance : _instances) {
- jinstances[jinstances.size()] = instance.toJson();
- }
- jobj[L"instances"] = jinstances;
- return jobj;
- }
- BabylonMesh::BabylonMesh() :
- _isEnabled(true),
- _isVisible(true),
- _billboardMode(0),
- _visibility(1),
- _skeletonId(-1),
- _pickable(true)
- {
- pivotMatrix.SetIdentity();
- }
- BabylonMesh::BabylonMesh(BabylonNode* node) :
- BabylonAbstractMesh(node),
- _isEnabled(true),
- _isVisible(true),
- _billboardMode(0),
- _visibility(1),
- _skeletonId(-1),
- _pickable(true),
- _hasVertexAlpha(false),
- _checkCollision(false),
- _receiveShadows(false),
- _infiniteDistance(false),
- _autoAnimate(false),
- _autoAnimateFrom(0),
- _autoAnimateTo(0),
- _autoAnimateLoop(false),
- _showBoundingBox(false),
- _showSubMeshesBoundingBox(false),
- _applyFog(false),
- _alphaIndex(0)
- {
- pivotMatrix.SetIdentity();
- auto fbxNode = node->fbxNode();
-
- std::string ansiName = fbxNode->GetName();
- name(std::wstring(ansiName.begin(), ansiName.end()));
- id(getNodeId(fbxNode));
- auto parent = fbxNode->GetParent();
- if (parent) {
- parentId(getNodeId(parent));
- }
- pivotMatrix = ConvertToBabylonCoordinateSystem( GetGeometryTransformation(fbxNode));
- auto mesh = fbxNode->GetMesh();
- auto animStack = fbxNode->GetScene()->GetCurrentAnimationStack();
- if (animStack) {
- FbxString animStackName = animStack->GetName();
- //FbxTakeInfo* takeInfo = node->GetScene()->GetTakeInfo(animStackName);
- auto animTimeMode = GlobalSettings::Current().AnimationsTimeMode;
- auto animFrameRate = GlobalSettings::Current().AnimationsFrameRate();
- auto startFrame = animStack->GetLocalTimeSpan().GetStart().GetFrameCount(animTimeMode);
- auto endFrame = animStack->GetLocalTimeSpan().GetStop().GetFrameCount(animTimeMode);
- auto animLengthInFrame = endFrame - startFrame + 1;
- _visibility = static_cast<float>(node->fbxNode()->Visibility.Get());
- auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"position", L"position", true, 0, static_cast<int>(animLengthInFrame), true);
- auto rotAnim = std::make_shared<BabylonAnimation<babylon_vector4>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"rotationQuaternion", L"rotationQuaternion", true, 0, static_cast<int>(animLengthInFrame), true);
- auto scaleAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"scaling", L"scaling", true, 0, static_cast<int>(animLengthInFrame), true);
- auto visibilityAnim = std::make_shared<BabylonAnimation<float>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"visibility", L"visibility", true, 0, static_cast<int>(animLengthInFrame), true);
- _isVisible = fbxNode->Show.Get();
- auto rotCurveNode = fbxNode->LclRotation.GetCurveNode();
- auto translateCurveNode = fbxNode->LclTranslation.GetCurveNode();
- auto scalingCurveNode = fbxNode->LclScaling.GetCurveNode();
- auto visibilityCurveNode = fbxNode->Visibility.GetCurveNode();
- if (rotCurveNode || translateCurveNode || scalingCurveNode) {
- for (auto ix = 0; ix < animLengthInFrame; ix++) {
- FbxTime currTime;
- currTime.SetFrame(startFrame + ix, animTimeMode);
- babylon_animation_key<babylon_vector3> poskey;
- babylon_animation_key<babylon_vector4> rotkey;
- babylon_animation_key<babylon_vector3> scalekey;
- poskey.frame = ix;
- rotkey.frame = ix;
- scalekey.frame = ix;
- auto currTransform = node->GetLocal(currTime);
- poskey.values = currTransform.translation();
- rotkey.values = currTransform.rotationQuaternion();
- scalekey.values = currTransform.scaling();
- posAnim->appendKey(poskey);
- rotAnim->appendKey(rotkey);
- scaleAnim->appendKey(scalekey);
- }
- }
- if (visibilityCurveNode) {
- for (auto ix = 0; ix < animLengthInFrame; ix++) {
- FbxTime currTime;
- currTime.SetFrame(startFrame + ix, animTimeMode);
- babylon_animation_key<float> visibilityKey;
- visibilityKey.frame = ix;
- visibilityKey.values = static_cast<float>(node->fbxNode()->Visibility.EvaluateValue(currTime));
- visibilityAnim->appendKey(visibilityKey);
- }
- }
- if (!posAnim->isConstant()){
- animations.push_back(posAnim);
- }
- if (!rotAnim->isConstant()){
- animations.push_back(rotAnim);
- }
- if (!scaleAnim->isConstant()){
- animations.push_back(scaleAnim);
- }
- if (!visibilityAnim->isConstant()) {
- animations.push_back(visibilityAnim);
- }
- }
- if (!mesh) {
- return;
- }
- if (mesh->GetPolygonCount() == 0){
- return;
- }
- _receiveShadows = mesh->ReceiveShadow.Get();
- FbxGeometryConverter conv(mesh->GetFbxManager());
- conv.ComputePolygonSmoothingFromEdgeSmoothing(mesh);
- if (!mesh->IsTriangleMesh()) {
- mesh = (FbxMesh*) conv.Triangulate(mesh, true);
- }
- mesh->RemoveBadPolygons();
- mesh->GenerateNormals();
- FbxStringList uvSetNameList;
- mesh->GetUVSetNames(uvSetNameList);
- std::vector<std::string> uniqueUVSets;
- int uvCount = uvSetNameList.GetCount();
- for (int i = 0; i < uvCount; ++i) {
- std::string value = uvSetNameList.GetStringAt(i);
- if (std::find(uniqueUVSets.begin(), uniqueUVSets.end(), value) == uniqueUVSets.end()) {
- uniqueUVSets.push_back(value);
- }
- }
- uvsets = uniqueUVSets;
- bool hasUv = uniqueUVSets.size() > 0;
- bool hasUv2 = uniqueUVSets.size() > 1;
- bool hasUv3 = uniqueUVSets.size() > 2;
- bool hasUv4 = uniqueUVSets.size() > 3;
- bool hasUv5 = uniqueUVSets.size() > 4;
- bool hasUv6 = uniqueUVSets.size() > 5;
- std::string uvSetName;
- std::string uv2SetName;
- std::string uv3SetName;
- std::string uv4SetName;
- std::string uv5SetName;
- std::string uv6SetName;
- if (hasUv) {
- uvSetName = uniqueUVSets[0];
- }
- if (hasUv2) {
- uv2SetName = uniqueUVSets[1];
- }
- if (hasUv3) {
- uv3SetName = uniqueUVSets[2];
- }
- if (hasUv4) {
- uv4SetName = uniqueUVSets[3];
- }
- if (hasUv5) {
- uv5SetName = uniqueUVSets[4];
- }
- if (hasUv6) {
- uv6SetName = uniqueUVSets[5];
- }
- auto colors = mesh->GetElementVertexColor();
- FbxLayerElement::EMappingMode colorMappingMode;
- FbxLayerElement::EReferenceMode colorReferenceMode;
- if (colors) {
- colorMappingMode = colors->GetMappingMode();
- colorReferenceMode = colors->GetReferenceMode();
- }
- auto normals = mesh->GetElementNormal();
- FbxGeometryElementUV* uvs = nullptr;
- FbxGeometryElementUV* uvs2 = nullptr;
- FbxGeometryElementUV* uvs3 = nullptr;
- FbxGeometryElementUV* uvs4 = nullptr;
- FbxGeometryElementUV* uvs5 = nullptr;
- FbxGeometryElementUV* uvs6 = nullptr;
- FbxLayerElement::EMappingMode uvsMappingMode;
- FbxLayerElement::EReferenceMode uvsReferenceMode;
- FbxLayerElement::EMappingMode uvs2MappingMode;
- FbxLayerElement::EReferenceMode uvs2ReferenceMode;
- FbxLayerElement::EMappingMode uvs3MappingMode;
- FbxLayerElement::EReferenceMode uvs3ReferenceMode;
- FbxLayerElement::EMappingMode uvs4MappingMode;
- FbxLayerElement::EReferenceMode uvs4ReferenceMode;
- FbxLayerElement::EMappingMode uvs5MappingMode;
- FbxLayerElement::EReferenceMode uvs5ReferenceMode;
- FbxLayerElement::EMappingMode uvs6MappingMode;
- FbxLayerElement::EReferenceMode uvs6ReferenceMode;
- if (hasUv) {
- uvs = mesh->GetElementUV(uvSetName.c_str());
- uvsMappingMode = uvs->GetMappingMode();
- uvsReferenceMode = uvs->GetReferenceMode();
- }
- if (hasUv2) {
- uvs2 = mesh->GetElementUV(uv2SetName.c_str());
- uvs2MappingMode = uvs2->GetMappingMode();
- uvs2ReferenceMode = uvs2->GetReferenceMode();
- }
- if (hasUv3) {
- uvs3 = mesh->GetElementUV(uv3SetName.c_str());
- uvs3MappingMode = uvs3->GetMappingMode();
- uvs3ReferenceMode = uvs3->GetReferenceMode();
- }
- if (hasUv4) {
- uvs4 = mesh->GetElementUV(uv4SetName.c_str());
- uvs4MappingMode = uvs4->GetMappingMode();
- uvs4ReferenceMode = uvs4->GetReferenceMode();
- }
- if (hasUv5) {
- uvs5 = mesh->GetElementUV(uv5SetName.c_str());
- uvs5MappingMode = uvs5->GetMappingMode();
- uvs5ReferenceMode = uvs5->GetReferenceMode();
- }
- if (hasUv6) {
- uvs6 = mesh->GetElementUV(uv6SetName.c_str());
- uvs6MappingMode = uvs6->GetMappingMode();
- uvs6ReferenceMode = uvs6->GetReferenceMode();
- }
- auto normalMappingMode = normals->GetMappingMode();
- auto normalReferenceMode = normals->GetReferenceMode();
- std::vector<SubmeshData> submeshes;
- auto materialCount = node->fbxNode()->GetMaterialCount();
- if (materialCount == 0) {
- materialCount = 1;
- }
- submeshes.resize(materialCount);
- auto baseLayer = mesh->GetLayer(0);
- auto materials = baseLayer->GetMaterials();
- FbxLayerElement::EMappingMode materialMappingMode = materials ?
- materials->GetMappingMode() : FbxLayerElement::eByPolygon;
- // extract deformers
- SkinInfo skinInfo(fbxNode);
- if (skinInfo.hasSkin()){
- associatedSkeleton = std::make_shared<BabylonSkeleton>();
- skinInfo.buildBabylonSkeleton(*associatedSkeleton);
- }
- auto triangleCount = mesh->GetPolygonCount();
- for (int triangleIndex = 0; triangleIndex < triangleCount; ++triangleIndex) {
- int materialIndex = 0;
- if (materialCount > 0 && materials) {
- switch (materialMappingMode) {
- case FbxLayerElement::eAllSame:
- materialIndex = materials->GetIndexArray().GetAt(0);
- break;
- case FbxLayerElement::eByPolygon:
- materialIndex = materials->GetIndexArray().GetAt(triangleIndex);
- }
- if (materialIndex < 0 || materialIndex >= materialCount) {
- materialIndex = 0;
- }
- }
- auto& submesh = submeshes[materialIndex];
- triangle t;
- for (int cornerIndex = 0; cornerIndex < 3; ++cornerIndex) {
- auto controlPointIndex = mesh->GetPolygonVertex(triangleIndex, cornerIndex);
- auto vertexIndex = triangleIndex * 3 + cornerIndex;
- auto position = mesh->GetControlPoints()[controlPointIndex];
- position[2] = -position[2];
- BabylonVertex v;
- v.position = position;
- if (normals) {
- int normalMapIndex = (normalMappingMode == FbxLayerElement::eByControlPoint) ?
- controlPointIndex : vertexIndex;
- int normalValueIndex = (normalReferenceMode == FbxLayerElement::eDirect) ?
- normalMapIndex : normals->GetIndexArray().GetAt(normalMapIndex);
- v.normal = normals->GetDirectArray().GetAt(normalValueIndex);
- v.normal.z = -v.normal.z;
- }
- if (colors) {
- int mappingIndex = (colorMappingMode == FbxLayerElement::eByControlPoint) ?
- controlPointIndex : vertexIndex;
- int valueIndex = (colorReferenceMode == FbxLayerElement::eDirect) ?
- mappingIndex : colors->GetIndexArray().GetAt(mappingIndex);
- v.color = colors->GetDirectArray().GetAt(valueIndex);
- }
- if (uvs) {
- int mappingIndex = (uvsMappingMode == FbxLayerElement::eByControlPoint) ?
- controlPointIndex : vertexIndex;
- int valueIndex = (uvsReferenceMode == FbxLayerElement::eDirect) ?
- mappingIndex : uvs->GetIndexArray().GetAt(mappingIndex);
- v.uv = uvs->GetDirectArray().GetAt(valueIndex);
- //v.uv.y = 1 - v.uv.y;
- }
- if (uvs2) {
- int mappingIndex = (uvs2MappingMode == FbxLayerElement::eByControlPoint) ?
- controlPointIndex : vertexIndex;
- int valueIndex = (uvs2ReferenceMode == FbxLayerElement::eDirect) ?
- mappingIndex : uvs2->GetIndexArray().GetAt(mappingIndex);
- v.uv2 = uvs2->GetDirectArray().GetAt(valueIndex);
- }
- if (uvs3) {
- int mappingIndex = (uvs3MappingMode == FbxLayerElement::eByControlPoint) ?
- controlPointIndex : vertexIndex;
- int valueIndex = (uvs3ReferenceMode == FbxLayerElement::eDirect) ?
- mappingIndex : uvs3->GetIndexArray().GetAt(mappingIndex);
- v.uv3 = uvs3->GetDirectArray().GetAt(valueIndex);
- }
- if (uvs4) {
- int mappingIndex = (uvs4MappingMode == FbxLayerElement::eByControlPoint) ?
- controlPointIndex : vertexIndex;
- int valueIndex = (uvs4ReferenceMode == FbxLayerElement::eDirect) ?
- mappingIndex : uvs4->GetIndexArray().GetAt(mappingIndex);
- v.uv4 = uvs4->GetDirectArray().GetAt(valueIndex);
- }
- if (uvs5) {
- int mappingIndex = (uvs5MappingMode == FbxLayerElement::eByControlPoint) ?
- controlPointIndex : vertexIndex;
- int valueIndex = (uvs5ReferenceMode == FbxLayerElement::eDirect) ?
- mappingIndex : uvs5->GetIndexArray().GetAt(mappingIndex);
- v.uv5 = uvs5->GetDirectArray().GetAt(valueIndex);
- }
- if (uvs6) {
- int mappingIndex = (uvs6MappingMode == FbxLayerElement::eByControlPoint) ?
- controlPointIndex : vertexIndex;
- int valueIndex = (uvs6ReferenceMode == FbxLayerElement::eDirect) ?
- mappingIndex : uvs6->GetIndexArray().GetAt(mappingIndex);
- v.uv6 = uvs6->GetDirectArray().GetAt(valueIndex);
- }
- if (skinInfo.hasSkin()){
- auto& skinData = skinInfo.controlPointBoneIndicesAndWeights(controlPointIndex);
- for (std::size_t boneix = 0; boneix < skinData.size()&&boneix< (size_t)4; ++boneix){
- v.boneIndices[boneix] = skinData[boneix].index;
- v.boneWeights[boneix] = static_cast<float>(skinData[boneix].weight);
- }
- for (auto boneix = skinData.size(); boneix < 4; ++boneix){
- v.boneIndices[boneix] = skinInfo.bonesCount();
- v.boneWeights[boneix] = 0;
- }
- }
- auto foundVertex = submesh.knownVertices.find(v);
- if (foundVertex != submesh.knownVertices.end()) {
- //submesh.indices.push_back(foundVertex->second);
- t.indices[cornerIndex] = foundVertex->second;
- }
- else {
- auto index = static_cast<int>(submesh.vertices.size());
- submesh.vertices.push_back(v);
- //submesh.indices.push_back(index);
- submesh.knownVertices[v] = index;
- t.indices[cornerIndex] = index;
- }
- }
- if (submesh.knownTriangles.insert(t).second) {
- submesh.indices.push_back(t.indices[0]);
- submesh.indices.push_back(t.indices[1]);
- submesh.indices.push_back(t.indices[2]);
- }
- else {
- std::cout << "duplicate triangle found (and eliminated) in " << fbxNode->GetName() << std::endl;
- }
- }
- std::uint32_t vertexOffset = 0;
- for (auto matIndex = 0u; matIndex < submeshes.size(); ++matIndex) {
- auto& submesh = submeshes[matIndex];
- BabylonSubmesh babsubmesh;
- babsubmesh.indexCount = static_cast<int>(submesh.indices.size());
- babsubmesh.indexStart = static_cast<int>(_indices.size());
- babsubmesh.materialIndex = matIndex;
- babsubmesh.verticesCount = static_cast<int>(submesh.vertices.size());
- babsubmesh.verticesStart = static_cast<int>(_positions.size());
- for (auto& v : submesh.vertices) {
- _positions.push_back(v.position);
- if (normals) {
- _normals.push_back(v.normal);
- }
- if (colors) {
- _colors.push_back(v.color);
- }
- if (uvs) {
- _uvs.push_back(v.uv);
- }
- if (uvs2) {
- _uvs2.push_back(v.uv2);
- }
- if (uvs3) {
- _uvs3.push_back(v.uv3);
- }
- if (uvs4) {
- _uvs4.push_back(v.uv4);
- }
- if (uvs5) {
- _uvs5.push_back(v.uv5);
- }
- if (uvs6) {
- _uvs6.push_back(v.uv6);
- }
- if (skinInfo.hasSkin()){
- float weight0 = v.boneWeights[0];
- float weight1 = v.boneWeights[1];
- float weight2 = v.boneWeights[2];
- int bone0 = v.boneIndices[0];
- int bone1 = v.boneIndices[1];
- int bone2 = v.boneIndices[2];
- int bone3 = v.boneIndices[3];
-
- _boneWeights.push_back(babylon_vector4( weight0, weight1, weight2, 1.0f - weight0 - weight1 - weight2));
- _boneIndices.push_back((bone3 << 24) | (bone2 << 16) | (bone1 << 8) | bone0);
- }
- }
- for (auto i : submesh.indices) {
- _indices.push_back(i + vertexOffset);
- }
- vertexOffset = static_cast<int>(_positions.size());
- _submeshes.push_back(babsubmesh);
- }
- }
- BabylonMesh::BabylonMesh(BabylonMesh && moved) :
- BabylonAbstractMesh(moved),
- _id(std::move(moved._id)),
- _parentId(std::move(moved._parentId)),
- _materialId(std::move(moved._materialId)),
- _isEnabled(std::move(moved._isEnabled)),
- _isVisible(std::move(moved._isVisible)),
- _pickable(std::move(moved._pickable)),
- _positions(std::move(moved._positions)),
- _normals(std::move(moved._normals)),
- _uvs(std::move(moved._uvs)),
- _uvs2(std::move(moved._uvs2)),
- _uvs3(std::move(moved._uvs3)),
- _uvs4(std::move(moved._uvs4)),
- _uvs5(std::move(moved._uvs5)),
- _uvs6(std::move(moved._uvs6)),
- _colors(std::move(moved._colors)),
- _hasVertexAlpha(std::move(moved._hasVertexAlpha)),
- _boneIndices(std::move(moved._boneIndices)),
- _boneWeights(std::move(moved._boneWeights)),
- _indices(std::move(moved._indices)),
- _checkCollision(std::move(moved._checkCollision)),
- _receiveShadows(std::move(moved._receiveShadows)),
- _infiniteDistance(std::move(moved._infiniteDistance)),
- _billboardMode(std::move(moved._billboardMode)),
- _visibility(std::move(moved._visibility)),
- _submeshes(std::move(moved._submeshes)),
- _instances(std::move(moved._instances)),
- _skeletonId(std::move(moved._skeletonId)),
- _autoAnimate(std::move(moved._autoAnimate)),
- _autoAnimateFrom(std::move(moved._autoAnimateFrom)),
- _autoAnimateTo(std::move(moved._autoAnimateTo)),
- _autoAnimateLoop(std::move(moved._autoAnimateLoop)),
- _showBoundingBox(std::move(moved._showBoundingBox)),
- _showSubMeshesBoundingBox(std::move(moved._showSubMeshesBoundingBox)),
- _applyFog(std::move(moved._applyFog)),
- _alphaIndex(std::move(moved._alphaIndex)),
- uvsets(std::move(moved.uvsets)),
- associatedSkeleton(std::move(moved.associatedSkeleton)),
- animations(std::move(moved.animations)),
- pivotMatrix(std::move(moved.pivotMatrix))
- {
- }
- void BabylonMesh::addInstance(BabylonNode * node)
- {
- _instances.emplace_back(node);
- }
- BabylonMesh::~BabylonMesh()
- {
- }
|