Преглед изворни кода

Merge pull request #618 from simonferquel/master

Fbx Exporter : Various animation fixes
David Catuhe пре 10 година
родитељ
комит
30623f05f1
25 измењених фајлова са 617 додато и 443 уклоњено
  1. 4 3
      Exporters/FBX/BabylonFbxNative/BabylonAbstractMesh.cpp
  2. 10 9
      Exporters/FBX/BabylonFbxNative/BabylonAnimation.h
  3. 37 30
      Exporters/FBX/BabylonFbxNative/BabylonCamera.cpp
  4. 1 0
      Exporters/FBX/BabylonFbxNative/BabylonFbxNative.vcxproj
  5. 3 0
      Exporters/FBX/BabylonFbxNative/BabylonFbxNative.vcxproj.filters
  6. 100 39
      Exporters/FBX/BabylonFbxNative/BabylonLight.cpp
  7. 42 2
      Exporters/FBX/BabylonFbxNative/BabylonLight.h
  8. 32 15
      Exporters/FBX/BabylonFbxNative/BabylonMaterial.cpp
  9. 3 2
      Exporters/FBX/BabylonFbxNative/BabylonMaterial.h
  10. 70 43
      Exporters/FBX/BabylonFbxNative/BabylonMesh.cpp
  11. 3 3
      Exporters/FBX/BabylonFbxNative/BabylonMesh.h
  12. 0 26
      Exporters/FBX/BabylonFbxNative/BabylonNode.cpp
  13. 5 22
      Exporters/FBX/BabylonFbxNative/BabylonNode.h
  14. 6 2
      Exporters/FBX/BabylonFbxNative/BabylonScene.cpp
  15. 2 0
      Exporters/FBX/BabylonFbxNative/BabylonScene.h
  16. 2 2
      Exporters/FBX/BabylonFbxNative/BabylonSkeleton.h
  17. 5 4
      Exporters/FBX/BabylonFbxNative/BabylonVertex.h
  18. 6 6
      Exporters/FBX/BabylonFbxNative/FbxMeshLoader.h
  19. 33 0
      Exporters/FBX/BabylonFbxNative/MatrixDecomposition.h
  20. 170 172
      Exporters/FBX/BabylonFbxNative/NodeHelpers.h
  21. 11 11
      Exporters/FBX/BabylonFbxNative/SkinInfo.cpp
  22. 5 5
      Exporters/FBX/BabylonFbxNative/SkinInfo.h
  23. 6 6
      Exporters/FBX/BabylonFbxNative/babylon_boundingbox.cpp
  24. 55 39
      Exporters/FBX/FbxExporter/FbxExporter.cpp
  25. 6 2
      Exporters/FBX/FbxRerouteSkeleton/FbxRerouteSkeleton.cpp

+ 4 - 3
Exporters/FBX/BabylonFbxNative/BabylonAbstractMesh.cpp

@@ -8,10 +8,11 @@ BabylonAbstractMesh::BabylonAbstractMesh()
 }
 
 BabylonAbstractMesh::BabylonAbstractMesh(BabylonNode* node)
-	: _position(node->localTranslate()),
-	_rotationQuaternion(node->localRotationQuat()),
-	_scaling(node->localScale())
 {
+	auto localTransform = node->GetLocal();
+	_position = localTransform.translation();
+	_rotationQuaternion = localTransform.rotationQuaternion();
+	_scaling = localTransform.scaling();
 	auto n = node->name();
 	_name = std::wstring(n.begin(), n.end());
 }

+ 10 - 9
Exporters/FBX/BabylonFbxNative/BabylonAnimation.h

@@ -37,6 +37,11 @@ public:
 	bool autoAnimateLoop;
 	BabylonAnimationBase(int loopBehavior, int fps, const std::wstring& name, const std::wstring& animatedProperty, bool autoAnimate, int autoAnimateFrom, int autoAnimateTo, bool autoAnimateLoop);
 	virtual ~BabylonAnimationBase(){}
+
+
+	virtual bool isConstant() = 0;
+
+	virtual web::json::value toJson() const = 0;
 };
 
 template<typename T>
@@ -84,11 +89,11 @@ struct bab_anim_traits < babylon_vector4 >
 };
 
 template<>
-struct bab_anim_traits < FbxAMatrix >
+struct bab_anim_traits < FbxMatrix >
 {
 	static const int dataType = BabylonAnimationBase::dataType_Matrix;
 
-	static web::json::value jsonify(const FbxAMatrix& value){
+	static web::json::value jsonify(const FbxMatrix& value){
 		auto jmat = web::json::value::array();
 		for (auto x = 0; x < 4; ++x){
 			for (auto y = 0; y < 4; ++y){
@@ -120,7 +125,7 @@ inline bool isNear<float>(const float& lhs, const float& rhs){
 }
 
 template <>
-inline bool isNear<FbxAMatrix>(const FbxAMatrix& lhs, const FbxAMatrix& rhs){
+inline bool isNear<FbxMatrix>(const FbxMatrix& lhs, const FbxMatrix& rhs){
 	return lhs == rhs;
 }
 
@@ -143,10 +148,6 @@ inline T lerp(const T& start, const T& end, float factor){
 	return start + (end - start)*factor;
 }
 
-template<>
-inline FbxAMatrix lerp(const FbxAMatrix& start, const FbxAMatrix& end, float factor){
-	return start.Slerp(end, factor);
-}
 template<typename T>
 bool isLinearInterpolation(const babylon_animation_key<T>& key0, const babylon_animation_key<T>& key1, const babylon_animation_key<T>& key2){
 	auto testVal = lerp(key0.values, key2.values, static_cast<float>(key1.frame - key0.frame) / static_cast<float>(key2.frame - key0.frame));
@@ -190,7 +191,7 @@ public:
 		}
 	}
 
-	bool isConstant(){
+	virtual bool isConstant() override{
 		if (keys.size() < 2){
 			return true;
 		}
@@ -201,7 +202,7 @@ public:
 		return isNear(keys[0].values, keys[1].values);
 	}
 
-	web::json::value toJson() const{
+	virtual web::json::value toJson() const override {
 		auto jobj = web::json::value::object();
 
 		/*

+ 37 - 30
Exporters/FBX/BabylonFbxNative/BabylonCamera.cpp

@@ -72,7 +72,7 @@ BabylonCamera buildCameraFromBoundingBox(const babylon_boundingbox& box){
 	result.target = box.getCenter();
 	result.position = babylon_vector3(result.target.x, result.target.y, result.target.z - 2 * std::max(box.getWidth(), std::max(box.getHeight(), box.getDepth())));
 	result.fov = 0.8576f;
-	result.minZ = -0.01*result.position.z;
+	result.minZ = -0.01f*result.position.z;
 	result.maxZ = -5 * result.position.z;
 	result.speed = (-result.position.z - result.target.z) / 10;
 	result.inertia = 0.9f;
@@ -104,12 +104,15 @@ BabylonCamera::BabylonCamera(BabylonNode& babnode)
 	else {
 		target = camera->InterestPosition.Get();
 	}
-	position = babnode.localTranslate();
-	rotationQuaternion = babnode.localRotationQuat();
+	auto localTransformAtStart = babnode.GetLocal();
+	position = localTransformAtStart.translation();
+	rotationQuaternion = localTransformAtStart.rotationQuaternion();
 	
-	fov = camera->FieldOfViewY * Euler2Rad;
-	minZ = camera->FrontPlaneDistance.Get();
-	maxZ = camera->BackPlaneDistance.Get();
+	fov = static_cast<float>(camera->FieldOfViewY * Euler2Rad);
+	
+	
+	minZ = static_cast<float>(camera->NearPlane.Get());
+	maxZ = static_cast<float>(camera->FarPlane.Get());
 
 	auto hasAnimStack = node->GetScene()->GetSrcObjectCount<FbxAnimStack>() > 0;
 	if (!hasAnimStack){
@@ -124,30 +127,34 @@ BabylonCamera::BabylonCamera(BabylonNode& babnode)
 	auto endFrame = takeInfo->mLocalTimeSpan.GetStop().GetFrameCount(animTimeMode);
 	auto animLengthInFrame = endFrame - startFrame + 1;
 
-	auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, animFrameRate, L"position", L"position", true, 0, animLengthInFrame, true);
-	auto rotAnim = std::make_shared<BabylonAnimation<babylon_vector4>>(BabylonAnimationBase::loopBehavior_Cycle, animFrameRate, L"rotation", L"rotation", true, 0, animLengthInFrame, true);
-	auto targetAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, animFrameRate, L"target", L"target", true, 0, animLengthInFrame, true);
-	
-	for (auto ix = 0ll; ix < animLengthInFrame; ix++){
-		FbxTime currTime;
-		currTime.SetFrame(startFrame + ix, animTimeMode);
-
-		babylon_animation_key<babylon_vector3> poskey;
-		babylon_animation_key<babylon_vector4> rotkey;
-		poskey.frame = ix;
-		rotkey.frame = ix;
-
-		poskey.values = babnode.localTranslate(currTime);
-		rotkey.values = babnode.localRotationQuat(currTime);
-		posAnim->appendKey(poskey);
-		rotAnim->appendKey(rotkey);
-
-		if (lockedTargetId.size() == 0){
-
-			babylon_animation_key<babylon_vector3> targetKey;
-			targetKey.frame = ix;
-			targetKey.values = camera->InterestPosition.EvaluateValue(currTime);
-			targetAnim->appendKey(targetKey);
+	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"rotation", L"rotation", true, 0, static_cast<int>(animLengthInFrame), true);
+	auto targetAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"target", L"target", true, 0, static_cast<int>(animLengthInFrame), true);
+	if (node->LclRotation.GetCurveNode() || node->LclScaling.GetCurveNode() || node->LclTranslation.GetCurveNode() || camera->InterestPosition.GetCurveNode()) {
+		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;
+			poskey.frame = ix;
+			rotkey.frame = ix;
+
+
+			auto transformAtT = babnode.GetLocal(currTime);
+
+			poskey.values = transformAtT.translation();
+			rotkey.values = transformAtT.rotationQuaternion();
+			posAnim->appendKey(poskey);
+			rotAnim->appendKey(rotkey);
+
+			if (lockedTargetId.size() == 0) {
+
+				babylon_animation_key<babylon_vector3> targetKey;
+				targetKey.frame = ix;
+				targetKey.values = camera->InterestPosition.EvaluateValue(currTime);
+				targetAnim->appendKey(targetKey);
+			}
 		}
 	}
 	if (!posAnim->isConstant()){

+ 1 - 0
Exporters/FBX/BabylonFbxNative/BabylonFbxNative.vcxproj

@@ -189,6 +189,7 @@
     <ClInclude Include="FbxSceneLoader.h" />
     <ClInclude Include="FbxVertexKey.h" />
     <ClInclude Include="GlobalSettings.h" />
+    <ClInclude Include="MatrixDecomposition.h" />
     <ClInclude Include="NodeHelpers.h" />
     <ClInclude Include="SkinInfo.h" />
     <ClInclude Include="stdafx.h" />

+ 3 - 0
Exporters/FBX/BabylonFbxNative/BabylonFbxNative.vcxproj.filters

@@ -84,6 +84,9 @@
     <ClInclude Include="GlobalSettings.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="MatrixDecomposition.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="stdafx.cpp">

+ 100 - 39
Exporters/FBX/BabylonFbxNative/BabylonLight.cpp

@@ -22,7 +22,7 @@ web::json::value BabylonLight::toJson() const
 	jobj[L"angle"] = web::json::value::number(angle);
 	writeVector3(jobj, L"groundColor", groundColor);
 
-	if (animations.size() == 0){
+	if (animations.size() == 0) {
 
 		jobj[L"autoAnimate"] = web::json::value::boolean(false);
 		jobj[L"autoAnimateLoop"] = web::json::value::boolean(false);
@@ -30,7 +30,7 @@ web::json::value BabylonLight::toJson() const
 		jobj[L"autoAnimateTo"] = web::json::value::number(0);
 
 	}
-	else{
+	else {
 
 		jobj[L"autoAnimate"] = web::json::value::boolean(animations[0]->autoAnimate);
 		jobj[L"autoAnimateLoop"] = web::json::value::boolean(animations[0]->autoAnimateLoop);
@@ -39,22 +39,35 @@ web::json::value BabylonLight::toJson() const
 	}
 
 	auto janimations = web::json::value::array();
-	for (const auto& anim : animations){
+	for (const auto& anim : animations) {
 		janimations[janimations.size()] = anim->toJson();
 	}
 	jobj[L"animations"] = janimations;
+
+	auto jarray = web::json::value::array();
+	for (auto& id : excludedMeshesIds) {
+		jarray[jarray.size()] = web::json::value::string(id);
+	}
+	jobj[L"excludedMeshesIds"] = jarray;
+
+	jarray = web::json::value::array();
+	for (auto& id : includedOnlyMeshesIds) {
+		jarray[jarray.size()] = web::json::value::string(id);
+	}
+	jobj[L"includedOnlyMeshesIds"] = jarray;
+
 	return jobj;
 }
 
 BabylonLight::BabylonLight() :
-diffuse(1, 1, 1),
-specular(1, 1, 1)
+	diffuse(1, 1, 1),
+	specular(1, 1, 1)
 {
 }
 
 BabylonLight::BabylonLight(BabylonNode & babnode) :
-diffuse(1, 1, 1),
-specular(1, 1, 1)
+	diffuse(1, 1, 1),
+	specular(1, 1, 1)
 {
 	auto node = babnode.fbxNode();
 	std::string ansiName = node->GetName();
@@ -64,7 +77,8 @@ specular(1, 1, 1)
 	if (parent) {
 		parentId = getNodeId(parent);
 	}
-	position = babnode.localTranslate();
+	auto localTransform = babnode.GetLocal();
+	position = localTransform.translation();
 	auto light = node->GetLight();
 	switch (light->LightType)
 	{
@@ -74,10 +88,11 @@ specular(1, 1, 1)
 	case FbxLight::eDirectional:
 		type = type_direct;
 		{
-			FbxDouble3 vDir(0, 1, 0);
+			FbxDouble3 vDir(0, -1, 0);
 			FbxAMatrix rotM;
 			rotM.SetIdentity();
-			rotM.SetQ(babnode.localTransform().GetQ());
+
+			rotM.SetQ(localTransform.fbxrot());
 			auto transDir = rotM.MultT(vDir);
 			direction = transDir;
 
@@ -86,14 +101,14 @@ specular(1, 1, 1)
 	case FbxLight::eSpot:
 		type = type_Spot;
 		{
-			FbxDouble3 vDir(0, 1, 0);
+			FbxDouble3 vDir(0, -1, 0);
 			FbxAMatrix rotM;
 			rotM.SetIdentity();
-			rotM.SetQ(babnode.localTransform().GetQ());
+			rotM.SetQ(localTransform.fbxrot());
 			auto transDir = rotM.MultT(vDir);
 			direction = transDir;
 			exponent = 1;
-			angle = light->OuterAngle*Euler2Rad;
+			angle = static_cast<float>(light->OuterAngle*Euler2Rad);
 
 		}
 		break;
@@ -101,14 +116,18 @@ specular(1, 1, 1)
 		break;
 	}
 	diffuse = light->Color.Get();
-	intensity = light->Intensity.Get() / 100.0;
+	intensity = static_cast<float>(light->Intensity.Get() / 100.0);
 	if (light->EnableFarAttenuation.Get()) {
-		range = light->FarAttenuationEnd.Get();
+		range = static_cast<float>(light->FarAttenuationEnd.Get());
 	}
 	auto hasAnimStack = node->GetScene()->GetSrcObjectCount<FbxAnimStack>() > 0;
-	if (!hasAnimStack){
+	if (!hasAnimStack) {
 		return;
 	}
+	castShadows = light->CastShadows.Get();
+	if (castShadows) {
+		shadowGenerator = std::make_shared<BabylonShadowGenerator>(node);
+	}
 	auto animStack = node->GetScene()->GetSrcObject<FbxAnimStack>(0);
 	FbxString animStackName = animStack->GetName();
 	FbxTakeInfo* takeInfo = node->GetScene()->GetTakeInfo(animStackName);
@@ -121,33 +140,35 @@ specular(1, 1, 1)
 	auto dirAnimName = getNodeId(node);
 	posAnimName.append(L"_position");
 	dirAnimName.append(L"_direction");
-	auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, animFrameRate, posAnimName, L"position", true, 0, animLengthInFrame, true);
-	auto dirAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, animFrameRate, dirAnimName, L"direction", true, 0, animLengthInFrame, true);
-	for (auto ix = 0ll; ix < animLengthInFrame; ix++){
-		babylon_animation_key<babylon_vector3> key;
-		key.frame = ix;
-		FbxTime currTime;
-		currTime.SetFrame(startFrame + ix, animTimeMode);
-		key.values = babnode.localTranslate(currTime);
-		posAnim->appendKey(key);
-
-		if (type == type_direct || type == type_Spot){
-			babylon_animation_key<babylon_vector3> dirkey;
-			dirkey.frame = ix;
-			auto transformAtTime = babnode.localTransform(currTime);
-			FbxDouble3 vDir(0, 1, 0);
-			FbxAMatrix rotM;
-			rotM.SetIdentity();
-			rotM.SetQ(transformAtTime.GetQ());
-			auto transDir = rotM.MultT(vDir);
-			dirkey.values = transDir;
-			dirAnim->appendKey(dirkey);
+	auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), posAnimName, L"position", true, 0, static_cast<int>(animLengthInFrame), true);
+	auto dirAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), dirAnimName, L"direction", true, 0, static_cast<int>(animLengthInFrame), true);
+	if (node->LclRotation.GetCurveNode() || node->LclTranslation.GetCurveNode()) {
+		for (auto ix = 0; ix < animLengthInFrame; ix++) {
+			babylon_animation_key<babylon_vector3> key;
+			key.frame = ix;
+			FbxTime currTime;
+			currTime.SetFrame(startFrame + ix, animTimeMode);
+			auto currTransform = babnode.GetLocal(currTime);
+			key.values = currTransform.translation();
+			posAnim->appendKey(key);
+
+			if (type == type_direct || type == type_Spot) {
+				babylon_animation_key<babylon_vector3> dirkey;
+				dirkey.frame = ix;
+				FbxDouble3 vDir(0, -1, 0);
+				FbxAMatrix rotM;
+				rotM.SetIdentity();
+				rotM.SetQ(currTransform.fbxrot());
+				auto transDir = rotM.MultT(vDir);
+				dirkey.values = transDir;
+				dirAnim->appendKey(dirkey);
+			}
 		}
 	}
-	if (!posAnim->isConstant()){
+	if (!posAnim->isConstant()) {
 		animations.push_back(posAnim);
 	}
-	if (!dirAnim->isConstant()){
+	if (!dirAnim->isConstant()) {
 		animations.push_back(dirAnim);
 	}
 }
@@ -156,3 +177,43 @@ specular(1, 1, 1)
 BabylonLight::~BabylonLight()
 {
 }
+
+BabylonShadowGenerator::BabylonShadowGenerator(FbxNode * lightNode)
+{
+	auto light = lightNode->GetLight();
+	lightId = getNodeId(lightNode);
+	mapSize = 2048;
+	bias = 0.00005f;
+	useBlurVarianceShadowMap = true;
+	blurScale = 2;
+	blurBoxOffset = 1;
+	useVarianceShadowMap = false;
+	usePoissonSampling = false;
+	auto nodeCount = lightNode->GetScene()->GetNodeCount();
+	for (auto ix = 0;ix < nodeCount;++ix) {
+		auto mnode = lightNode->GetScene()->GetNode(ix);
+		auto mesh = mnode->GetMesh();
+		if (mesh && mesh->CastShadow.Get()) {
+			renderList.push_back(getNodeId(mnode));
+		}
+	}
+
+}
+
+web::json::value BabylonShadowGenerator::toJson()
+{
+	auto jobj =web::json::value::object();
+	jobj[L"mapSize"] = web::json::value::number(mapSize);
+	jobj[L"lightId"] = web::json::value::string(lightId);
+	jobj[L"useVarianceShadowMap"] = web::json::value::boolean(useVarianceShadowMap);
+	jobj[L"usePoissonSampling"] = web::json::value::boolean(usePoissonSampling);
+	/*jobj[L"useBlurVarianceShadowMap"] = web::json::value::boolean(useBlurVarianceShadowMap);
+	jobj[L"blurScale"] = web::json::value::number(blurScale);
+	jobj[L"blurBoxOffset"] = web::json::value::number(blurBoxOffset);*/
+	auto jarr = web::json::value::array();
+	for (auto& id : renderList) {
+		jarr[jarr.size()] = web::json::value::string(id);
+	}
+	jobj[L"renderList"] = jarr;
+	return jobj;
+}

+ 42 - 2
Exporters/FBX/BabylonFbxNative/BabylonLight.h

@@ -4,7 +4,45 @@
 #include "BabylonNode.h"
 #include "BabylonAnimation.h"
 #include <memory>
+#include <string>
 #undef max
+
+class BabylonShadowGenerator
+{
+public:
+
+	int mapSize;
+
+		
+	float bias;
+
+		
+	std::wstring lightId;
+
+		
+	bool useVarianceShadowMap;
+
+		
+	bool usePoissonSampling;
+
+		
+	bool useBlurVarianceShadowMap;
+
+		
+	float blurScale;
+
+		
+	float blurBoxOffset;
+
+		
+	std::vector<std::wstring> renderList;
+
+	BabylonShadowGenerator(FbxNode* lightNode);
+	web::json::value toJson();
+
+};
+
+
 class BabylonLight
 {
 public:
@@ -53,10 +91,12 @@ public:
 		
 	babylon_vector3 groundColor;
 
-		
+	bool castShadows;
+	std::vector<std::wstring> includedOnlyMeshesIds;
+	std::vector<std::wstring> excludedMeshesIds;
 
 		
-	
+	std::shared_ptr<BabylonShadowGenerator> shadowGenerator;
 
 	web::json::value toJson() const;
 

+ 32 - 15
Exporters/FBX/BabylonFbxNative/BabylonMaterial.cpp

@@ -2,6 +2,7 @@
 #include "BabylonMaterial.h"
 #include <Windows.h>
 #include "NodeHelpers.h"
+#include "GlobalSettings.h"
 
 web::json::value BabylonMaterial::toJson() const
 {
@@ -61,10 +62,10 @@ alpha(1)
 }
 
 std::wstring utf8ToWstring(const std::string& src){
-	auto size = MultiByteToWideChar(CP_UTF8, 0, src.c_str(), src.size(), nullptr, 0);
+	auto size = MultiByteToWideChar(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), nullptr, 0);
 	std::wstring result;
 	result.resize(size, ' ');
-	MultiByteToWideChar(CP_UTF8, 0, src.c_str(), src.size(), &result[0], result.size());
+	MultiByteToWideChar(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), &result[0], size);
 	return result;
 }
 
@@ -133,7 +134,7 @@ alpha(1){
 		transcolor = transColorProp.Get<FbxDouble3>();
 		if (transfactor== 1.0){ // from Maya .fbx
 			if (transcolor[0] >= DBL_MIN) {
-				alpha = 1 - transcolor[0];
+				alpha = static_cast<float>(1 - transcolor[0]);
 			}
 			else {
 				alpha = 1;
@@ -141,7 +142,7 @@ alpha(1){
 		}
 		else { // from 3dsmax .fbx
 			if (transfactor>=DBL_MIN){
-				alpha = 1 - transfactor;
+				alpha = static_cast<float>(1 - transfactor);
 			}
 			else {
 				alpha = 1;
@@ -156,7 +157,7 @@ alpha(1){
 	GetMaterialProperty(mat, FbxSurfaceMaterial::sReflection, FbxSurfaceMaterial::sReflectionFactor, reflectionTex);
 	auto shininessProp = mat->FindProperty(FbxSurfaceMaterial::sShininess);
 	if (shininessProp.IsValid()){
-		specularPower = shininessProp.Get<FbxDouble>();
+		specularPower = static_cast<float>(shininessProp.Get<FbxDouble>())*12;
 	}
 
 	auto normalMapProp = mat->FindProperty(FbxSurfaceMaterial::sNormalMap);
@@ -250,6 +251,11 @@ web::json::value BabylonTexture::toJson(){
 	jobj[L"wrapV"] = web::json::value::boolean(wrapV);
 	jobj[L"coordinatesIndex"] = web::json::value::number(coordinatesIndex);
 	jobj[L"isRenderTarget"] = web::json::value::boolean(isRenderTarget);
+	auto janims = web::json::value::array();
+	for (auto& anim : animations) {
+		janims[janims.size()] = anim->toJson();
+	}
+	jobj[L"animations"] = janims;
 	return jobj;
 }
 BabylonTexture::BabylonTexture(FbxFileTexture* texture){
@@ -301,20 +307,31 @@ BabylonTexture::BabylonTexture(FbxFileTexture* texture){
 		break;
 	}
 
-	auto translation = texture->Translation.Get();
-	auto rot = texture->Rotation.Get();
-	auto scale  = texture->Scaling.Get();
-	uOffset = translation[0];
-	vOffset = translation[1];
-	uScale = scale[0];
-	vScale = scale[1];
-	uAng = rot[0] * Euler2Rad;
-	vAng = rot[1] * Euler2Rad;
-	wAng = rot[2] * Euler2Rad;
+	babylon_vector3 rot = texture->Rotation.Get();
+	babylon_vector3 scaling = texture->Scaling.Get();
+
+	babylon_vector2 trans((float)texture->GetTranslationU(), (float)texture->GetTranslationV());
+	
+	
+	uOffset = trans.x;
+	vOffset = trans.y;
+	uScale = scaling.x;
+	vScale = scaling.y;
+	std::string strFileName = texture->GetFileName();
+	auto lastDot = strFileName.find_last_of('.');
+	auto ext = strFileName.substr(lastDot);
+	if (_stricmp(ext.c_str(), ".dds") == 0) {
+		vScale *= -1;
+	}
+	uAng = static_cast<float>(rot.x * Euler2Rad);
+	vAng = static_cast<float>(rot.y * Euler2Rad);
+	wAng = static_cast<float>(rot.z * Euler2Rad);
 	auto uwrapMode = texture->GetWrapModeU();
 	auto vwrapMode = texture->GetWrapModeV();
 	wrapU = uwrapMode == FbxTexture::eRepeat;
 	wrapV = vwrapMode == FbxTexture::eRepeat;
+
+	uvset = texture->UVSet.Get();
 	
 	
 

+ 3 - 2
Exporters/FBX/BabylonFbxNative/BabylonMaterial.h

@@ -5,7 +5,7 @@
 #include "BabylonVertex.h"
 #include <vector>
 #include <fbxsdk.h>
-
+#include "BabylonAnimation.h"
 
 
 class BabylonTexture{
@@ -13,7 +13,7 @@ public:
 	
 	 std::wstring name;
 	 std::wstring fullPath;
-
+	 std::string uvset;
 		
 	 float level = 1.0f;
 
@@ -61,6 +61,7 @@ public:
 
 		
 	 bool isRenderTarget = false;
+	 std::vector<std::shared_ptr<BabylonAnimationBase>> animations;
 
 	 BabylonTexture(FbxFileTexture* texture);
 

+ 70 - 43
Exporters/FBX/BabylonFbxNative/BabylonMesh.cpp

@@ -343,7 +343,7 @@ web::json::value BabylonMesh::toJson()
 	if (_boneWeights.size() > 0){
 		jobj[L"matricesWeights"] = convertToJson(_boneWeights);
 	}
-	if (animations.size() == 0 && quatAnimations.size() == 0 && !associatedSkeleton){
+	if (animations.size() == 0 && !associatedSkeleton){
 
 		jobj[L"autoAnimate"] = web::json::value::boolean(false);
 		jobj[L"autoAnimateLoop"] = web::json::value::boolean(false);
@@ -358,12 +358,7 @@ web::json::value BabylonMesh::toJson()
 		jobj[L"autoAnimateFrom"] = web::json::value::number(animations[0]->autoAnimateFrom);
 		jobj[L"autoAnimateTo"] = web::json::value::number(animations[0]->autoAnimateTo);
 	}
-	else if(quatAnimations.size()>0){
-		jobj[L"autoAnimate"] = web::json::value::boolean(quatAnimations[0]->autoAnimate);
-		jobj[L"autoAnimateLoop"] = web::json::value::boolean(quatAnimations[0]->autoAnimateLoop);
-		jobj[L"autoAnimateFrom"] = web::json::value::number(quatAnimations[0]->autoAnimateFrom);
-		jobj[L"autoAnimateTo"] = web::json::value::number(quatAnimations[0]->autoAnimateTo);
-	}
+	
 	else{
 
 		jobj[L"autoAnimate"] = web::json::value::boolean(associatedSkeleton->bones[0].animation->autoAnimate);
@@ -375,11 +370,11 @@ web::json::value BabylonMesh::toJson()
 	auto janimations = web::json::value::array();
 	for (const auto& anim : animations){
 		janimations[janimations.size()] = anim->toJson();
-	}for (const auto& anim : quatAnimations){
-		janimations[janimations.size()] = anim->toJson();
 	}
 	jobj[L"animations"] = janimations;
-	if (!pivotMatrix.IsIdentity()){
+	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){
@@ -429,6 +424,7 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 
 	pivotMatrix.SetIdentity();
 	auto fbxNode = node->fbxNode();
+	
 	std::string ansiName = fbxNode->GetName();
 	name(std::wstring(ansiName.begin(), ansiName.end()));
 	id(getNodeId(fbxNode));
@@ -441,52 +437,82 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 	auto animStack = fbxNode->GetScene()->GetSrcObject<FbxAnimStack>(0);
 	FbxString animStackName = animStack->GetName();
 	FbxTakeInfo* takeInfo = fbxNode->GetScene()->GetTakeInfo(animStackName);
-
 	auto animTimeMode = GlobalSettings::Current().AnimationsTimeMode;
 	auto animFrameRate = GlobalSettings::Current().AnimationsFrameRate();
 	auto startFrame = takeInfo->mLocalTimeSpan.GetStart().GetFrameCount(animTimeMode);
 	auto endFrame = takeInfo->mLocalTimeSpan.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);
+	auto mesh = fbxNode->GetMesh();
+	_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);
+
 
-	auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, animFrameRate, L"position", L"position", true, 0, animLengthInFrame, true);
-	auto rotAnim = std::make_shared<BabylonAnimation<babylon_vector4>>(BabylonAnimationBase::loopBehavior_Cycle, animFrameRate, L"rotationQuaternion", L"rotationQuaternion", true, 0, animLengthInFrame, true);
-	auto scaleAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, animFrameRate, L"scale", L"scale", true, 0, animLengthInFrame, true);
-
-	for (auto ix = 0ll; 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;
-		poskey.values = node->localTranslate(currTime);
-		rotkey.values = node->localRotationQuat(currTime);
-		scalekey.values = node->localScale(currTime);
-		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()){
-		quatAnimations.push_back(rotAnim);
+		animations.push_back(rotAnim);
 	}
 	if (!scaleAnim->isConstant()){
 		animations.push_back(scaleAnim);
 	}
-	auto mesh = fbxNode->GetMesh();
+	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()) {
@@ -508,6 +534,7 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 			uniqueUVSets.push_back(value);
 		}
 	}
+	uvsets = uniqueUVSets;
 	bool hasUv = uniqueUVSets.size() > 0;
 	bool hasUv2 = uniqueUVSets.size() > 1;
 	bool hasUv3 = uniqueUVSets.size() > 2;
@@ -703,7 +730,7 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 				auto& skinData = skinInfo.controlPointBoneIndicesAndWeights(controlPointIndex);
 				for (auto boneix = 0; boneix < skinData.size()&&boneix<4; ++boneix){
 					v.boneIndices[boneix] = skinData[boneix].index;
-					v.boneWeights[boneix] = skinData[boneix].weight;
+					v.boneWeights[boneix] = static_cast<float>(skinData[boneix].weight);
 				}
 				for (auto boneix = skinData.size(); boneix < 4; ++boneix){
 
@@ -717,7 +744,7 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 				t.indices[cornerIndex] = foundVertex->second;
 			}
 			else {
-				auto index = submesh.vertices.size();
+				auto index = static_cast<int>(submesh.vertices.size());
 				submesh.vertices.push_back(v);
 				//submesh.indices.push_back(index);
 				submesh.knownVertices[v] = index;
@@ -739,11 +766,11 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 	for (auto matIndex = 0u; matIndex < submeshes.size(); ++matIndex) {
 		auto& submesh = submeshes[matIndex];
 		BabylonSubmesh babsubmesh;
-		babsubmesh.indexCount = submesh.indices.size();
-		babsubmesh.indexStart = _indices.size();
+		babsubmesh.indexCount = static_cast<int>(submesh.indices.size());
+		babsubmesh.indexStart = static_cast<int>(_indices.size());
 		babsubmesh.materialIndex = matIndex;
-		babsubmesh.verticesCount = submesh.vertices.size();
-		babsubmesh.verticesStart = _positions.size();
+		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) {
@@ -779,7 +806,7 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 				 int bone2 = v.boneIndices[2];
 				 int bone3 = v.boneIndices[3];
                
-				_boneWeights.push_back(babylon_vector4( weight0, weight1, weight2, 1.0 - weight0 - weight1 - weight2));
+				_boneWeights.push_back(babylon_vector4( weight0, weight1, weight2, 1.0f - weight0 - weight1 - weight2));
                 _boneIndices.push_back((bone3 << 24) | (bone2 << 16) | (bone1 << 8) | bone0);
 			}
 		}
@@ -787,7 +814,7 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 			_indices.push_back(i + vertexOffset);
 		}
 
-		vertexOffset = _positions.size();
+		vertexOffset = static_cast<int>(_positions.size());
 		_submeshes.push_back(babsubmesh);
 	}
 

+ 3 - 3
Exporters/FBX/BabylonFbxNative/BabylonMesh.h

@@ -56,6 +56,7 @@ private:
 	bool _applyFog;
 	int _alphaIndex;
 public:
+	std::vector<std::string> uvsets;
 	const std::wstring& id(){ return _id; }
 	const std::wstring& parentId(){ return _parentId; }
 	const std::wstring& materialId(){ return _materialId; }
@@ -113,9 +114,8 @@ public:
 
 	std::shared_ptr<BabylonSkeleton> associatedSkeleton;
 
-	std::vector<std::shared_ptr < BabylonAnimation<babylon_vector3>>> animations;
-	std::vector<std::shared_ptr < BabylonAnimation<babylon_vector4>>> quatAnimations;
-	FbxAMatrix pivotMatrix;
+	std::vector<std::shared_ptr < BabylonAnimationBase>> animations;
+	FbxMatrix pivotMatrix;
 
 	virtual web::json::value toJson() override;
 	BabylonMesh();

+ 0 - 26
Exporters/FBX/BabylonFbxNative/BabylonNode.cpp

@@ -1,12 +1,8 @@
-#include "BabylonNode.h"
-#include "BabylonNode.h"
 #include "stdafx.h"
 #include "BabylonNode.h"
 #include "NodeHelpers.h"
 
 BabylonNode::BabylonNode(FbxNode* fbxNode) : _node(fbxNode){
-	_localTransform = ConvertToBabylonCoordinateSystem(CalculateLocalTransform( fbxNode));
-	_globalTransform = ConvertToBabylonCoordinateSystem(CalculateLocalTransform(fbxNode));
 	auto childCount = fbxNode->GetChildCount();
 	for (int i = 0; i < childCount; ++i){
 		_children.emplace_back(fbxNode->GetChild(i));
@@ -65,25 +61,3 @@ bool BabylonNode::isEmptySkeletonOrEmptyMeshRecursive()
 	}
 	return true;
 }
-
-babylon_vector3 BabylonNode::localScale(FbxTime time){
-	auto transform = ConvertToBabylonCoordinateSystem(CalculateLocalTransform(_node,time));
-	return transform.GetS();
-
-}
-
-babylon_vector4 BabylonNode::localRotationQuat(){
-	auto ret = _localTransform.GetQ();
-	return babylon_vector4(ret[0], ret[1], ret[2], ret[3]);
-}
-babylon_vector4 BabylonNode::localRotationQuat(FbxTime time){
-
-	auto transform = ConvertToBabylonCoordinateSystem(CalculateLocalTransform(_node, time));
-	auto ret = transform.GetQ();
-	return babylon_vector4(ret[0], ret[1], ret[2], ret[3]);
-}
-babylon_vector3 BabylonNode::localTranslate(FbxTime time){
-	auto transform = ConvertToBabylonCoordinateSystem(CalculateLocalTransform(_node, time));
-	return transform.GetT();
-
-}

+ 5 - 22
Exporters/FBX/BabylonFbxNative/BabylonNode.h

@@ -4,6 +4,7 @@
 #include <cstdint>
 #include "NodeHelpers.h"
 #include "BabylonVertex.h"
+#include "MatrixDecomposition.h"
 enum class BabylonNodeType{
 	Camera,
 	Mesh,
@@ -15,8 +16,6 @@ class BabylonNode;
 class BabylonNode
 {
 private:
-	FbxAMatrix _localTransform;
-	FbxAMatrix _globalTransform;
 	FbxNode* _node;
 	std::vector<BabylonNode> _children;
 public:
@@ -59,27 +58,11 @@ public:
 		return true;
 	}
 
-	babylon_vector3 localScale(){
-		auto ret = _localTransform.GetS();
-		return ret;
+	MatrixDecomposition GetLocal() {
+		return MatrixDecomposition(ConvertToBabylonCoordinateSystem(_node->EvaluateLocalTransform()));
 	}
-	babylon_vector4 localRotationQuat();
-	babylon_vector3 localTranslate(){
-
-		auto ret = _localTransform.GetT();
-		return ret;
-	}
-
-
-
-	babylon_vector3 localScale(FbxTime time);
-	babylon_vector4 localRotationQuat(FbxTime time);
-	babylon_vector3 localTranslate(FbxTime time);
-
-	FbxAMatrix localTransform(FbxTime time){
-		return ConvertToBabylonCoordinateSystem(CalculateLocalTransform(_node, time));
+	MatrixDecomposition GetLocal(const FbxTime& time) {
+		return MatrixDecomposition(ConvertToBabylonCoordinateSystem(_node->EvaluateLocalTransform(time)));
 	}
 
-	const FbxAMatrix& localTransform() { return _localTransform; }
-	const FbxAMatrix& globalTransform() { return _globalTransform; }
 };

+ 6 - 2
Exporters/FBX/BabylonFbxNative/BabylonScene.cpp

@@ -8,7 +8,7 @@ web::json::value BabylonScene::toJson()
 	jobj[L"autoClear"] = web::json::value::boolean(_autoClear);
 	writeVector3(jobj, L"clearColor", _clearColor);
 	writeVector3(jobj, L"ambientColor", _ambientColor);
-	jobj[L"fogMode"] = web::json::value::boolean(_fogMode);
+	jobj[L"fogMode"] = web::json::value::number(_fogMode);
 	writeVector3(jobj, L"fogColor", _fogColor);
 	jobj[L"fogStart"] = web::json::value::number(_fogStart);
 	jobj[L"fogEnd"] = web::json::value::number(_fogEnd);
@@ -54,7 +54,11 @@ web::json::value BabylonScene::toJson()
 		jskeletons[jskeletons.size()] = skel->toJson();
 	}
 	jobj[L"skeletons"] = jskeletons;
-
+	auto jshadowGenerators = web::json::value::array();
+	for (auto& sg : _shadowGenerators) {
+		jshadowGenerators[jshadowGenerators.size()] = sg->toJson();
+	}
+	jobj[L"shadowGenerators"] = jshadowGenerators;
 	return jobj;
 }
 

+ 2 - 0
Exporters/FBX/BabylonFbxNative/BabylonScene.h

@@ -26,6 +26,7 @@ private:
 	std::vector<BabylonMaterial> _materials;
 	std::vector<BabylonMultiMaterial> _multiMaterials;
 	std::vector<BabylonLight> _lights;
+	std::vector<std::shared_ptr<BabylonShadowGenerator>> _shadowGenerators;
 	std::vector<std::shared_ptr<BabylonSkeleton>> _skeletons;
 	// particleSystems
 	// lensFlareSystems
@@ -52,6 +53,7 @@ public:
 	std::vector<BabylonMultiMaterial>& multiMaterials(){ return _multiMaterials; }
 
 	std::vector<BabylonLight>& lights() { return _lights; }
+	std::vector<std::shared_ptr<BabylonShadowGenerator>>& shadowGenerators() { return _shadowGenerators; }
 	std::vector<std::shared_ptr<BabylonSkeleton>>& skeletons() { return _skeletons; }
 	// particleSystems
 	// lensFlareSystems

+ 2 - 2
Exporters/FBX/BabylonFbxNative/BabylonSkeleton.h

@@ -11,8 +11,8 @@ public:
 	std::wstring name;
 	int index;
 	int parentBoneIndex = -1;
-	FbxAMatrix matrix;
-	std::shared_ptr<BabylonAnimation<FbxAMatrix>> animation;
+	FbxMatrix matrix;
+	std::shared_ptr<BabylonAnimation<FbxMatrix>> animation;
 	web::json::value toJson();
 
 	//public BabylonAnimation animation{ get; set; }

+ 5 - 4
Exporters/FBX/BabylonFbxNative/BabylonVertex.h

@@ -13,7 +13,8 @@ struct babylon_vector4{
 	float w;
 	babylon_vector4() :x(0), y(0), z(0), w(0){}
 	babylon_vector4(float x, float y, float z, float w) :x(x), y(y), z(z), w(w){}
-	babylon_vector4(const babylon_vector4& v) :x(v.x), y(v.y), z(v.z), w(v.w){}
+	babylon_vector4(const babylon_vector4& v) :x(v.x), y(v.y), z(v.z), w(v.w) {}
+	babylon_vector4(const FbxQuaternion& v) :x(static_cast<float>(v[0])), y(static_cast<float>(v[1])), z(static_cast<float>(v[2])), w(static_cast<float>(v[3])) {}
 };
 struct babylon_vector3{
 	float x;
@@ -82,9 +83,9 @@ struct babylon_vector2{
 	float x;
 	float y;
 	babylon_vector2() :x(0), y(0){}
-	babylon_vector2(float x, float y, float z) :x(x), y(y){}
+	babylon_vector2(float x, float y) :x(x), y(y){}
 	babylon_vector2(const babylon_vector2& v) :x(v.x), y(v.y){}
-	babylon_vector2(const FbxDouble2& v) :x(v[0]), y(v[1]){}
+	babylon_vector2(const FbxDouble2& v) :x(static_cast<float>(v[0])), y(static_cast<float>(v[1])){}
 
 };
 
@@ -253,7 +254,7 @@ struct babylon_color{
 	float a;
 
 	babylon_color() :r(0), g(0), b(0), a(0){}
-	babylon_color(const FbxColor& v) : r(v.mRed), g(v.mGreen), b(v.mBlue), a(v.mAlpha){}
+	babylon_color(const FbxColor& v) : r(static_cast<float>(v.mRed)), g(static_cast<float>(v.mGreen)), b(static_cast<float>(v.mBlue)), a(static_cast<float>(v.mAlpha)){}
 };
 
 inline bool operator <(const babylon_color& lhs, const babylon_color& rhs){

+ 6 - 6
Exporters/FBX/BabylonFbxNative/FbxMeshLoader.h

@@ -169,7 +169,7 @@ babylon_mesh<babylon_vertex_normal_uv_color> loadStaticMesh<babylon_vertex_norma
 			submesh.indices.push_back(found->second);
 		}
 		else{
-			int index = submesh.resolvedVertices.size();
+			int index = static_cast<int>(submesh.resolvedVertices.size());
 			babylon_vertex_normal_uv_color babVertex;
 			auto& elements = vertexKey.getKeyMembers();
 			babVertex.pos_x = (float) elements.at(0);
@@ -192,8 +192,8 @@ babylon_mesh<babylon_vertex_normal_uv_color> loadStaticMesh<babylon_vertex_norma
 	int totalVertices = 0;
 	int totalIndices = 0;
 	for (auto&& submesh : submeshes){
-		totalVertices += submesh.second.vertices.size();
-		totalIndices += submesh.second.indices.size();
+		totalVertices += static_cast<int>(submesh.second.vertices.size());
+		totalIndices += static_cast<int>(submesh.second.indices.size());
 	}
 	std::vector<babylon_vertex_normal_uv_color>vertices(totalVertices);
 	std::vector<int> indices(totalIndices);
@@ -218,10 +218,10 @@ babylon_mesh<babylon_vertex_normal_uv_color> loadStaticMesh<babylon_vertex_norma
 		babylon_submesh babSubmesh;
 		babSubmesh.material_id = materialHandler.RegisterMaterial(submesh.first);
 		babSubmesh.index_start = indicesFilled;
-		babSubmesh.index_count = submesh.second.indices.size();
+		babSubmesh.index_count = static_cast<int>(submesh.second.indices.size());
 		finalSubmeshes.push_back(babSubmesh);
-		verticesFilled += submesh.second.vertices.size();
-		indicesFilled += submesh.second.indices.size();
+		verticesFilled += static_cast<int>(submesh.second.vertices.size());
+		indicesFilled += static_cast<int>(submesh.second.indices.size());
 	}
 	return babylon_mesh<babylon_vertex_normal_uv_color>(mesh->GetName(), std::move(vertices), std::move(indices), std::move(finalSubmeshes), node->GetAnimationEvaluator()->GetNodeGlobalTransform(node));
 }

+ 33 - 0
Exporters/FBX/BabylonFbxNative/MatrixDecomposition.h

@@ -0,0 +1,33 @@
+#pragma once
+#include <fbxsdk.h>
+#include "BabylonVertex.h"
+class MatrixDecomposition
+{
+	babylon_vector3 _trans;
+	babylon_vector4 _quat;
+	babylon_vector3 _scaling;
+
+	FbxVector4 _fbxtrans;
+	FbxQuaternion _fbxrot;
+	FbxVector4 _fbxshearing;
+	FbxVector4 _fbxscaling;
+public:
+	const babylon_vector3& translation() { return _trans; }
+	const babylon_vector4& rotationQuaternion() { return _quat; }
+	const babylon_vector3& scaling() { return _scaling; }
+
+
+	const FbxVector4& fbxtrans() { return _fbxtrans; };
+	const FbxQuaternion& fbxrot() { return _fbxrot; };
+	const FbxVector4& fbxshearing() { return _fbxshearing; };
+	const FbxVector4& fbxscaling() { return _fbxscaling; };
+	MatrixDecomposition(const FbxMatrix& mat){
+		
+		double sign;
+		mat.GetElements(_fbxtrans, _fbxrot, _fbxshearing, _fbxscaling, sign);
+		_trans = _fbxtrans;
+		_quat = _fbxrot;
+		_scaling = _fbxscaling;
+	}
+};
+

+ 170 - 172
Exporters/FBX/BabylonFbxNative/NodeHelpers.h

@@ -17,7 +17,7 @@ inline std::wstring getNodeId(FbxNode* node) {
 
 const double Euler2Rad = 3.141592653589793238462 / 180;
 
-inline FbxAMatrix GetGeometryTransformation(FbxNode* inNode)
+inline FbxMatrix GetGeometryTransformation(FbxNode* inNode)
 {
 	if (!inNode)
 	{
@@ -28,177 +28,175 @@ inline FbxAMatrix GetGeometryTransformation(FbxNode* inNode)
 	const FbxVector4 lR = inNode->GetGeometricRotation(FbxNode::eSourcePivot);
 	const FbxVector4 lS = inNode->GetGeometricScaling(FbxNode::eSourcePivot);
 
-	return FbxAMatrix(lT, lR, lS);
+	return FbxMatrix(lT, lR, lS);
 }
 
-inline FbxAMatrix ConvertToBabylonCoordinateSystem(const FbxAMatrix& origin){
-	FbxAMatrix input = origin;
-	FbxVector4 translation = input.GetT();
-	auto rotationQ = input.GetQ();
-	translation.Set(translation.mData[0], translation.mData[1], -translation.mData[2]); // This negate Z of Translation Component of the matrix
-	rotationQ[0] = -rotationQ[0];
-	rotationQ[1] = -rotationQ[1];
-	//rotationQ[2] = -rotationQ[2];
-	//rotation.Set(-rotation.mData[0], -rotation.mData[1], rotation.mData[2]); // This negate X,Y of Rotation Component of the matrix
-	// These 2 lines finally set "input" to the eventual converted result
-	input.SetT(translation);
-	input.SetQ(rotationQ);
-	return input;
+inline FbxMatrix ConvertToBabylonCoordinateSystem(const FbxMatrix& origin){
+	FbxVector4 trans;
+	FbxQuaternion rot;
+	FbxVector4 shearing;
+	FbxVector4 scaling;
+	double sign;
+	origin.GetElements(trans, rot, shearing, scaling, sign);
+	trans[2] = -trans[2]; // This negate Z of Translation Component of the matrix
+	rot[0] = -rot[0];
+	rot[1] = -rot[1];
+	return FbxMatrix (trans, rot, scaling);
 }
-
-inline FbxAMatrix CalculateGlobalTransform(FbxNode* pNode, const FbxTime& time = FBXSDK_TIME_INFINITE)
-{
-	FbxAMatrix lTranlationM, lScalingM, lScalingPivotM, lScalingOffsetM, lRotationOffsetM, lRotationPivotM, \
-		lPreRotationM, lRotationM, lPostRotationM, lTransform;
-
-	FbxAMatrix lParentGX, lGlobalT, lGlobalRS;
-
-	if (!pNode)
-	{
-		lTransform.SetIdentity();
-		return lTransform;
-	}
-
-	// Construct translation matrix
-	FbxVector4 lTranslation = pNode->LclTranslation.EvaluateValue(time);
-	lTranlationM.SetT(lTranslation);
-
-	// Construct rotation matrices
-	FbxVector4 lRotation = pNode->LclRotation.EvaluateValue(time);
-	FbxVector4 lPreRotation = pNode->PreRotation.EvaluateValue(time);
-	FbxVector4 lPostRotation = pNode->PostRotation.EvaluateValue(time);
-	lRotationM.SetR(lRotation);
-	lPreRotationM.SetR(lPreRotation);
-	lPostRotationM.SetR(lPostRotation);
-
-	// Construct scaling matrix
-	FbxVector4 lScaling = pNode->LclScaling.EvaluateValue(time);
-	lScalingM.SetS(lScaling);
-
-	// Construct offset and pivot matrices
-	FbxVector4 lScalingOffset = pNode->ScalingOffset.EvaluateValue(time);
-	FbxVector4 lScalingPivot = pNode->ScalingPivot.EvaluateValue(time);
-	FbxVector4 lRotationOffset = pNode->RotationOffset.EvaluateValue(time);
-	FbxVector4 lRotationPivot = pNode->RotationPivot.EvaluateValue(time);
-	lScalingOffsetM.SetT(lScalingOffset);
-	lScalingPivotM.SetT(lScalingPivot);
-	lRotationOffsetM.SetT(lRotationOffset);
-	lRotationPivotM.SetT(lRotationPivot);
-
-	// Calculate the global transform matrix of the parent node
-	FbxNode* lParentNode = pNode->GetParent();
-	if (lParentNode)
-	{
-		lParentGX = CalculateGlobalTransform(lParentNode);
-	}
-	else
-	{
-		lParentGX.SetIdentity();
-	}
-
-	//Construct Global Rotation
-	FbxAMatrix lLRM, lParentGRM;
-	FbxVector4 lParentGR = lParentGX.GetR();
-	lParentGRM.SetR(lParentGR);
-	lLRM = lPreRotationM * lRotationM * lPostRotationM;
-
-	//Construct Global Shear*Scaling
-	//FBX SDK does not support shear, to patch this, we use:
-	//Shear*Scaling = RotationMatrix.Inverse * TranslationMatrix.Inverse * WholeTranformMatrix
-	FbxAMatrix lLSM, lParentGSM, lParentGRSM, lParentTM;
-	FbxVector4 lParentGT = lParentGX.GetT();
-	lParentTM.SetT(lParentGT);
-	lParentGRSM = lParentTM.Inverse() * lParentGX;
-	lParentGSM = lParentGRM.Inverse() * lParentGRSM;
-	lLSM = lScalingM;
-
-	//Do not consider translation now
-	FbxTransform::EInheritType lInheritType = pNode->InheritType.EvaluateValue(time);
-	if (lInheritType == FbxTransform::eInheritRrSs)
-	{
-		lGlobalRS = lParentGRM * lLRM * lParentGSM * lLSM;
-	}
-	else if (lInheritType == FbxTransform::eInheritRSrs)
-	{
-		lGlobalRS = lParentGRM * lParentGSM * lLRM * lLSM;
-	}
-	else if (lInheritType == FbxTransform::eInheritRrs)
-	{
-		FbxAMatrix lParentLSM;
-		FbxVector4 lParentLS = lParentNode->LclScaling.EvaluateValue(time);
-		lParentLSM.SetS(lParentLS);
-
-		FbxAMatrix lParentGSM_noLocal = lParentGSM * lParentLSM.Inverse();
-		lGlobalRS = lParentGRM * lLRM * lParentGSM_noLocal * lLSM;
-	}
-	else
-	{
-		FBXSDK_printf("error, unknown inherit type! \n");
-	}
-
-	// Construct translation matrix
-	// Calculate the local transform matrix
-	lTransform = lTranlationM * lRotationOffsetM * lRotationPivotM * lPreRotationM * lRotationM * lPostRotationM * lRotationPivotM.Inverse()\
-		* lScalingOffsetM * lScalingPivotM * lScalingM * lScalingPivotM.Inverse();
-	FbxVector4 lLocalTWithAllPivotAndOffsetInfo = lTransform.GetT();
-	// Calculate global translation vector according to: 
-	// GlobalTranslation = ParentGlobalTransform * LocalTranslationWithPivotAndOffsetInfo
-	FbxVector4 lGlobalTranslation = lParentGX.MultT(lLocalTWithAllPivotAndOffsetInfo);
-	lGlobalT.SetT(lGlobalTranslation);
-
-	//Construct the whole global transform
-	lTransform = lGlobalT * lGlobalRS;
-
-	return lTransform;
-}
-
-
-inline FbxAMatrix CalculateLocalTransform(FbxNode* pNode, const FbxTime& time = FBXSDK_TIME_INFINITE)
-{
-	FbxAMatrix lTranlationM, lScalingM, lScalingPivotM, lScalingOffsetM, lRotationOffsetM, lRotationPivotM, \
-		lPreRotationM, lRotationM, lPostRotationM, lTransform;
-
-
-	if (!pNode)
-	{
-		lTransform.SetIdentity();
-		return lTransform;
-	}
-
-	// Construct translation matrix
-	FbxVector4 lTranslation = pNode->LclTranslation.EvaluateValue(time);
-	lTranlationM.SetT(lTranslation);
-
-	// Construct rotation matrices
-	FbxVector4 lRotation = pNode->LclRotation.EvaluateValue(time);
-	FbxVector4 lPreRotation = pNode->PreRotation.EvaluateValue(time);
-	FbxVector4 lPostRotation = pNode->PostRotation.EvaluateValue(time);
-	lRotationM.SetR(lRotation);
-	lPreRotationM.SetR(lPreRotation);
-	lPostRotationM.SetR(lPostRotation);
-
-	// Construct scaling matrix
-	FbxVector4 lScaling = pNode->LclScaling.EvaluateValue(time);
-	lScalingM.SetS(lScaling);
-
-	// Construct offset and pivot matrices
-	FbxVector4 lScalingOffset = pNode->ScalingOffset.EvaluateValue(time);
-	FbxVector4 lScalingPivot = pNode->ScalingPivot.EvaluateValue(time);
-	FbxVector4 lRotationOffset = pNode->RotationOffset.EvaluateValue(time);
-	FbxVector4 lRotationPivot = pNode->RotationPivot.EvaluateValue(time);
-	lScalingOffsetM.SetT(lScalingOffset);
-	lScalingPivotM.SetT(lScalingPivot);
-	lRotationOffsetM.SetT(lRotationOffset);
-	lRotationPivotM.SetT(lRotationPivot);
-
-	
-	
-
-	// Construct translation matrix
-	// Calculate the local transform matrix
-	lTransform = lTranlationM * lRotationOffsetM * lRotationPivotM * lPreRotationM * lRotationM * lPostRotationM * lRotationPivotM.Inverse()\
-		* lScalingOffsetM * lScalingPivotM * lScalingM * lScalingPivotM.Inverse();
-	
-
-	return lTransform;
-}
+//
+//inline FbxAMatrix CalculateGlobalTransform(FbxNode* pNode, const FbxTime& time = FBXSDK_TIME_INFINITE)
+//{
+//	FbxAMatrix lTranlationM, lScalingM, lScalingPivotM, lScalingOffsetM, lRotationOffsetM, lRotationPivotM, \
+//		lPreRotationM, lRotationM, lPostRotationM, lTransform;
+//
+//	FbxAMatrix lParentGX, lGlobalT, lGlobalRS;
+//
+//	if (!pNode)
+//	{
+//		lTransform.SetIdentity();
+//		return lTransform;
+//	}
+//
+//	// Construct translation matrix
+//	FbxVector4 lTranslation = pNode->LclTranslation.EvaluateValue(time);
+//	lTranlationM.SetT(lTranslation);
+//
+//	// Construct rotation matrices
+//	FbxVector4 lRotation = pNode->LclRotation.EvaluateValue(time);
+//	FbxVector4 lPreRotation = pNode->PreRotation.EvaluateValue(time);
+//	FbxVector4 lPostRotation = pNode->PostRotation.EvaluateValue(time);
+//	lRotationM.SetR(lRotation);
+//	lPreRotationM.SetR(lPreRotation);
+//	lPostRotationM.SetR(lPostRotation);
+//
+//	// Construct scaling matrix
+//	FbxVector4 lScaling = pNode->LclScaling.EvaluateValue(time);
+//	lScalingM.SetS(lScaling);
+//
+//	// Construct offset and pivot matrices
+//	FbxVector4 lScalingOffset = pNode->ScalingOffset.EvaluateValue(time);
+//	FbxVector4 lScalingPivot = pNode->ScalingPivot.EvaluateValue(time);
+//	FbxVector4 lRotationOffset = pNode->RotationOffset.EvaluateValue(time);
+//	FbxVector4 lRotationPivot = pNode->RotationPivot.EvaluateValue(time);
+//	lScalingOffsetM.SetT(lScalingOffset);
+//	lScalingPivotM.SetT(lScalingPivot);
+//	lRotationOffsetM.SetT(lRotationOffset);
+//	lRotationPivotM.SetT(lRotationPivot);
+//
+//	// Calculate the global transform matrix of the parent node
+//	FbxNode* lParentNode = pNode->GetParent();
+//	if (lParentNode)
+//	{
+//		lParentGX = CalculateGlobalTransform(lParentNode);
+//	}
+//	else
+//	{
+//		lParentGX.SetIdentity();
+//	}
+//
+//	//Construct Global Rotation
+//	FbxAMatrix lLRM, lParentGRM;
+//	FbxVector4 lParentGR = lParentGX.GetR();
+//	lParentGRM.SetR(lParentGR);
+//	lLRM = lPreRotationM * lRotationM * lPostRotationM;
+//
+//	//Construct Global Shear*Scaling
+//	//FBX SDK does not support shear, to patch this, we use:
+//	//Shear*Scaling = RotationMatrix.Inverse * TranslationMatrix.Inverse * WholeTranformMatrix
+//	FbxAMatrix lLSM, lParentGSM, lParentGRSM, lParentTM;
+//	FbxVector4 lParentGT = lParentGX.GetT();
+//	lParentTM.SetT(lParentGT);
+//	lParentGRSM = lParentTM.Inverse() * lParentGX;
+//	lParentGSM = lParentGRM.Inverse() * lParentGRSM;
+//	lLSM = lScalingM;
+//
+//	//Do not consider translation now
+//	FbxTransform::EInheritType lInheritType = pNode->InheritType.EvaluateValue(time);
+//	if (lInheritType == FbxTransform::eInheritRrSs)
+//	{
+//		lGlobalRS = lParentGRM * lLRM * lParentGSM * lLSM;
+//	}
+//	else if (lInheritType == FbxTransform::eInheritRSrs)
+//	{
+//		lGlobalRS = lParentGRM * lParentGSM * lLRM * lLSM;
+//	}
+//	else if (lInheritType == FbxTransform::eInheritRrs)
+//	{
+//		FbxAMatrix lParentLSM;
+//		FbxVector4 lParentLS = lParentNode->LclScaling.EvaluateValue(time);
+//		lParentLSM.SetS(lParentLS);
+//
+//		FbxAMatrix lParentGSM_noLocal = lParentGSM * lParentLSM.Inverse();
+//		lGlobalRS = lParentGRM * lLRM * lParentGSM_noLocal * lLSM;
+//	}
+//	else
+//	{
+//		FBXSDK_printf("error, unknown inherit type! \n");
+//	}
+//
+//	// Construct translation matrix
+//	// Calculate the local transform matrix
+//	lTransform = lTranlationM * lRotationOffsetM * lRotationPivotM * lPreRotationM * lRotationM * lPostRotationM * lRotationPivotM.Inverse()\
+//		* lScalingOffsetM * lScalingPivotM * lScalingM * lScalingPivotM.Inverse();
+//	FbxVector4 lLocalTWithAllPivotAndOffsetInfo = lTransform.GetT();
+//	// Calculate global translation vector according to: 
+//	// GlobalTranslation = ParentGlobalTransform * LocalTranslationWithPivotAndOffsetInfo
+//	FbxVector4 lGlobalTranslation = lParentGX.MultT(lLocalTWithAllPivotAndOffsetInfo);
+//	lGlobalT.SetT(lGlobalTranslation);
+//
+//	//Construct the whole global transform
+//	lTransform = lGlobalT * lGlobalRS;
+//
+//	return lTransform;
+//}
+
+//
+//inline FbxAMatrix CalculateLocalTransform(FbxNode* pNode, const FbxTime& time = FBXSDK_TIME_INFINITE)
+//{
+//	FbxAMatrix lTranlationM, lScalingM, lScalingPivotM, lScalingOffsetM, lRotationOffsetM, lRotationPivotM, \
+//		lPreRotationM, lRotationM, lPostRotationM, lTransform;
+//
+//
+//	if (!pNode)
+//	{
+//		lTransform.SetIdentity();
+//		return lTransform;
+//	}
+//
+//	// Construct translation matrix
+//	FbxVector4 lTranslation = pNode->LclTranslation.EvaluateValue(time);
+//	lTranlationM.SetT(lTranslation);
+//
+//	// Construct rotation matrices
+//	FbxVector4 lRotation = pNode->LclRotation.EvaluateValue(time);
+//	FbxVector4 lPreRotation = pNode->PreRotation.EvaluateValue(time);
+//	FbxVector4 lPostRotation = pNode->PostRotation.EvaluateValue(time);
+//	lRotationM.SetR(lRotation);
+//	lPreRotationM.SetR(lPreRotation);
+//	lPostRotationM.SetR(lPostRotation);
+//
+//	// Construct scaling matrix
+//	FbxVector4 lScaling = pNode->LclScaling.EvaluateValue(time);
+//	lScalingM.SetS(lScaling);
+//
+//	// Construct offset and pivot matrices
+//	FbxVector4 lScalingOffset = pNode->ScalingOffset.EvaluateValue(time);
+//	FbxVector4 lScalingPivot = pNode->ScalingPivot.EvaluateValue(time);
+//	FbxVector4 lRotationOffset = pNode->RotationOffset.EvaluateValue(time);
+//	FbxVector4 lRotationPivot = pNode->RotationPivot.EvaluateValue(time);
+//	lScalingOffsetM.SetT(lScalingOffset);
+//	lScalingPivotM.SetT(lScalingPivot);
+//	lRotationOffsetM.SetT(lRotationOffset);
+//	lRotationPivotM.SetT(lRotationPivot);
+//
+//	
+//	
+//
+//	// Construct translation matrix
+//	// Calculate the local transform matrix
+//	lTransform = lTranlationM * lRotationOffsetM * lRotationPivotM * lPreRotationM * lRotationM * lPostRotationM * lRotationPivotM.Inverse()\
+//		* lScalingOffsetM * lScalingPivotM * lScalingM * lScalingPivotM.Inverse();
+//	
+//
+//	return lTransform;
+//}

+ 11 - 11
Exporters/FBX/BabylonFbxNative/SkinInfo.cpp

@@ -31,7 +31,7 @@ void ComputeBoneHierarchy(const std::vector<FbxNode*>& unsortedFlatListOfNodes,
 		info.linkNode = unsortedFlatListOfNodes[ix];
 		info.parentBoneIndex = currentRootIndex;
 		info.name = getNodeId(node);
-		auto boneIndex = output.size();
+		auto boneIndex = static_cast<int>(output.size());
 		output.push_back(info);
 		clusterIndexToBoneIndex[ix] = boneIndex;
 
@@ -45,7 +45,7 @@ void ComputeBoneHierarchy(const std::vector<FbxNode*>& unsortedFlatListOfNodes,
 			controlPointsData[controlPoint].push_back(biw);
 		}
 		// recursively parse children
-		ComputeBoneHierarchy(unsortedFlatListOfNodes, unsortedFlatListOfClusters, output, clusterIndexToBoneIndex, controlPointsData, node, boneIndex);
+		ComputeBoneHierarchy(unsortedFlatListOfNodes, unsortedFlatListOfClusters, output, clusterIndexToBoneIndex, controlPointsData, node, static_cast<int>(boneIndex));
 	}
 }
 FbxAMatrix NotDecomposedMultiply(const FbxAMatrix& lhs, const FbxAMatrix& rhs){
@@ -110,7 +110,7 @@ _node(meshNode), _mesh(meshNode->GetMesh()), _skin(nullptr)
 	for (auto& bone : _bones){
 		FbxAMatrix transformMatrix;
 		FbxAMatrix transformLinkMatrix;
-		FbxAMatrix globalBindposeInverseMatrix;
+		FbxMatrix globalBindposeInverseMatrix;
 
 		bone.cluster->GetTransformMatrix(transformMatrix);	// The transformation of the mesh at binding time
 		bone.cluster->GetTransformLinkMatrix(transformLinkMatrix);	// The transformation of the cluster(joint) at binding time from joint space to world space
@@ -122,7 +122,7 @@ _node(meshNode), _mesh(meshNode->GetMesh()), _skin(nullptr)
 				break;
 			}
 		}*/
-		globalBindposeInverseMatrix = transformLinkMatrix.Inverse() * transformMatrix * geometryTransform;
+		globalBindposeInverseMatrix = FbxMatrix(transformLinkMatrix.Inverse()) * FbxMatrix(transformMatrix) * geometryTransform;
 
 
 		bone.matrixGlobalBindPose = ConvertToBabylonCoordinateSystem(globalBindposeInverseMatrix.Inverse());
@@ -133,7 +133,7 @@ _node(meshNode), _mesh(meshNode->GetMesh()), _skin(nullptr)
 		}
 		else{
 			bone.matrixLocalBindPose =
-				NotDecomposedMultiply(_bones[bone.parentBoneIndex].matrixGlobalBindPose.Inverse(), bone.matrixGlobalBindPose);
+				_bones[bone.parentBoneIndex].matrixGlobalBindPose.Inverse()* bone.matrixGlobalBindPose;
 			
 		}
 	}
@@ -151,12 +151,12 @@ _node(meshNode), _mesh(meshNode->GetMesh()), _skin(nullptr)
 	auto animLengthInFrame = endFrame - startFrame + 1;
 
 
-	for (auto ix = 0ll; ix < animLengthInFrame; ix++){
+	for (auto ix = 0; ix < animLengthInFrame; ix++){
 		FbxTime currTime;
 		currTime.SetFrame(startFrame + ix, animTimeMode);
 
 
-		auto currTransformOffset = meshNode->EvaluateGlobalTransform(currTime) * geometryTransform;
+		auto currTransformOffset = FbxMatrix(meshNode->EvaluateGlobalTransform(currTime)) * geometryTransform;
 		auto currTransformOffsetInverse = currTransformOffset.Inverse();
 
 		// compute global transform and local
@@ -174,7 +174,7 @@ _node(meshNode), _mesh(meshNode->GetMesh()), _skin(nullptr)
 				auto& parentBone = _bones[bone.parentBoneIndex];
 				
 				kf.matrixLocal = //bone.matrixLocalBindPose;
-					NotDecomposedMultiply(parentBone.keyFrames[parentBone.keyFrames.size() - 1].matrixGlobal.Inverse(), kf.matrixGlobal);
+					parentBone.keyFrames[parentBone.keyFrames.size() - 1].matrixGlobal.Inverse()* kf.matrixGlobal;
 
 			}
 
@@ -193,7 +193,7 @@ void SkinInfo::buildBabylonSkeleton(BabylonSkeleton& skel){
 	skel.name = getNodeId(_node) + L"_skeleton";
 	for (auto& b : _bones){
 		BabylonBone babbone;
-		babbone.index = skel.bones.size();
+		babbone.index = static_cast<int>(skel.bones.size());
 		//babbone.matrix = ConvertToBabylonCoordinateSystem( b.matrixLocalBindPose);
 		babbone.matrix = b.matrixLocalBindPose;
 		babbone.name = b.name;
@@ -208,10 +208,10 @@ void SkinInfo::buildBabylonSkeleton(BabylonSkeleton& skel){
 		auto endFrame = takeInfo->mLocalTimeSpan.GetStop().GetFrameCount(animTimeMode);
 		auto animLengthInFrame = endFrame - startFrame + 1;
 
-		auto matrixAnim = std::make_shared<BabylonAnimation<FbxAMatrix>>(BabylonAnimationBase::loopBehavior_Cycle, animFrameRate, L"_matrix", L"_matrix", true, 0, animLengthInFrame, true);
+		auto matrixAnim = std::make_shared<BabylonAnimation<FbxMatrix>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"_matrix", L"_matrix", true, 0, static_cast<int>(animLengthInFrame), true);
 		for (auto& kf : b.keyFrames){
 
-			babylon_animation_key<FbxAMatrix> key;
+			babylon_animation_key<FbxMatrix> key;
 			key.frame = kf.frame;
 			//key.values = ConvertToBabylonCoordinateSystem(kf.matrixLocal);
 			key.values = kf.matrixLocal;

+ 5 - 5
Exporters/FBX/BabylonFbxNative/SkinInfo.h

@@ -8,8 +8,8 @@
 
 struct BoneAnimKeyFrame{
 	int frame;
-	FbxAMatrix matrixLocal;
-	FbxAMatrix matrixGlobal;
+	FbxMatrix matrixLocal;
+	FbxMatrix matrixGlobal;
 };
 struct BoneInfo{
 	FbxNode*  linkNode;
@@ -18,8 +18,8 @@ struct BoneInfo{
 	int parentBoneIndex;
 	std::wstring name;
 
-	FbxAMatrix matrixGlobalBindPose;
-	FbxAMatrix matrixLocalBindPose;
+	FbxMatrix matrixGlobalBindPose;
+	FbxMatrix matrixLocalBindPose;
 	std::vector<BoneAnimKeyFrame> keyFrames;
 };
 
@@ -49,7 +49,7 @@ public:
 	}
 
 	int bonesCount() const{
-		return _bones.size();
+		return static_cast<int>( _bones.size());
 	}
 
 	void buildBabylonSkeleton(BabylonSkeleton& skel);

+ 6 - 6
Exporters/FBX/BabylonFbxNative/babylon_boundingbox.cpp

@@ -19,12 +19,12 @@ babylon_boundingbox::babylon_boundingbox()
 babylon_boundingbox::babylon_boundingbox(FbxScene* scene){
 	FbxVector4 vmin, vmax, vcenter;
 	scene->ComputeBoundingBoxMinMaxCenter(vmin, vmax, vcenter);
-	_minX = vmin[0];
-	_minY = vmin[1];
-	_minZ = vmin[2];
-	_maxX = vmax[0];
-	_maxY = vmax[1];
-	_maxZ = vmax[2];
+	_minX = static_cast<float>(vmin[0]);
+	_minY = static_cast<float>(vmin[1]);
+	_minZ = static_cast<float>(vmin[2]);
+	_maxX = static_cast<float>(vmax[0]);
+	_maxY = static_cast<float>(vmax[1]);
+	_maxZ = static_cast<float>(vmax[2]);
 
 }
 void babylon_boundingbox::addPosition(float x, float y, float z){

+ 55 - 39
Exporters/FBX/FbxExporter/FbxExporter.cpp

@@ -32,6 +32,7 @@ std::string toString(BabylonNodeType type) {
 		return "<empty>";
 		break;
 	default:
+		return "unknown";
 		break;
 	}
 }
@@ -41,43 +42,43 @@ std::string toString(FbxDouble3 value) {
 	s << "(" << value[0] << "," << value[1] << "," << value[2] << ")";
 	return s.str();
 }
-void printNode(BabylonNode& node, int indent = 0) {
-	for (auto i = 0; i < indent; ++i) {
-		std::cout << '\t';
-	}
-	std::cout << node.uniqueId() << " : " << node.name() << " " << toString(node.nodeType()) << " has only skeleton desc : " << node.hasOnlySkeletonDescendants() << std::endl;
-	for (auto i = 0; i < indent; ++i) {
-		std::cout << '\t';
-	}
-	
-}
 
 
 std::string wstringToUtf8(const std::wstring& src){
-	auto size = WideCharToMultiByte(CP_UTF8, 0, src.c_str(), src.size(), nullptr, 0, nullptr, nullptr);
+	auto size = WideCharToMultiByte(CP_UTF8, 0, src.c_str(), static_cast<int>( src.size()), nullptr, 0, nullptr, nullptr);
 	std::string result;
 	result.resize(size, ' ');
-	WideCharToMultiByte(CP_UTF8, 0, src.c_str(), src.size(), &result[0], result.size(),nullptr, nullptr);
+	WideCharToMultiByte(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), &result[0], size,nullptr, nullptr);
 	return result;
 }
 
-bool isNodeOrDescendantVisible(FbxNode* node){
-	if (node == nullptr){
-		return false;
+void fixupTextureCoordinateIndices(BabylonMaterial& mat, BabylonMesh& mesh) {
+	std::vector<std::shared_ptr<BabylonTexture>> textures;
+	if (mat.ambientTexture) {
+		textures.push_back(mat.ambientTexture);
 	}
-	if (node->GetVisibility()){
-		return true;
+	if (mat.diffuseTexture) {
+		textures.push_back(mat.diffuseTexture);
 	}
-
-	auto childCount = node->GetChildCount();
-	for (auto ix = 0; ix < childCount; ++ix){
-		if (isNodeOrDescendantVisible(node->GetChild(ix))){
-			return true;
+	if (mat.specularTexture) {
+		textures.push_back(mat.specularTexture);
+	}
+	if (mat.emissiveTexture) {
+		textures.push_back(mat.emissiveTexture);
+	}
+	if (mat.reflectionTexture) {
+		textures.push_back(mat.reflectionTexture);
+	}
+	if (mat.bumpTexture) {
+		textures.push_back(mat.bumpTexture);
+	}
+	for (auto& tex : textures) {
+		auto found = std::find(mesh.uvsets.begin(), mesh.uvsets.end(), tex->uvset);
+		if (found != mesh.uvsets.end()) {
+			tex->coordinatesIndex = static_cast<int>(found - mesh.uvsets.begin());
 		}
 	}
-	return false;
 }
-
 void exploreMeshes(BabylonScene& scene, BabylonNode& node, bool skipEmptyNodes) {
 	if (node.nodeType() == BabylonNodeType::Skeleton && node.hasOnlySkeletonDescendants()) {
 		return;
@@ -92,36 +93,46 @@ void exploreMeshes(BabylonScene& scene, BabylonNode& node, bool skipEmptyNodes)
 	case BabylonNodeType::Mesh:
 	case BabylonNodeType::Skeleton:
 	{
+
+		scene.meshes().emplace_back(&node);
+		auto& mesh = scene.meshes()[scene.meshes().size() - 1];
 		auto matCount = node.fbxNode()->GetMaterialCount();
 		BabylonMultiMaterial multiMat;
 		for (auto i = 0; i < matCount; ++i) {
 			auto mat = node.fbxNode()->GetMaterial(i);
 			if (mat) {
-				BabylonMaterial babMat(mat);
-				auto id = babMat.id;
-				multiMat.materials.push_back(id);
+
+				auto id = getMaterialId(mat);
 				auto existing = std::find_if(scene.materials().begin(), scene.materials().end(), [id](const BabylonMaterial& e) {
 					return e.id == id;
 				});
 				if (existing == scene.materials().end()) {
+					auto babMat = BabylonMaterial(mat);
+					fixupTextureCoordinateIndices(babMat, mesh);
 					scene.materials().push_back(babMat);
 				}
+
+				multiMat.materials.push_back(id);
+				
 			}
 		}
 
-		scene.meshes().emplace_back(&node);
-		auto& mesh = scene.meshes()[scene.meshes().size() - 1];
 		if (mesh.associatedSkeleton){
-			mesh.associatedSkeleton->id = scene.skeletons().size()+1;
-			mesh.skeletonId(scene.skeletons().size()+1);
+			mesh.associatedSkeleton->id = static_cast<int>(scene.skeletons().size()+1);
+			mesh.skeletonId(static_cast<int>(scene.skeletons().size()+1));
 			scene.skeletons().push_back(mesh.associatedSkeleton);
 		}
 		if (multiMat.materials.size() > 0) {
 			auto& mesh = scene.meshes()[scene.meshes().size() - 1];
-			multiMat.id = mesh.id();
-			multiMat.name = mesh.name();
-			mesh.materialId(multiMat.id);
-			scene.multiMaterials().push_back(multiMat);
+			/*if (multiMat.materials.size() == 1) {
+				mesh.materialId(multiMat.materials[0]);
+			}
+			else {*/
+				multiMat.id = mesh.id();
+				multiMat.name = mesh.name();
+				mesh.materialId(multiMat.id);
+				scene.multiMaterials().push_back(multiMat);
+			//}
 		}
 	}
 	break;
@@ -134,7 +145,14 @@ void exploreMeshes(BabylonScene& scene, BabylonNode& node, bool skipEmptyNodes)
 	}
 	break;
 	case BabylonNodeType::Light:
+	{
 		scene.lights().emplace_back(node);
+		auto& l = scene.lights()[scene.lights().size() - 1];
+		if (l.shadowGenerator) {
+			scene.shadowGenerators().push_back(l.shadowGenerator);
+		}
+	}
+	break;
 	default:
 		break;
 	}
@@ -189,7 +207,7 @@ void exportTexture(const std::shared_ptr<BabylonTexture>& tex, const std::wstrin
 		}
 		outputPath[indexOfSlash] = L'\\';
 	}
-	auto start = 0;
+	size_t start = 0;
 	for (;;){
 		auto indexOfSlash = outputPath.find(L'\\', start);
 		if (indexOfSlash == outputPath.npos){
@@ -258,10 +276,8 @@ int _tmain(int argc, _TCHAR* argv[])
 
 	FbxSceneLoader sceneLoader(wstringToUtf8(wInputPath));
 	auto root = sceneLoader.rootNode();
-	printNode(*root);
 
 	BabylonScene babScene;
-	std::cout << "exporting empty nodes as empty meshes" << std::endl;
 	exploreMeshes(babScene, *root, skipEmptyNodes);
 
 	for (auto& mat : babScene.materials()){
@@ -331,7 +347,7 @@ int _tmain(int argc, _TCHAR* argv[])
 	wOutputPath.erase(lastDot);
 	wOutputPath.append(L".babylon");
 	DeleteFile(wOutputPath.c_str());
-	std::wofstream stream(wOutputPath);
+	std::ofstream stream(wOutputPath);
 	json.serialize(stream);
 	stream.flush();
 	return 0;

+ 6 - 2
Exporters/FBX/FbxRerouteSkeleton/FbxRerouteSkeleton.cpp

@@ -12,10 +12,10 @@
 #include <memory>
 
 std::string wstringToUtf8(const std::wstring& src){
-	auto size = WideCharToMultiByte(CP_UTF8, 0, src.c_str(), src.size(), nullptr, 0, nullptr, nullptr);
+	auto size = WideCharToMultiByte(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), nullptr, 0, nullptr, nullptr);
 	std::string result;
 	result.resize(size, ' ');
-	WideCharToMultiByte(CP_UTF8, 0, src.c_str(), src.size(), &result[0], result.size(), nullptr, nullptr);
+	WideCharToMultiByte(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), &result[0], size, nullptr, nullptr);
 	return result;
 }
 
@@ -24,6 +24,10 @@ void populateNodeMap(std::map<std::string, FbxNode*>& m, FbxNode* currNode){
 		return;
 	}
 	m[currNode->GetName()] = currNode;
+	auto mesh = currNode->GetMesh();
+	if (mesh) {
+		currNode->SetNodeAttribute(nullptr);
+	}
 	for (auto ix = 0; ix < currNode->GetChildCount(); ++ix){
 		populateNodeMap(m, currNode->GetChild(ix));
 	}