FbxExporter.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // FbxExporter.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #include "..\BabylonFbxNative\FbxSceneLoader.h"
  5. #include <iostream>
  6. #include <fstream>
  7. #include <Windows.h>
  8. #include <string>
  9. #include <sstream>
  10. #include "..\BabylonFbxNative\BabylonScene.h"
  11. #include "..\BabylonFbxNative\GlobalSettings.h"
  12. #include "..\BabylonFbxNative\StringUtils.h"
  13. void exportTexture(const std::shared_ptr<BabylonTexture>& tex, const std::wstring& wOutputPath){
  14. if (!tex){
  15. return;
  16. }
  17. auto fullPath = tex->fullPath;
  18. for (;;){
  19. auto indexOfSlash = fullPath.find(L'/');
  20. if (indexOfSlash == fullPath.npos){
  21. break;
  22. }
  23. fullPath[indexOfSlash] = L'\\';
  24. }
  25. auto outputPath = tex->name;
  26. for (;;){
  27. auto indexOfSlash = outputPath.find(L'/');
  28. if (indexOfSlash == outputPath.npos){
  29. break;
  30. }
  31. outputPath[indexOfSlash] = L'\\';
  32. }
  33. size_t start = 0;
  34. for (;;){
  35. auto indexOfSlash = outputPath.find(L'\\', start);
  36. if (indexOfSlash == outputPath.npos){
  37. break;
  38. }
  39. auto pathToCreate = wOutputPath;
  40. if (pathToCreate[pathToCreate.size() - 1] != L'\\'){
  41. pathToCreate.push_back(L'\\');
  42. }
  43. pathToCreate.append(outputPath.begin(), outputPath.begin() + indexOfSlash);
  44. CreateDirectory(pathToCreate.c_str(), nullptr);
  45. start = indexOfSlash + 1;
  46. }
  47. auto fullOutputPath = wOutputPath;
  48. if (fullOutputPath[fullOutputPath.size() - 1] != L'\\'){
  49. fullOutputPath.push_back(L'\\');
  50. }
  51. fullOutputPath.append(outputPath);
  52. CopyFile(fullPath.c_str(), fullOutputPath.c_str(), false);
  53. }
  54. int _tmain(int argc, _TCHAR* argv[])
  55. {
  56. std::wcout << L"version : 2015.09.14" << std::endl;
  57. std::wcout << L"Usage : FbxExporter <path to fbx file> <outdir> [/fps:60|30|24] [/skipemptynodes] [/animstack:\"animstack name\"]" << std::endl;
  58. if (argc < 3) {
  59. std::wcerr << L"Invalid argument count" << std::endl;
  60. return -1;
  61. }
  62. std::wstring wInputPath(argv[1]);
  63. std::wstring wInputDir(argv[1]);
  64. std::wstring wInputFileName(argv[1]);
  65. auto lastDirSeparator = wInputDir.find_last_of(L'\\');
  66. if (lastDirSeparator == wInputDir.npos) {
  67. wInputDir = L".";
  68. }
  69. else {
  70. wInputDir.erase(lastDirSeparator);
  71. wInputFileName.erase(0, lastDirSeparator + 1);
  72. }
  73. std::wstring wOutputPath(argv[2]);
  74. CreateDirectory(wOutputPath.c_str(), nullptr);
  75. bool skipEmptyNodes = false;
  76. std::wstring animStackName;
  77. for (int i = 3; i < argc; ++i){
  78. std::wstring warg = argv[i];
  79. if (warg == L"/skipemptynodes") {
  80. skipEmptyNodes = true;
  81. }
  82. else if (warg.find(L"/fps:") == 0){
  83. if (warg == L"/fps:60"){
  84. GlobalSettings::Current().AnimationsTimeMode = FbxTime::EMode::eFrames60;
  85. }
  86. else if (warg == L"/fps:30"){
  87. GlobalSettings::Current().AnimationsTimeMode = FbxTime::EMode::eFrames30;
  88. }
  89. else if (warg == L"/fps:24"){
  90. GlobalSettings::Current().AnimationsTimeMode = FbxTime::EMode::eFrames24;
  91. }
  92. else{
  93. std::wcerr << L"Unrecognized fps parameter" << std::endl;
  94. return -2;
  95. }
  96. }
  97. else if (warg.find(L"/animstack:") == 0) {
  98. animStackName = warg.substr(11);
  99. if (animStackName.size()>0 && animStackName[0] == L'\"') {
  100. animStackName.erase(0, 1);
  101. }
  102. if (animStackName.size() > 0 && animStackName[animStackName.size() - 1] == L'\"') {
  103. animStackName.erase(animStackName.size() - 1, 1);
  104. }
  105. }
  106. }
  107. FbxSceneLoader sceneLoader(wstringToUtf8(wInputPath));
  108. auto animStackCount = sceneLoader.getScene()->GetSrcObjectCount<FbxAnimStack>();
  109. if (animStackName.size() == 0) {
  110. GlobalSettings::Current().AnimStackIndex = 0;
  111. }
  112. else {
  113. for (auto ix = 0; ix < animStackCount; ++ix) {
  114. auto animStack = sceneLoader.getScene()->GetSrcObject<FbxAnimStack>(ix);
  115. if (utf8ToWstring(animStack->GetName()) == animStackName) {
  116. GlobalSettings::Current().AnimStackIndex = ix;
  117. }
  118. }
  119. }
  120. std::wcout << L"Animation stacks : " << std::endl;
  121. for (auto ix = 0; ix < animStackCount; ++ix) {
  122. auto animStack = sceneLoader.getScene()->GetSrcObject<FbxAnimStack>(ix);
  123. if (ix == GlobalSettings::Current().AnimStackIndex) {
  124. std::wcout << L"[X] ";
  125. sceneLoader.getScene()->SetCurrentAnimationStack(animStack);
  126. }
  127. else {
  128. std::wcout << L"[ ] ";
  129. }
  130. std::wcout << utf8ToWstring(animStack->GetName());
  131. auto ts=animStack->GetLocalTimeSpan();
  132. auto start = ts.GetStart();
  133. auto stop = ts.GetStop();
  134. std::wcout << L"(" << start.GetMilliSeconds() << L" - " << stop.GetMilliSeconds() << L")" << std::endl;
  135. }
  136. auto root = sceneLoader.rootNode();
  137. BabylonScene babScene(*root, skipEmptyNodes);
  138. for (auto& mat : babScene.materials()){
  139. exportTexture(mat.ambientTexture, wOutputPath);
  140. exportTexture(mat.diffuseTexture, wOutputPath);
  141. exportTexture(mat.specularTexture, wOutputPath);
  142. exportTexture(mat.emissiveTexture, wOutputPath);
  143. exportTexture(mat.reflectionTexture, wOutputPath);
  144. exportTexture(mat.bumpTexture, wOutputPath);
  145. }
  146. auto json = babScene.toJson();
  147. if (L'\\' != *wOutputPath.crbegin()) {
  148. wOutputPath.append(L"\\");
  149. }
  150. wOutputPath.append(wInputFileName);
  151. auto lastDot = wOutputPath.find_last_of(L'.');
  152. wOutputPath.erase(lastDot);
  153. wOutputPath.append(L".babylon");
  154. DeleteFile(wOutputPath.c_str());
  155. std::ofstream stream(wOutputPath);
  156. json.serialize(stream);
  157. stream.flush();
  158. return 0;
  159. }