BabylonScene.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. #include "stdafx.h"
  2. #include "BabylonScene.h"
  3. web::json::value BabylonScene::toJson()
  4. {
  5. auto jobj = web::json::value::object();
  6. jobj[L"autoClear"] = web::json::value::boolean(_autoClear);
  7. writeVector3(jobj, L"clearColor", _clearColor);
  8. writeVector3(jobj, L"ambientColor", _ambientColor);
  9. jobj[L"fogMode"] = web::json::value::number(_fogMode);
  10. writeVector3(jobj, L"fogColor", _fogColor);
  11. jobj[L"fogStart"] = web::json::value::number(_fogStart);
  12. jobj[L"fogEnd"] = web::json::value::number(_fogEnd);
  13. jobj[L"fogDensity"] = web::json::value::number(_fogDensity);
  14. writeVector3(jobj, L"gravity", _gravity);
  15. jobj[L"activeCameraID"] = web::json::value::string(_activeCameraID);
  16. auto jcameras = web::json::value::array();
  17. for (auto& cam : _cameras) {
  18. jcameras[jcameras.size()] = cam.toJson();
  19. }
  20. jobj[L"cameras"] = jcameras;
  21. auto jmeshes = web::json::value::array();
  22. for (auto& mesh : _meshes) {
  23. jmeshes[jmeshes.size()] = mesh.toJson();
  24. }
  25. jobj[L"meshes"] = jmeshes;
  26. auto jmats = web::json::value::array();
  27. for (auto& mat : _materials) {
  28. jmats[jmats.size()] = mat.toJson();
  29. }
  30. jobj[L"materials"] = jmats;
  31. auto jmulmats = web::json::value::array();
  32. for (auto& mat : _multiMaterials) {
  33. jmulmats[jmulmats.size()] = mat.toJson();
  34. }
  35. jobj[L"multiMaterials"] = jmulmats;
  36. auto jlights = web::json::value::array();
  37. for (auto& light : _lights) {
  38. jlights[jlights.size()] = light.toJson();
  39. }
  40. jobj[L"lights"] = jlights;
  41. auto jskeletons = web::json::value::array();
  42. for (auto& skel : _skeletons){
  43. jskeletons[jskeletons.size()] = skel->toJson();
  44. }
  45. jobj[L"skeletons"] = jskeletons;
  46. auto jshadowGenerators = web::json::value::array();
  47. for (auto& sg : _shadowGenerators) {
  48. jshadowGenerators[jshadowGenerators.size()] = sg->toJson();
  49. }
  50. jobj[L"shadowGenerators"] = jshadowGenerators;
  51. return jobj;
  52. }
  53. BabylonScene::BabylonScene() :
  54. _autoClear(true),
  55. _clearColor(.2f, .2f, .3f),
  56. _ambientColor(0,0,0),
  57. _gravity(0,0,-.9f)
  58. {
  59. }
  60. BabylonScene::BabylonScene(BabylonNode & rootNode, bool skipEmptyNodes) :
  61. _autoClear(true),
  62. _clearColor(.2f, .2f, .3f),
  63. _ambientColor(0, 0, 0),
  64. _gravity(0, 0, -.9f)
  65. {
  66. exploreNodes(rootNode, skipEmptyNodes);
  67. if (_cameras.size() == 0) {
  68. babylon_boundingbox bbox(rootNode.fbxNode()->GetScene());
  69. auto cam = buildCameraFromBoundingBox(bbox);
  70. _activeCameraID = cam.id;
  71. _cameras.push_back(std::move(cam));
  72. }
  73. if (_lights.size() == 0) {
  74. BabylonLight light;
  75. light.diffuse = babylon_vector3(1, 1, 1);
  76. light.specular = babylon_vector3(1, 1, 1);
  77. light.position = babylon_vector3(0, 0, 0);
  78. light.parentId = _activeCameraID;
  79. light.type = 0;
  80. light.id = L"default_light";
  81. light.name = L"default_light";
  82. light.intensity = 1;
  83. _lights.push_back(std::move(light));
  84. }
  85. }
  86. BabylonScene::BabylonScene(BabylonScene && moved) :
  87. _autoClear(std::move(moved._autoClear)),
  88. _clearColor(std::move(moved._clearColor)),
  89. _ambientColor(std::move(moved._ambientColor)),
  90. _fogMode(std::move(moved._fogMode)),
  91. _fogColor(std::move(moved._fogColor)),
  92. _fogStart(std::move(moved._fogStart)),
  93. _fogEnd(std::move(moved._fogEnd)),
  94. _fogDensity(std::move(moved._fogDensity)),
  95. _gravity(std::move(moved._gravity)),
  96. _cameras(std::move(moved._cameras)),
  97. _activeCameraID(std::move(moved._activeCameraID)),
  98. _meshes(std::move(moved._meshes)),
  99. _materials(std::move(moved._materials)),
  100. _multiMaterials(std::move(moved._multiMaterials)),
  101. _lights(std::move(moved._lights)),
  102. _shadowGenerators(std::move(moved._shadowGenerators)),
  103. _skeletons(std::move(moved._skeletons))
  104. {
  105. }
  106. BabylonScene::~BabylonScene()
  107. {
  108. }
  109. void fixupTextureCoordinateIndices(BabylonMaterial& mat, BabylonMesh& mesh) {
  110. std::vector<std::shared_ptr<BabylonTexture>> textures;
  111. if (mat.ambientTexture) {
  112. textures.push_back(mat.ambientTexture);
  113. }
  114. if (mat.diffuseTexture) {
  115. textures.push_back(mat.diffuseTexture);
  116. }
  117. if (mat.specularTexture) {
  118. textures.push_back(mat.specularTexture);
  119. }
  120. if (mat.emissiveTexture) {
  121. textures.push_back(mat.emissiveTexture);
  122. }
  123. if (mat.reflectionTexture) {
  124. textures.push_back(mat.reflectionTexture);
  125. }
  126. if (mat.bumpTexture) {
  127. textures.push_back(mat.bumpTexture);
  128. }
  129. for (auto& tex : textures) {
  130. auto found = std::find(mesh.uvsets.begin(), mesh.uvsets.end(), tex->uvset);
  131. if (found != mesh.uvsets.end()) {
  132. tex->coordinatesIndex = static_cast<int>(found - mesh.uvsets.begin());
  133. }
  134. }
  135. }
  136. void BabylonScene::exploreNodes(BabylonNode & node, bool skipEmptyNodes)
  137. {
  138. if (node.nodeType() == BabylonNodeType::Skeleton && node.hasOnlySkeletonDescendants()) {
  139. return;
  140. }
  141. if (skipEmptyNodes && node.isEmptySkeletonOrEmptyMeshRecursive()) {
  142. return;
  143. }
  144. // append mesh
  145. switch (node.nodeType())
  146. {
  147. case BabylonNodeType::Empty:
  148. case BabylonNodeType::Mesh:
  149. case BabylonNodeType::Skeleton:
  150. {
  151. BabylonMesh mesh(&node);
  152. auto matCount = node.fbxNode()->GetMaterialCount();
  153. BabylonMultiMaterial multiMat;
  154. for (auto i = 0; i < matCount; ++i) {
  155. auto mat = node.fbxNode()->GetMaterial(i);
  156. if (mat) {
  157. auto id = getMaterialId(mat);
  158. auto existing = std::find_if(_materials.begin(), _materials.end(), [id](const BabylonMaterial& e) {
  159. return e.id == id;
  160. });
  161. if (existing == _materials.end()) {
  162. auto babMat = BabylonMaterial(mat);
  163. fixupTextureCoordinateIndices(babMat, mesh);
  164. _materials.push_back(std::move(babMat));
  165. }
  166. multiMat.materials.push_back(id);
  167. }
  168. }
  169. if (mesh.associatedSkeleton) {
  170. mesh.associatedSkeleton->id = static_cast<int>(_skeletons.size() + 1);
  171. mesh.skeletonId(static_cast<int>(_skeletons.size() + 1));
  172. _skeletons.push_back(mesh.associatedSkeleton);
  173. }
  174. if (multiMat.materials.size() > 0) {
  175. multiMat.id = mesh.id();
  176. multiMat.name = mesh.name();
  177. mesh.materialId(multiMat.id);
  178. _multiMaterials.push_back(std::move(multiMat));
  179. }
  180. _meshes.push_back(std::move(mesh));
  181. }
  182. break;
  183. case BabylonNodeType::Camera:
  184. {
  185. _cameras.emplace_back(node);
  186. if (_cameras.size() == 1) {
  187. activeCameraID(_cameras[0].id);
  188. }
  189. }
  190. break;
  191. case BabylonNodeType::Light:
  192. {
  193. _lights.emplace_back(node);
  194. auto& l = _lights[_lights.size() - 1];
  195. if (l.shadowGenerator) {
  196. _shadowGenerators.push_back(l.shadowGenerator);
  197. }
  198. }
  199. break;
  200. default:
  201. break;
  202. }
  203. for (auto& child : node.children()) {
  204. exploreNodes(child, skipEmptyNodes);
  205. }
  206. }