BabylonLight.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #include "stdafx.h"
  2. #include "BabylonLight.h"
  3. #include "NodeHelpers.h"
  4. #include "GlobalSettings.h"
  5. web::json::value BabylonLight::toJson() const
  6. {
  7. auto jobj = web::json::value::object();
  8. jobj[L"name"] = web::json::value::string(name);
  9. jobj[L"id"] = web::json::value::string(id);
  10. if (parentId.size() > 0)
  11. jobj[L"parentId"] = web::json::value::string(parentId);
  12. writeVector3(jobj, L"position", position);
  13. writeVector3(jobj, L"direction", direction);
  14. jobj[L"type"] = web::json::value::number(type);
  15. writeVector3(jobj, L"diffuse", diffuse);
  16. writeVector3(jobj, L"specular", specular);
  17. jobj[L"intensity"] = web::json::value::number(intensity);
  18. jobj[L"range"] = web::json::value::number(range);
  19. jobj[L"exponent"] = web::json::value::number(exponent);
  20. jobj[L"angle"] = web::json::value::number(angle);
  21. writeVector3(jobj, L"groundColor", groundColor);
  22. if (animations.size() == 0) {
  23. jobj[L"autoAnimate"] = web::json::value::boolean(false);
  24. jobj[L"autoAnimateLoop"] = web::json::value::boolean(false);
  25. jobj[L"autoAnimateFrom"] = web::json::value::number(0);
  26. jobj[L"autoAnimateTo"] = web::json::value::number(0);
  27. }
  28. else {
  29. jobj[L"autoAnimate"] = web::json::value::boolean(animations[0]->autoAnimate);
  30. jobj[L"autoAnimateLoop"] = web::json::value::boolean(animations[0]->autoAnimateLoop);
  31. jobj[L"autoAnimateFrom"] = web::json::value::number(animations[0]->autoAnimateFrom);
  32. jobj[L"autoAnimateTo"] = web::json::value::number(animations[0]->autoAnimateTo);
  33. }
  34. auto janimations = web::json::value::array();
  35. for (const auto& anim : animations) {
  36. janimations[janimations.size()] = anim->toJson();
  37. }
  38. jobj[L"animations"] = janimations;
  39. auto jarray = web::json::value::array();
  40. for (auto& id : excludedMeshesIds) {
  41. jarray[jarray.size()] = web::json::value::string(id);
  42. }
  43. jobj[L"excludedMeshesIds"] = jarray;
  44. jarray = web::json::value::array();
  45. for (auto& id : includedOnlyMeshesIds) {
  46. jarray[jarray.size()] = web::json::value::string(id);
  47. }
  48. jobj[L"includedOnlyMeshesIds"] = jarray;
  49. return jobj;
  50. }
  51. BabylonLight::BabylonLight() :
  52. diffuse(1, 1, 1),
  53. specular(1, 1, 1)
  54. {
  55. }
  56. BabylonLight::BabylonLight(BabylonNode & babnode) :
  57. diffuse(1, 1, 1),
  58. specular(1, 1, 1)
  59. {
  60. auto node = babnode.fbxNode();
  61. std::string ansiName = node->GetName();
  62. name = std::wstring(ansiName.begin(), ansiName.end());
  63. id = getNodeId(node);
  64. auto parent = node->GetParent();
  65. if (parent) {
  66. parentId = getNodeId(parent);
  67. }
  68. auto localTransform = babnode.GetLocal();
  69. position = localTransform.translation();
  70. auto light = node->GetLight();
  71. switch (light->LightType)
  72. {
  73. case FbxLight::ePoint:
  74. type = type_omni;
  75. break;
  76. case FbxLight::eDirectional:
  77. type = type_direct;
  78. {
  79. FbxDouble3 vDir(0, -1, 0);
  80. FbxAMatrix rotM;
  81. rotM.SetIdentity();
  82. rotM.SetQ(localTransform.fbxrot());
  83. auto transDir = rotM.MultT(vDir);
  84. direction = transDir;
  85. }
  86. break;
  87. case FbxLight::eSpot:
  88. type = type_Spot;
  89. {
  90. FbxDouble3 vDir(0, -1, 0);
  91. FbxAMatrix rotM;
  92. rotM.SetIdentity();
  93. rotM.SetQ(localTransform.fbxrot());
  94. auto transDir = rotM.MultT(vDir);
  95. direction = transDir;
  96. exponent = 1;
  97. angle = static_cast<float>(light->OuterAngle*Euler2Rad);
  98. }
  99. break;
  100. default:
  101. break;
  102. }
  103. diffuse = light->Color.Get();
  104. intensity = static_cast<float>(light->Intensity.Get() / 100.0);
  105. if (light->EnableFarAttenuation.Get()) {
  106. range = static_cast<float>(light->FarAttenuationEnd.Get());
  107. }
  108. auto hasAnimStack = node->GetScene()->GetSrcObjectCount<FbxAnimStack>() > 0;
  109. if (!hasAnimStack) {
  110. return;
  111. }
  112. castShadows = light->CastShadows.Get();
  113. if (castShadows) {
  114. shadowGenerator = std::make_shared<BabylonShadowGenerator>(node);
  115. }
  116. auto animStack = node->GetScene()->GetCurrentAnimationStack();
  117. FbxString animStackName = animStack->GetName();
  118. //FbxTakeInfo* takeInfo = node->GetScene()->GetTakeInfo(animStackName);
  119. auto animTimeMode = GlobalSettings::Current().AnimationsTimeMode;
  120. auto animFrameRate = GlobalSettings::Current().AnimationsFrameRate();
  121. auto startFrame = animStack->GetLocalTimeSpan().GetStart().GetFrameCount(animTimeMode);
  122. auto endFrame = animStack->GetLocalTimeSpan().GetStop().GetFrameCount(animTimeMode);
  123. auto animLengthInFrame = endFrame - startFrame + 1;
  124. auto posAnimName = getNodeId(node);
  125. auto dirAnimName = getNodeId(node);
  126. posAnimName.append(L"_position");
  127. dirAnimName.append(L"_direction");
  128. 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);
  129. 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);
  130. if (node->LclRotation.GetCurveNode() || node->LclTranslation.GetCurveNode()) {
  131. for (auto ix = 0; ix < animLengthInFrame; ix++) {
  132. babylon_animation_key<babylon_vector3> key;
  133. key.frame = ix;
  134. FbxTime currTime;
  135. currTime.SetFrame(startFrame + ix, animTimeMode);
  136. auto currTransform = babnode.GetLocal(currTime);
  137. key.values = currTransform.translation();
  138. posAnim->appendKey(key);
  139. if (type == type_direct || type == type_Spot) {
  140. babylon_animation_key<babylon_vector3> dirkey;
  141. dirkey.frame = ix;
  142. FbxDouble3 vDir(0, -1, 0);
  143. FbxAMatrix rotM;
  144. rotM.SetIdentity();
  145. rotM.SetQ(currTransform.fbxrot());
  146. auto transDir = rotM.MultT(vDir);
  147. dirkey.values = transDir;
  148. dirAnim->appendKey(dirkey);
  149. }
  150. }
  151. }
  152. if (!posAnim->isConstant()) {
  153. animations.push_back(posAnim);
  154. }
  155. if (!dirAnim->isConstant()) {
  156. animations.push_back(dirAnim);
  157. }
  158. }
  159. BabylonLight::BabylonLight(BabylonLight && moved) :
  160. name(std::move(moved.name)),
  161. id(std::move(moved.id)),
  162. parentId(std::move(moved.parentId)),
  163. position(std::move(moved.position)),
  164. direction(std::move(moved.direction)),
  165. type(std::move(moved.type)),
  166. diffuse(std::move(moved.diffuse)),
  167. specular(std::move(moved.specular)),
  168. intensity(std::move(moved.intensity)),
  169. range(std::move(moved.range)),
  170. exponent(std::move(moved.exponent)),
  171. angle(std::move(moved.angle)),
  172. groundColor(std::move(moved.groundColor)),
  173. castShadows(std::move(moved.castShadows)),
  174. includedOnlyMeshesIds(std::move(moved.includedOnlyMeshesIds)),
  175. excludedMeshesIds(std::move(moved.excludedMeshesIds)),
  176. shadowGenerator(std::move(moved.shadowGenerator)),
  177. animations(std::move(moved.animations))
  178. {
  179. }
  180. BabylonLight::~BabylonLight()
  181. {
  182. }
  183. BabylonShadowGenerator::BabylonShadowGenerator(FbxNode * lightNode)
  184. {
  185. auto light = lightNode->GetLight();
  186. lightId = getNodeId(lightNode);
  187. mapSize = 2048;
  188. bias = 0.00005f;
  189. useBlurVarianceShadowMap = true;
  190. blurScale = 2;
  191. blurBoxOffset = 1;
  192. useVarianceShadowMap = false;
  193. usePoissonSampling = false;
  194. auto nodeCount = lightNode->GetScene()->GetNodeCount();
  195. for (auto ix = 0;ix < nodeCount;++ix) {
  196. auto mnode = lightNode->GetScene()->GetNode(ix);
  197. auto mesh = mnode->GetMesh();
  198. if (mesh && mesh->CastShadow.Get()) {
  199. renderList.push_back(getNodeId(mnode));
  200. }
  201. }
  202. }
  203. BabylonShadowGenerator::BabylonShadowGenerator(BabylonShadowGenerator && moved) :
  204. mapSize(std::move(moved.mapSize)),
  205. bias(std::move(moved.bias)),
  206. lightId(std::move(moved.lightId)),
  207. useVarianceShadowMap(std::move(moved.useVarianceShadowMap)),
  208. usePoissonSampling(std::move(moved.usePoissonSampling)),
  209. useBlurVarianceShadowMap(std::move(moved.useBlurVarianceShadowMap)),
  210. blurScale(std::move(moved.blurScale)),
  211. blurBoxOffset(std::move(moved.blurBoxOffset)),
  212. renderList(std::move(moved.renderList))
  213. {
  214. }
  215. web::json::value BabylonShadowGenerator::toJson()
  216. {
  217. auto jobj =web::json::value::object();
  218. jobj[L"mapSize"] = web::json::value::number(mapSize);
  219. jobj[L"lightId"] = web::json::value::string(lightId);
  220. jobj[L"useVarianceShadowMap"] = web::json::value::boolean(useVarianceShadowMap);
  221. jobj[L"usePoissonSampling"] = web::json::value::boolean(usePoissonSampling);
  222. /*jobj[L"useBlurVarianceShadowMap"] = web::json::value::boolean(useBlurVarianceShadowMap);
  223. jobj[L"blurScale"] = web::json::value::number(blurScale);
  224. jobj[L"blurBoxOffset"] = web::json::value::number(blurBoxOffset);*/
  225. auto jarr = web::json::value::array();
  226. for (auto& id : renderList) {
  227. jarr[jarr.size()] = web::json::value::string(id);
  228. }
  229. jobj[L"renderList"] = jarr;
  230. return jobj;
  231. }