瀏覽代碼

Added : Default Camera / light creation (if none)
Fixed : Opacity on materials
Added : Tool to merge multiple FBX files and reroute skeletons

Simon 10 年之前
父節點
當前提交
50a941acb9

+ 72 - 25
Exporters/FBX/BabylonFBXExporter.sln

@@ -1,82 +1,129 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.22609.0
+# Visual Studio 2013
+VisualStudioVersion = 12.0.31101.0
 MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BabylonFbxNative", ".\BabylonFbxNative\BabylonFbxNative.vcxproj", "{6C145CFB-31AC-4B28-8B74-26680D26A6E3}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BabylonFbxNative", "BabylonFbxNative\BabylonFbxNative.vcxproj", "{6C145CFB-31AC-4B28-8B74-26680D26A6E3}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FbxExporter", ".\FbxExporter\FbxExporter.vcxproj", "{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FbxExporter", "FbxExporter\FbxExporter.vcxproj", "{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", ".\3rdParty\DirectXTex\DirectXTex_Desktop_2013.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DirectXTex", "3rdParty\DirectXTex\DirectXTex_Desktop_2013.vcxproj", "{371B9FA9-4C90-4AC6-A123-ACED756D6C77}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FbxRerouteSkeleton", "FbxRerouteSkeleton\FbxRerouteSkeleton.vcxproj", "{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Mixed Platforms = Debug|Mixed Platforms
+		Debug|Win32 = Debug|Win32
 		Debug|x64 = Debug|x64
 		Debug|x86 = Debug|x86
+		Profile|Mixed Platforms = Profile|Mixed Platforms
+		Profile|Win32 = Profile|Win32
 		Profile|x64 = Profile|x64
 		Profile|x86 = Profile|x86
+		Release|Mixed Platforms = Release|Mixed Platforms
+		Release|Win32 = Release|Win32
 		Release|x64 = Release|x64
 		Release|x86 = Release|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Debug|Win32.Build.0 = Debug|Win32
 		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Debug|x64.ActiveCfg = Debug|x64
 		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Debug|x64.Build.0 = Debug|x64
 		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Debug|x86.ActiveCfg = Debug|Win32
 		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Debug|x86.Build.0 = Debug|Win32
+		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Profile|Mixed Platforms.ActiveCfg = Release|Win32
+		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Profile|Mixed Platforms.Build.0 = Release|Win32
+		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Profile|Win32.ActiveCfg = Release|Win32
+		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Profile|Win32.Build.0 = Release|Win32
 		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Profile|x64.ActiveCfg = Release|x64
 		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Profile|x64.Build.0 = Release|x64
 		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Profile|x86.ActiveCfg = Release|Win32
 		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Profile|x86.Build.0 = Release|Win32
+		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Release|Mixed Platforms.Build.0 = Release|Win32
+		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Release|Win32.ActiveCfg = Release|Win32
+		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Release|Win32.Build.0 = Release|Win32
 		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Release|x64.ActiveCfg = Release|x64
 		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Release|x64.Build.0 = Release|x64
 		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Release|x86.ActiveCfg = Release|Win32
 		{6C145CFB-31AC-4B28-8B74-26680D26A6E3}.Release|x86.Build.0 = Release|Win32
+		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Debug|Win32.ActiveCfg = Debug|Win32
+		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Debug|Win32.Build.0 = Debug|Win32
 		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Debug|x64.ActiveCfg = Debug|x64
 		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Debug|x64.Build.0 = Debug|x64
 		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Debug|x86.ActiveCfg = Debug|Win32
 		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Debug|x86.Build.0 = Debug|Win32
+		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Profile|Mixed Platforms.ActiveCfg = Release|Win32
+		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Profile|Mixed Platforms.Build.0 = Release|Win32
+		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Profile|Win32.ActiveCfg = Release|Win32
+		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Profile|Win32.Build.0 = Release|Win32
 		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Profile|x64.ActiveCfg = Release|x64
 		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Profile|x64.Build.0 = Release|x64
 		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Profile|x86.ActiveCfg = Release|Win32
 		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Profile|x86.Build.0 = Release|Win32
+		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Release|Mixed Platforms.Build.0 = Release|Win32
+		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Release|Win32.ActiveCfg = Release|Win32
+		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Release|Win32.Build.0 = Release|Win32
 		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Release|x64.ActiveCfg = Release|x64
 		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Release|x64.Build.0 = Release|x64
 		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Release|x86.ActiveCfg = Release|Win32
 		{DF8C65DD-1E5C-44BE-8FD2-457C72AA46FC}.Release|x86.Build.0 = Release|Win32
+		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.ActiveCfg = Debug|Win32
+		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|Win32.Build.0 = Debug|Win32
 		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.ActiveCfg = Debug|x64
 		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x64.Build.0 = Debug|x64
 		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x86.ActiveCfg = Debug|Win32
 		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Debug|x86.Build.0 = Debug|Win32
+		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Mixed Platforms.ActiveCfg = Profile|Win32
+		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Mixed Platforms.Build.0 = Profile|Win32
+		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.ActiveCfg = Profile|Win32
+		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|Win32.Build.0 = Profile|Win32
 		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.ActiveCfg = Profile|x64
 		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x64.Build.0 = Profile|x64
 		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x86.ActiveCfg = Profile|Win32
 		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Profile|x86.Build.0 = Profile|Win32
+		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Mixed Platforms.Build.0 = Release|Win32
+		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.ActiveCfg = Release|Win32
+		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|Win32.Build.0 = Release|Win32
 		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.ActiveCfg = Release|x64
 		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x64.Build.0 = Release|x64
 		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x86.ActiveCfg = Release|Win32
 		{371B9FA9-4C90-4AC6-A123-ACED756D6C77}.Release|x86.Build.0 = Release|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Debug|Win32.Build.0 = Debug|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Debug|x64.ActiveCfg = Debug|x64
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Debug|x64.Build.0 = Debug|x64
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Debug|x86.ActiveCfg = Debug|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Debug|x86.Build.0 = Debug|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Profile|Mixed Platforms.ActiveCfg = Release|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Profile|Mixed Platforms.Build.0 = Release|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Profile|Win32.ActiveCfg = Release|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Profile|Win32.Build.0 = Release|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Profile|x64.ActiveCfg = Release|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Profile|x86.ActiveCfg = Release|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Profile|x86.Build.0 = Release|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Release|Mixed Platforms.Build.0 = Release|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Release|Win32.ActiveCfg = Release|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Release|Win32.Build.0 = Release|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Release|x64.ActiveCfg = Release|x64
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Release|x64.Build.0 = Release|x64
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Release|x86.ActiveCfg = Release|Win32
+		{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}.Release|x86.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
-	GlobalSection(TeamFoundationVersionControl) = preSolution
-		SccNumberOfProjects = 3
-		SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
-		SccTeamFoundationServer = https://deltakosh.visualstudio.com/defaultcollection
-		SccProjectUniqueName0 = ..\\BabylonFbxNative\\BabylonFbxNative.vcxproj
-		SccProjectName0 = ../BabylonFbxNative
-		SccAuxPath0 = https://deltakosh.visualstudio.com/defaultcollection
-		SccLocalPath0 = ..\\BabylonFbxNative
-		SccProvider0 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
-		SccProjectUniqueName1 = ..\\FbxExporter\\FbxExporter.vcxproj
-		SccProjectName1 = ../FbxExporter
-		SccAuxPath1 = https://deltakosh.visualstudio.com/defaultcollection
-		SccLocalPath1 = ..\\FbxExporter
-		SccProvider1 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
-		SccProjectUniqueName2 = ..\\3rdParty\\DirectXTex\\DirectXTex_Desktop_2013.vcxproj
-		SccProjectName2 = ../3rdParty/DirectXTex
-		SccAuxPath2 = https://deltakosh.visualstudio.com/defaultcollection
-		SccLocalPath2 = ..\\3rdParty\\DirectXTex
-		SccProvider2 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
-	EndGlobalSection
 EndGlobal

+ 27 - 7
Exporters/FBX/BabylonFbxNative/BabylonCamera.cpp

@@ -1,6 +1,7 @@
 #include "stdafx.h"
 #include "BabylonCamera.h"
 #include "NodeHelpers.h"
+#include "GlobalSettings.h"
 
 web::json::value BabylonCamera::toJson() const
 {
@@ -25,7 +26,7 @@ web::json::value BabylonCamera::toJson() const
 	jobj[L"inertia"] = web::json::value::number(inertia);
 	jobj[L"checkCollisions"] = web::json::value::boolean(checkCollisions);
 	jobj[L"applyGravity"] = web::json::value::boolean(applyGravity);
-	writeVector2(jobj, L"ellipsoid", ellipsoid);
+	writeVector3(jobj, L"ellipsoid", ellipsoid);
 	if (animations.size() == 0 && quatAnimations.size() == 0){
 
 		jobj[L"autoAnimate"] = web::json::value::boolean(false);
@@ -63,6 +64,23 @@ BabylonCamera::BabylonCamera()
 }
 
 
+BabylonCamera buildCameraFromBoundingBox(const babylon_boundingbox& box){
+	BabylonCamera result;
+	result.name = L"defaultcamera";
+	result.id = L"defaultcamera";
+
+	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.maxZ = -5 * result.position.z;
+	result.speed = (-result.position.z - result.target.z) / 10;
+	result.inertia = 0.9f;
+	result.checkCollisions = false;
+	result.applyGravity = false;
+	result.ellipsoid = babylon_vector3(.2f, .9f, .2f);
+	return result;
+}
 
 BabylonCamera::BabylonCamera(BabylonNode& babnode)
 {
@@ -100,17 +118,19 @@ BabylonCamera::BabylonCamera(BabylonNode& babnode)
 	auto animStack = node->GetScene()->GetSrcObject<FbxAnimStack>(0);
 	FbxString animStackName = animStack->GetName();
 	FbxTakeInfo* takeInfo = node->GetScene()->GetTakeInfo(animStackName);
-	auto startFrame = takeInfo->mLocalTimeSpan.GetStart().GetFrameCount(FbxTime::eFrames24);
-	auto endFrame = takeInfo->mLocalTimeSpan.GetStop().GetFrameCount(FbxTime::eFrames24);
+	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;
 
-	auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, 24, L"position", L"position", true, 0, animLengthInFrame, true);
-	auto rotAnim = std::make_shared<BabylonAnimation<babylon_vector4>>(BabylonAnimationBase::loopBehavior_Cycle, 24, L"rotation", L"rotation", true, 0, animLengthInFrame, true);
-	auto targetAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, 24, L"target", L"target", true, 0, animLengthInFrame, true);
+	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, FbxTime::eFrames24);
+		currTime.SetFrame(startFrame + ix, animTimeMode);
 
 		babylon_animation_key<babylon_vector3> poskey;
 		babylon_animation_key<babylon_vector4> rotkey;

+ 4 - 2
Exporters/FBX/BabylonFbxNative/BabylonCamera.h

@@ -28,7 +28,7 @@ public:
 	babylon_vector3 position;
 
 		
-	babylon_vector4 rotationQuaternion;
+	babylon_vector4 rotationQuaternion = babylon_vector4(0,0,0,1);
 
 		
 	babylon_vector3 target;
@@ -55,7 +55,7 @@ public:
 	bool applyGravity = false;
 
 		
-	babylon_vector2 ellipsoid;
+	babylon_vector3 ellipsoid;
 
 		
 	bool autoAnimate = false;
@@ -80,3 +80,5 @@ public:
 	~BabylonCamera();
 };
 
+
+BabylonCamera buildCameraFromBoundingBox(const babylon_boundingbox& box);

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

@@ -188,6 +188,7 @@
     <ClInclude Include="FbxMeshLoader.h" />
     <ClInclude Include="FbxSceneLoader.h" />
     <ClInclude Include="FbxVertexKey.h" />
+    <ClInclude Include="GlobalSettings.h" />
     <ClInclude Include="NodeHelpers.h" />
     <ClInclude Include="SkinInfo.h" />
     <ClInclude Include="stdafx.h" />
@@ -208,6 +209,7 @@
     <ClCompile Include="FbxMaterialHandler.cpp" />
     <ClCompile Include="FbxSceneLoader.cpp" />
     <ClCompile Include="FbxVertexKey.cpp" />
+    <ClCompile Include="GlobalSettings.cpp" />
     <ClCompile Include="SkinInfo.cpp" />
     <ClCompile Include="stdafx.cpp">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>

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

@@ -81,6 +81,9 @@
     <ClInclude Include="BabylonSkeleton.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="GlobalSettings.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="stdafx.cpp">
@@ -131,6 +134,9 @@
     <ClCompile Include="BabylonSkeleton.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="GlobalSettings.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="packages.config" />

+ 8 - 5
Exporters/FBX/BabylonFbxNative/BabylonLight.cpp

@@ -1,6 +1,7 @@
 #include "stdafx.h"
 #include "BabylonLight.h"
 #include "NodeHelpers.h"
+#include "GlobalSettings.h"
 
 web::json::value BabylonLight::toJson() const
 {
@@ -111,20 +112,22 @@ specular(1, 1, 1)
 	auto animStack = node->GetScene()->GetSrcObject<FbxAnimStack>(0);
 	FbxString animStackName = animStack->GetName();
 	FbxTakeInfo* takeInfo = node->GetScene()->GetTakeInfo(animStackName);
-	auto startFrame = takeInfo->mLocalTimeSpan.GetStart().GetFrameCount(FbxTime::eFrames24);
-	auto endFrame = takeInfo->mLocalTimeSpan.GetStop().GetFrameCount(FbxTime::eFrames24);
+	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;
 	auto posAnimName = getNodeId(node);
 	auto dirAnimName = getNodeId(node);
 	posAnimName.append(L"_position");
 	dirAnimName.append(L"_direction");
-	auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, 24, posAnimName, L"position", true, 0, animLengthInFrame, true);
-	auto dirAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, 24, dirAnimName, L"direction", true, 0, animLengthInFrame, true);
+	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, FbxTime::eFrames24);
+		currTime.SetFrame(startFrame + ix, animTimeMode);
 		key.values = babnode.localTranslate(currTime);
 		posAnim->appendKey(key);
 

+ 33 - 0
Exporters/FBX/BabylonFbxNative/BabylonMaterial.cpp

@@ -113,13 +113,42 @@ specularPower(64),
 alpha(1){
 	std::string ansiName = mat->GetName();
 	name = std::wstring(ansiName.begin(), ansiName.end());
+	auto rawId = mat->GetUniqueID();
 	id = getMaterialId(mat);
 	FbxFileTexture* ambientTex = nullptr;
 	FbxFileTexture* diffuseTex = nullptr;
 	FbxFileTexture* specularTex = nullptr;
 	FbxFileTexture* emissiveTex = nullptr;
 	FbxFileTexture* reflectionTex = nullptr;
+	FbxFileTexture* opacityTex = nullptr;
 	FbxFileTexture* bumpTex = nullptr;
+	GetMaterialProperty(mat, FbxSurfaceMaterial::sTransparentColor, FbxSurfaceMaterial::sTransparencyFactor, opacityTex)[0];
+
+	FbxDouble3 transcolor;
+	FbxDouble transfactor;
+	auto transFactorProp = mat->FindProperty(FbxSurfaceMaterial::sTransparencyFactor);
+	auto transColorProp = mat->FindProperty(FbxSurfaceMaterial::sTransparentColor);
+	if (transFactorProp.IsValid() && transColorProp.IsValid()){
+		transfactor = transFactorProp.Get<FbxDouble>();
+		transcolor = transColorProp.Get<FbxDouble3>();
+		if (transfactor== 1.0){ // from Maya .fbx
+			if (transcolor[0] >= DBL_MIN) {
+				alpha = 1 - transcolor[0];
+			}
+			else {
+				alpha = 1;
+			}
+		}
+		else { // from 3dsmax .fbx
+			if (transfactor>=DBL_MIN){
+				alpha = 1 - transfactor;
+			}
+			else {
+				alpha = 1;
+			}
+		}
+	}
+
 	ambient = GetMaterialProperty(mat, FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor, ambientTex);
 	diffuse = GetMaterialProperty(mat, FbxSurfaceMaterial::sDiffuse, FbxSurfaceMaterial::sDiffuseFactor, diffuseTex);
 	specular = GetMaterialProperty(mat, FbxSurfaceMaterial::sSpecular, FbxSurfaceMaterial::sSpecularFactor, specularTex);
@@ -176,6 +205,10 @@ alpha(1){
 		bumpTexture = std::make_shared<BabylonTexture>(bumpTex);
 	}
 
+	if (opacityTex){
+		opacityTexture = std::make_shared<BabylonTexture>(opacityTex);
+	}
+
 }
 
 

+ 13 - 6
Exporters/FBX/BabylonFbxNative/BabylonMesh.cpp

@@ -5,6 +5,7 @@
 #include <iostream>
 #include <sstream>
 #include "NodeHelpers.h"
+#include "GlobalSettings.h"
 
 struct BabylonVertex {
 	babylon_vector3 position;
@@ -396,17 +397,20 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 	auto animStack = fbxNode->GetScene()->GetSrcObject<FbxAnimStack>(0);
 	FbxString animStackName = animStack->GetName();
 	FbxTakeInfo* takeInfo = fbxNode->GetScene()->GetTakeInfo(animStackName);
-	auto startFrame = takeInfo->mLocalTimeSpan.GetStart().GetFrameCount(FbxTime::eFrames24);
-	auto endFrame = takeInfo->mLocalTimeSpan.GetStop().GetFrameCount(FbxTime::eFrames24);
+
+	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;
 
-	auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, 24, L"position", L"position", true, 0, animLengthInFrame, true);
-	auto rotAnim = std::make_shared<BabylonAnimation<babylon_vector4>>(BabylonAnimationBase::loopBehavior_Cycle, 24, L"rotationQuaternion", L"rotationQuaternion", true, 0, animLengthInFrame, true);
-	auto scaleAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, 24, L"scale", L"scale", true, 0, animLengthInFrame, true);
+	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, FbxTime::eFrames24);
+		currTime.SetFrame(startFrame + ix, animTimeMode);
 
 		babylon_animation_key<babylon_vector3> poskey;
 		babylon_animation_key<babylon_vector4> rotkey;
@@ -436,6 +440,9 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 	if (!mesh) {
 		return;
 	}
+	if (mesh->GetPolygonCount() == 0){
+		return;
+	}
 	FbxGeometryConverter conv(mesh->GetFbxManager());
 	conv.ComputePolygonSmoothingFromEdgeSmoothing(mesh);
 	if (!mesh->IsTriangleMesh()) {

+ 2 - 1
Exporters/FBX/BabylonFbxNative/BabylonVertex.h

@@ -178,6 +178,8 @@ public:
 			0.5f*(_maxZ + _minZ));
 	}
 	babylon_boundingbox();
+
+	babylon_boundingbox(FbxScene* scene);
 	~babylon_boundingbox();
 };
 
@@ -346,7 +348,6 @@ struct babylon_camera{
 
 };
 
-babylon_camera buildCameraFromBoundingBox(const babylon_boundingbox& box);
 
 
 

+ 8 - 3
Exporters/FBX/BabylonFbxNative/FbxSceneLoader.cpp

@@ -16,6 +16,7 @@ void MapNodes(std::map<std::uint64_t, BabylonNode*> map, BabylonNode* node){
 FbxSceneLoader::FbxSceneLoader(const std::string& filePath) :_scene(nullptr), _filePath(filePath), _fbxMgr(FbxManager::Create())
 {
 	std::unique_ptr<FbxIOSettings, FbxDeleter> iosettings(FbxIOSettings::Create(_fbxMgr.get(), IOSROOT));
+
 	iosettings->SetBoolProp(IMP_FBX_MATERIAL, true);
 	iosettings->SetBoolProp(IMP_FBX_TEXTURE, true);
 	iosettings->SetBoolProp(IMP_FBX_LINK, true);
@@ -24,16 +25,18 @@ FbxSceneLoader::FbxSceneLoader(const std::string& filePath) :_scene(nullptr), _f
 	iosettings->SetBoolProp(IMP_FBX_ANIMATION, true);
 	iosettings->SetBoolProp(IMP_SKINS, true);
 	iosettings->SetBoolProp(IMP_DEFORMATION, true);
-	iosettings->SetBoolProp(IMP_BONE, true);
 	iosettings->SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true);
 	iosettings->SetBoolProp(IMP_TAKE, true);
 	_fbxMgr->SetIOSettings(iosettings.get());
+
 	std::unique_ptr<FbxImporter, FbxDeleter> importer(FbxImporter::Create(_fbxMgr.get(), "SceneImporter"));
 	if (!importer->Initialize(_filePath.c_str())){
 		throw FbxLoadException(importer->GetStatus().GetErrorString());
 	}
 	_scene = FbxScene::Create(_fbxMgr.get(), filePath.c_str());
 	importer->Import(_scene);
+
+	
 	//auto srcSystem = _scene->GetGlobalSettings().GetAxisSystem();
 	////FbxAxisSystem::OpenGL.ConvertScene(_scene);
 	////FbxAxisSystem::DirectX.ConvertChildren(_scene->GetRootNode(), srcSystem);
@@ -44,13 +47,15 @@ FbxSceneLoader::FbxSceneLoader(const std::string& filePath) :_scene(nullptr), _f
 
 	//_scene->GetRootNode()->LclScaling.Set(scale);
 	//_scene->GetRootNode()->LclRotation.Set(rot);
-	_rootNode = std::make_unique<BabylonNode>( _scene->GetRootNode());
+	_rootNode = std::make_unique<BabylonNode>(_scene->GetRootNode());
 	MapNodes(_nodesMap, _rootNode.get());
 }
 
 
+
 FbxSceneLoader::~FbxSceneLoader()
 {
+	_scene->Destroy(true);
 }
 
 
@@ -58,7 +63,7 @@ babylon_global_settings FbxSceneLoader::getGlobalSettings(){
 	babylon_global_settings result;
 	auto& settings = _scene->GetGlobalSettings();
 	/*auto color = settings.GetAmbientColor();
-	
+
 	result.ambientColor = babylon_vector3( (float) color.mRed, (float) color.mGreen, (float) color.mBlue );*/
 	return result;
 }

+ 13 - 0
Exporters/FBX/BabylonFbxNative/GlobalSettings.cpp

@@ -0,0 +1,13 @@
+#include "stdafx.h"
+#include "GlobalSettings.h"
+
+
+
+GlobalSettings::GlobalSettings()
+{
+}
+
+GlobalSettings& GlobalSettings::Current(){
+	static GlobalSettings settings;
+	return settings;
+}

+ 14 - 0
Exporters/FBX/BabylonFbxNative/GlobalSettings.h

@@ -0,0 +1,14 @@
+#pragma once
+#include <fbxsdk.h>
+class GlobalSettings
+{
+private:
+
+	GlobalSettings();
+public:
+	FbxTime::EMode AnimationsTimeMode = FbxTime::eFrames24;
+	double AnimationsFrameRate(){
+		return FbxTime::GetFrameRate(AnimationsTimeMode);
+	}
+	static GlobalSettings& Current();
+};

+ 12 - 6
Exporters/FBX/BabylonFbxNative/SkinInfo.cpp

@@ -2,6 +2,7 @@
 #include <iostream>
 #include "SkinInfo.h"
 #include "NodeHelpers.h"
+#include "GlobalSettings.h"
 
 void ComputeBoneHierarchy(const std::vector<FbxNode*>& unsortedFlatListOfNodes,
 	const std::vector<FbxCluster*>& unsortedFlatListOfClusters,
@@ -142,14 +143,17 @@ _node(meshNode), _mesh(meshNode->GetMesh()), _skin(nullptr)
 	auto animStack = _node->GetScene()->GetSrcObject<FbxAnimStack>(0);
 	FbxString animStackName = animStack->GetName();
 	FbxTakeInfo* takeInfo = _node->GetScene()->GetTakeInfo(animStackName);
-	auto startFrame = takeInfo->mLocalTimeSpan.GetStart().GetFrameCount(FbxTime::eFrames24);
-	auto endFrame = takeInfo->mLocalTimeSpan.GetStop().GetFrameCount(FbxTime::eFrames24);
+
+	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;
 
 
 	for (auto ix = 0ll; ix < animLengthInFrame; ix++){
 		FbxTime currTime;
-		currTime.SetFrame(startFrame + ix, FbxTime::eFrames24);
+		currTime.SetFrame(startFrame + ix, animTimeMode);
 
 
 		auto currTransformOffset = meshNode->EvaluateGlobalTransform(currTime) * geometryTransform;
@@ -198,11 +202,13 @@ void SkinInfo::buildBabylonSkeleton(BabylonSkeleton& skel){
 		auto animStack = _node->GetScene()->GetSrcObject<FbxAnimStack>(0);
 		FbxString animStackName = animStack->GetName();
 		FbxTakeInfo* takeInfo = _node->GetScene()->GetTakeInfo(animStackName);
-		auto startFrame = takeInfo->mLocalTimeSpan.GetStart().GetFrameCount(FbxTime::eFrames24);
-		auto endFrame = takeInfo->mLocalTimeSpan.GetStop().GetFrameCount(FbxTime::eFrames24);
+		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;
 
-		auto matrixAnim = std::make_shared<BabylonAnimation<FbxAMatrix>>(BabylonAnimationBase::loopBehavior_Cycle, 24, L"_matrix", L"_matrix", true, 0, animLengthInFrame, true);
+		auto matrixAnim = std::make_shared<BabylonAnimation<FbxAMatrix>>(BabylonAnimationBase::loopBehavior_Cycle, animFrameRate, L"_matrix", L"_matrix", true, 0, animLengthInFrame, true);
 		for (auto& kf : b.keyFrames){
 
 			babylon_animation_key<FbxAMatrix> key;

+ 14 - 19
Exporters/FBX/BabylonFbxNative/babylon_boundingbox.cpp

@@ -2,6 +2,7 @@
 #include "BabylonVertex.h"
 #include <numeric>
 #include <algorithm>
+#include "BabylonCamera.h"
 
 
 babylon_boundingbox::babylon_boundingbox()
@@ -13,6 +14,19 @@ babylon_boundingbox::babylon_boundingbox()
 	  _maxZ(std::numeric_limits<float>::min())
 {
 }
+
+
+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];
+
+}
 void babylon_boundingbox::addPosition(float x, float y, float z){
 	_minX = std::min(x, _minX);
 	_minY = std::min(y, _minY);
@@ -34,22 +48,3 @@ babylon_boundingbox mergeBoundingBoxes(const std::vector<babylon_boundingbox>& b
 	}
 	return result;
 }
-
-babylon_camera buildCameraFromBoundingBox(const babylon_boundingbox& box){
-	babylon_camera result;
-	result.name = "defaultcamera";
-	result.id = "defaultcamera";
-
-	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.maxZ = -5 * result.position.z;
-	result.speed = (-result.position.z - result.target.z) / 10;
-	result.inertia = 0.9f;
-	result.checkCollisions = false;
-	result.applyGravity = false;
-	result.ellipsoid = babylon_vector3(.2f, .9f, .2f);
-	result.rotation = babylon_vector3(0, 0, 0);
-	return result;
-}

+ 86 - 30
Exporters/FBX/FbxExporter/FbxExporter.cpp

@@ -11,6 +11,7 @@
 #include <string>
 #include <sstream>
 #include "..\BabylonFbxNative\BabylonScene.h"
+#include "..\BabylonFbxNative\GlobalSettings.h"
 
 std::string toString(BabylonNodeType type) {
 	switch (type)
@@ -52,10 +53,38 @@ void printNode(BabylonNode& node, int indent = 0) {
 }
 
 
+std::string wstringToUtf8(const std::wstring& src){
+	auto size = WideCharToMultiByte(CP_UTF8, 0, src.c_str(), 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);
+	return result;
+}
+
+bool isNodeOrDescendantVisible(FbxNode* node){
+	if (node == nullptr){
+		return false;
+	}
+	if (node->GetVisibility()){
+		return true;
+	}
+
+	auto childCount = node->GetChildCount();
+	for (auto ix = 0; ix < childCount; ++ix){
+		if (isNodeOrDescendantVisible(node->GetChild(ix))){
+			return true;
+		}
+	}
+	return false;
+}
+
 void exploreMeshes(BabylonScene& scene, BabylonNode& node) {
 	if (node.nodeType() == BabylonNodeType::Skeleton && node.hasOnlySkeletonDescendants()) {
 		return;
 	}
+	if (!node.fbxNode()->GetVisibility()){
+		return;
+	}
 	// append mesh
 	switch (node.nodeType())
 	{
@@ -139,7 +168,7 @@ TextureFormat getInputFormat(const std::wstring& fileName){
 	return TextureFormat::Unkwown;
 }
 
-void exportTexture(TextureFormat outputFormat, const std::shared_ptr<BabylonTexture>& tex, const std::wstring& wOutputPath){
+void exportTexture(const std::shared_ptr<BabylonTexture>& tex, const std::wstring& wOutputPath){
 	if (!tex){
 		return;
 	}
@@ -184,8 +213,8 @@ void exportTexture(TextureFormat outputFormat, const std::shared_ptr<BabylonText
 
 int _tmain(int argc, _TCHAR* argv[])
 {
-	std::wcout << L"Usage : FbxExporter <path to fbx file> <outdir> [jpg|png|dds]" << std::endl;
-	if (argc < 3 || argc >4) {
+	std::wcout << L"Usage : FbxExporter <path to fbx file> <outdir> [/fps:60|30|24]" << std::endl;
+	if (argc < 3) {
 		std::wcerr << L"Invalid argument count" << std::endl;
 		return -1;
 	}
@@ -202,30 +231,29 @@ int _tmain(int argc, _TCHAR* argv[])
 	}
 	std::wstring wOutputPath(argv[2]);
 	CreateDirectory(wOutputPath.c_str(), nullptr);
-	TextureFormat texFormat = TextureFormat::Png;
-	if (argc == 4) {
-		std::wstring wFormat(argv[3]);
-		std::wstring wFormatLower;
-		wFormatLower.reserve(wFormat.size());
-		std::transform(wFormat.begin(), wFormat.end(), std::back_inserter(wFormatLower), towlower);
-		if (wFormatLower == L"jpg") {
-			texFormat = TextureFormat::Jpg;
-		}
-		else if (wFormatLower == L"png") {
-			texFormat = TextureFormat::Png;
-		}
-		else if (wFormatLower == L"dds") {
-			texFormat = TextureFormat::Dds;
-		}
-		else {
-
-			std::wcerr << L"Invalid texture format : " << wFormat << std::endl;
-			return -1;
+	
+	for (int i = 3; i < argc; ++i){
+		std::wstring warg = argv[i];
+		if (warg.find(L"/fps:") == 0){
+			if (warg == L"/fps:60"){
+				GlobalSettings::Current().AnimationsTimeMode = FbxTime::EMode::eFrames60;
+			}
+			else if (warg == L"/fps:30"){
+				GlobalSettings::Current().AnimationsTimeMode = FbxTime::EMode::eFrames30;
+			}
+			else if (warg == L"/fps:24"){
+				GlobalSettings::Current().AnimationsTimeMode = FbxTime::EMode::eFrames24;
+			}
+			else{
+				std::wcerr << L"Unrecognized fps parameter" << std::endl;
+				return -2;
+			}
 		}
+		
 	}
+	
 
-
-	FbxSceneLoader sceneLoader(std::string(wInputPath.begin(), wInputPath.end()));
+	FbxSceneLoader sceneLoader(wstringToUtf8(wInputPath));
 	auto root = sceneLoader.rootNode();
 	printNode(*root);
 
@@ -234,14 +262,42 @@ int _tmain(int argc, _TCHAR* argv[])
 	exploreMeshes(babScene, *root);
 
 	for (auto& mat : babScene.materials()){
-		exportTexture(texFormat, mat.ambientTexture, wOutputPath);
-		exportTexture(texFormat, mat.diffuseTexture, wOutputPath);
-		exportTexture(texFormat, mat.specularTexture, wOutputPath);
-		exportTexture(texFormat, mat.emissiveTexture, wOutputPath);
-		exportTexture(texFormat, mat.reflectionTexture, wOutputPath);
-		exportTexture(texFormat, mat.bumpTexture, wOutputPath);
+		exportTexture(mat.ambientTexture, wOutputPath);
+		exportTexture(mat.diffuseTexture, wOutputPath);
+		exportTexture(mat.specularTexture, wOutputPath);
+		exportTexture(mat.emissiveTexture, wOutputPath);
+		exportTexture(mat.reflectionTexture, wOutputPath);
+		exportTexture(mat.bumpTexture, wOutputPath);
 		
 	}
+	if (babScene.cameras().size() == 0){
+		babylon_boundingbox bbox(sceneLoader.getScene());
+		auto cam = buildCameraFromBoundingBox(bbox);
+		babScene.cameras().push_back(cam);
+		babScene.activeCameraID(cam.id);
+	}
+	if (babScene.lights().size() == 0){
+		babylon_boundingbox bbox(sceneLoader.getScene());
+		BabylonLight light;
+		light.diffuse = babylon_vector3(1, 1, 1);
+		light.specular = babylon_vector3(1, 1, 1);
+		light.position = babylon_vector3(0,0,0);
+		light.parentId = babScene.activeCameraID();
+		light.type = 0;
+		light.id = L"default_light";
+		light.name = L"default_light";
+		light.intensity = 1;
+		babScene.lights().push_back(light);
+		//	web::json::value defaultLight = web::json::value::object();
+		//	writeVector3(defaultLight, L"diffuse", babylon_vector3(1, 1, 1));
+		//	writeVector3(defaultLight, L"specular", babylon_vector3(1, 1, 1));
+		//	writeVector3(defaultLight, L"position", babylon_vector3(bbox.getMinX()*2, bbox.getMaxY()*2, bbox.getMinZ()*2));
+		//	defaultLight[L"type"] = web::json::value(0);
+		//	defaultLight[L"direction"] = web::json::value::null();
+		//	defaultLight[L"id"] = web::json::value(L"default light");
+		//	defaultLight[L"name"] = web::json::value(L"default light");
+		//	defaultLight[L"intensity"] = web::json::value(1);
+	}
 	/*auto camera = sceneLoader.GetDefaultCamera();
 	auto spaceshipSettings = sceneLoader.getGlobalSettings();
 	FbxMaterialStore materials(wInputDir, wOutputPath, texFormat);

+ 11 - 0
Exporters/FBX/FbxRerouteSkeleton/FbxDeleter.h

@@ -0,0 +1,11 @@
+#pragma once
+#include <fbxsdk.h>
+template <typename T>
+struct FbxBaseDeleter{
+	void operator()(T* fbxObject){
+		fbxObject->Destroy();
+	}
+};
+
+struct FbxManagerDeleter : public FbxBaseDeleter<FbxManager>{};
+struct FbxDeleter : public FbxBaseDeleter<FbxObject>{};

+ 270 - 0
Exporters/FBX/FbxRerouteSkeleton/FbxRerouteSkeleton.cpp

@@ -0,0 +1,270 @@
+// FbxRerouteSkeleton.cpp : Defines the entry point for the console application.
+//
+
+#include "stdafx.h"
+#include <fbxsdk.h>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <Windows.h>
+#include <map>
+#include "FbxDeleter.h"
+#include <memory>
+
+std::string wstringToUtf8(const std::wstring& src){
+	auto size = WideCharToMultiByte(CP_UTF8, 0, src.c_str(), 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);
+	return result;
+}
+
+void populateNodeMap(std::map<std::string, FbxNode*>& m, FbxNode* currNode){
+	if (currNode == nullptr){
+		return;
+	}
+	m[currNode->GetName()] = currNode;
+	for (auto ix = 0; ix < currNode->GetChildCount(); ++ix){
+		populateNodeMap(m, currNode->GetChild(ix));
+	}
+}
+
+struct ScopedScene{
+	FbxScene* scene = nullptr;
+	ScopedScene(FbxManager* mgr) :scene(FbxScene::Create(mgr, "TempScene")){}
+	~ScopedScene(){
+		if (scene){
+			scene->Destroy(true);
+		}
+	}
+};
+
+void DeepClone(FbxNode* n, FbxNode* container){
+	auto cloned = n->Clone(FbxObject::ECloneType::eDeepClone, container);
+	for (auto ix = 0; ix < n->GetChildCount(); ++ix){
+		DeepClone(n->GetChild(ix), (FbxNode*) cloned);
+	}
+}
+
+void importAdditionalFile(FbxScene* globalScene, FbxImporter* importer, const std::string& file){
+	importer->Initialize(file.c_str());
+	ScopedScene tempScene(globalScene->GetFbxManager());
+	importer->Import(tempScene.scene);
+	auto tempRootNode = tempScene.scene->GetRootNode();
+
+	std::vector<FbxNode*> childrenToMove;
+	int lNumChildren = tempRootNode->GetChildCount();
+	for (int i = 0; i < lNumChildren; i++) {
+
+		// Obtain a child node from the currently loaded scene.
+		FbxNode* lChildNode = tempRootNode->GetChild(i);
+
+		if (lChildNode){
+			childrenToMove.push_back(lChildNode);
+		}
+	}
+	for (auto item : childrenToMove){
+		//DeepClone(item, globalScene->GetRootNode());
+		globalScene->GetRootNode()->AddChild(item);
+	}
+
+	// Remove the children from the root node.
+	tempScene.scene->GetRootNode()->DisconnectAllSrcObject();
+
+
+	std::vector<FbxObject* > objsToMove;
+	// Move other objects to the reference scene.
+	int lNumSceneObjects = tempScene.scene->GetSrcObjectCount();
+	for (int i = 0; i < lNumSceneObjects; i++) {
+		FbxObject* lObj = tempScene.scene->GetSrcObject(i);
+		auto isAnimStack = lObj->GetClassId() == FbxAnimStack::ClassId;
+		if (lObj == tempScene.scene->GetRootNode() || *lObj == tempScene.scene->GetGlobalSettings() || isAnimStack){
+			// Don't move the root node or the scene's global settings; these
+			// objects are created for every scene.
+			continue;
+		}
+
+		objsToMove.push_back(lObj);
+	}
+
+	for (auto obj : objsToMove){
+		obj->ConnectDstObject(globalScene);
+	}
+
+	tempScene.scene->DisconnectAllSrcObject();
+}
+
+void patchSkins(FbxNode* currentRoot, const std::map<std::string, FbxNode*>& animatedNodes, const std::string& prefix){
+	auto mesh = currentRoot->GetMesh();
+	if (mesh){
+		auto skinCount = mesh->GetDeformerCount(FbxDeformer::EDeformerType::eSkin);
+		for (auto ix = 0; ix < skinCount; ++ix){
+			auto skin = (FbxSkin*) mesh->GetDeformer(ix, FbxDeformer::EDeformerType::eSkin);
+			if (skin){
+				std::vector<FbxCluster*> replacements;
+				auto clusterCount = skin->GetClusterCount();
+				for (auto clusterIx = 0; clusterIx < clusterCount; ++clusterIx){
+					auto cluster = skin->GetCluster(clusterIx);
+					if (cluster){
+						auto linkNode = cluster->GetLink();
+						if (linkNode){
+							auto candidateName = prefix;
+							candidateName.append(linkNode->GetName());
+							auto found = animatedNodes.find(candidateName);
+							if (found != animatedNodes.end()){
+								FbxCluster* newCluster = FbxCluster::Create(currentRoot->GetScene(), "");
+								newCluster->SetLink(found->second);
+								newCluster->SetLinkMode(cluster->GetLinkMode());
+								FbxAMatrix mat;
+								newCluster->SetTransformAssociateModelMatrix(cluster->GetTransformAssociateModelMatrix(mat));
+								newCluster->SetAssociateModel(cluster->GetAssociateModel());
+								newCluster->SetTransformLinkMatrix(cluster->GetTransformLinkMatrix(mat));
+								newCluster->SetTransformMatrix(cluster->GetTransformMatrix(mat));
+								newCluster->SetTransformParentMatrix(cluster->GetTransformParentMatrix(mat));
+
+								auto indicesAndWeightsCount = cluster->GetControlPointIndicesCount();
+								for (auto ix = 0; ix < indicesAndWeightsCount; ++ix){
+									newCluster->AddControlPointIndex(cluster->GetControlPointIndices()[ix], cluster->GetControlPointWeights()[ix]);
+
+								}
+
+
+								replacements.push_back(newCluster);
+							}
+						}
+					}
+				}
+				if (replacements.size() == clusterCount){
+					while (skin->GetClusterCount()>0){
+						auto oldCluster = skin->GetCluster(skin->GetClusterCount() - 1);
+						skin->RemoveCluster(oldCluster);
+						oldCluster->Destroy();
+					}
+					for (auto c : replacements){
+						skin->AddCluster(c);
+					}
+				}
+				else{
+					for (auto c : replacements){
+						c->Destroy();
+					}
+				}
+			}
+		}
+	}
+
+	for (auto ix = 0; ix < currentRoot->GetChildCount(); ++ix){
+		patchSkins(currentRoot->GetChild(ix), animatedNodes, prefix);
+	}
+}
+
+int _tmain(int argc, _TCHAR* argv [])
+{
+	std::cout << "usage : FbxRerouteSkeleton.exe /m:<origin mesh and skeleton data.fbx> /m:<other origin mesh and skeleton data.fbx> /a:<animated skeleton.fbx> /o:<output fbx> [/prefix:<prefix added to each bone in animated skeleton.fbx>]" << std::endl;
+	std::vector<std::string> meshFiles;
+	std::string skeletonFile;
+	std::string outputPath;
+	std::string prefix;
+	for (auto ix = 1; ix < argc; ++ix){
+		std::wstring warg = argv[ix];
+		if (warg.find(L"/m:") == 0){
+			meshFiles.push_back(wstringToUtf8(warg.substr(3)));
+		}
+		else if (warg.find(L"/a:") == 0)
+		{
+			if (skeletonFile.size()>0){
+
+				std::wcout << L"only one animated skeleton file is allowed" << std::endl;
+				return -2;
+			}
+			skeletonFile = wstringToUtf8(warg.substr(3));
+		}
+		else if (warg.find(L"/o:") == 0){
+			if (outputPath.size() > 0){
+
+				std::wcout << L"only one output file is allowed" << std::endl;
+				return -3;
+			}
+
+			CloseHandle(CreateFile(warg.substr(3).c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr));
+			outputPath = wstringToUtf8(warg.substr(3));
+		}
+		else if (warg.find(L"/prefix:") == 0){
+			if (prefix.size() > 0){
+
+				std::wcout << L"only one prefix is allowed" << std::endl;
+				return -4;
+			}
+			prefix = wstringToUtf8(warg.substr(8));
+		}
+		else{
+			std::wcout << L"unrecognized parameter " << warg << std::endl;
+			return -1;
+		}
+	}
+	if (meshFiles.size() == 0){
+
+		std::wcout << L"no origin mesh file" << std::endl;
+		return -5;
+	}
+	if (skeletonFile.size() == 0){
+
+		std::wcout << L"skeleton file unspecified" << std::endl;
+		return -6;
+	}
+	if (outputPath.size() == 0){
+
+		std::wcout << L"output file unspecified" << std::endl;
+		return -7;
+	}
+
+	auto fbxManager = std::unique_ptr<FbxManager, FbxManagerDeleter>( FbxManager::Create());
+	auto iosettings = std::unique_ptr<FbxIOSettings, FbxDeleter>(FbxIOSettings::Create(fbxManager.get(), IOSROOT));
+
+	iosettings->SetBoolProp(IMP_FBX_MATERIAL, true);
+	iosettings->SetBoolProp(IMP_FBX_TEXTURE, true);
+	iosettings->SetBoolProp(IMP_FBX_LINK, true);
+	iosettings->SetBoolProp(IMP_FBX_SHAPE, true);
+	iosettings->SetBoolProp(IMP_FBX_GOBO, true);
+	iosettings->SetBoolProp(IMP_FBX_ANIMATION, true);
+	iosettings->SetBoolProp(IMP_SKINS, true);
+	iosettings->SetBoolProp(IMP_DEFORMATION, true);
+	iosettings->SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true);
+	iosettings->SetBoolProp(IMP_TAKE, true);
+
+
+	iosettings->SetBoolProp(EXP_FBX_MATERIAL, true);
+	iosettings->SetBoolProp(EXP_FBX_TEXTURE, true);
+	iosettings->SetBoolProp(EXP_MESHPOLY, true);
+	iosettings->SetBoolProp(EXP_FBX_SHAPE, true);
+	iosettings->SetBoolProp(EXP_FBX_GOBO, true);
+	iosettings->SetBoolProp(EXP_FBX_ANIMATION, true);
+	iosettings->SetBoolProp(EXP_SKINS, true);
+	iosettings->SetBoolProp(EXP_DEFORMATION, true);
+	iosettings->SetBoolProp(EXP_FBX_GLOBAL_SETTINGS, true);
+	iosettings->SetBoolProp(EXP_MESHTRIANGLE, true);
+	iosettings->SetBoolProp(EXP_EMBEDTEXTURE, true);
+	fbxManager->SetIOSettings(iosettings.get());
+
+	auto importer = std::unique_ptr<FbxImporter, FbxDeleter> (FbxImporter::Create(fbxManager.get(), "SceneImporter"));
+	importer->Initialize(skeletonFile.c_str(), -1, iosettings.get());
+	auto globalScene = std::unique_ptr<FbxScene, FbxDeleter>(FbxScene::Create(fbxManager.get(), "merged scene"));
+	importer->Import(globalScene.get());
+
+	std::map<std::string, FbxNode*> animatedSkeletonNodesMap;
+	populateNodeMap(animatedSkeletonNodesMap, globalScene->GetRootNode());
+
+	for (auto& f : meshFiles){
+		importAdditionalFile(globalScene.get(), importer.get(), f);
+	}
+
+	patchSkins(globalScene->GetRootNode(), animatedSkeletonNodesMap, prefix);
+
+	auto exporter = std::unique_ptr<FbxExporter, FbxDeleter>(FbxExporter::Create(fbxManager.get(), "SceneExporter"));
+	auto res = exporter->Initialize(outputPath.c_str(), -1, iosettings.get());
+	res = exporter->Export(globalScene.get());
+	auto status = exporter->GetStatus();
+
+	return 0;
+}
+

+ 173 - 0
Exporters/FBX/FbxRerouteSkeleton/FbxRerouteSkeleton.vcxproj

@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{C4B4FC3F-B13B-4919-A412-15CF0C2A1E5C}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>FbxRerouteSkeleton</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <IncludePath>$(SolutionDir)\3rdParty\Fbx2016\include;$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2016\lib\vs2013\x86\debug;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <IncludePath>$(SolutionDir)\3rdParty\Fbx2016\include;$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2016\lib\vs2013\x64\debug;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>$(SolutionDir)\3rdParty\Fbx2016\include;$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2016\lib\vs2013\x86\release;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>$(SolutionDir)\3rdParty\Fbx2016\include;$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)\3rdParty\Fbx2016\lib\vs2013\x64\release;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);</LibraryPath>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>libfbxsdk-md.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>libfbxsdk-md.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>libfbxsdk-md.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>libfbxsdk-md.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="FbxDeleter.h" />
+    <ClInclude Include="stdafx.h" />
+    <ClInclude Include="targetver.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="FbxRerouteSkeleton.cpp" />
+    <ClCompile Include="stdafx.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 39 - 0
Exporters/FBX/FbxRerouteSkeleton/FbxRerouteSkeleton.vcxproj.filters

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="stdafx.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="targetver.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="FbxDeleter.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="stdafx.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="FbxRerouteSkeleton.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>

+ 40 - 0
Exporters/FBX/FbxRerouteSkeleton/ReadMe.txt

@@ -0,0 +1,40 @@
+========================================================================
+    CONSOLE APPLICATION : FbxRerouteSkeleton Project Overview
+========================================================================
+
+AppWizard has created this FbxRerouteSkeleton application for you.
+
+This file contains a summary of what you will find in each of the files that
+make up your FbxRerouteSkeleton application.
+
+
+FbxRerouteSkeleton.vcxproj
+    This is the main project file for VC++ projects generated using an Application Wizard.
+    It contains information about the version of Visual C++ that generated the file, and
+    information about the platforms, configurations, and project features selected with the
+    Application Wizard.
+
+FbxRerouteSkeleton.vcxproj.filters
+    This is the filters file for VC++ projects generated using an Application Wizard. 
+    It contains information about the association between the files in your project 
+    and the filters. This association is used in the IDE to show grouping of files with
+    similar extensions under a specific node (for e.g. ".cpp" files are associated with the
+    "Source Files" filter).
+
+FbxRerouteSkeleton.cpp
+    This is the main application source file.
+
+/////////////////////////////////////////////////////////////////////////////
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+    These files are used to build a precompiled header (PCH) file
+    named FbxRerouteSkeleton.pch and a precompiled types file named StdAfx.obj.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" comments to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////

+ 8 - 0
Exporters/FBX/FbxRerouteSkeleton/stdafx.cpp

@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// FbxRerouteSkeleton.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file

+ 15 - 0
Exporters/FBX/FbxRerouteSkeleton/stdafx.h

@@ -0,0 +1,15 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#include <stdio.h>
+#include <tchar.h>
+
+
+
+// TODO: reference additional headers your program requires here

+ 8 - 0
Exporters/FBX/FbxRerouteSkeleton/targetver.h

@@ -0,0 +1,8 @@
+#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#include <SDKDDKVer.h>