BabylonMaterial.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. #include "stdafx.h"
  2. #include "BabylonMaterial.h"
  3. #include <Windows.h>
  4. #include "NodeHelpers.h"
  5. #include "GlobalSettings.h"
  6. web::json::value BabylonMaterial::toJson() const
  7. {
  8. auto jobj = web::json::value::object();
  9. jobj[L"name"] = web::json::value::string(name);
  10. jobj[L"id"] = web::json::value::string(id);
  11. jobj[L"backFaceCulling"] = web::json::value::boolean(backFaceCulling);
  12. jobj[L"wireframe"] = web::json::value::boolean(wireframe);
  13. writeVector3(jobj, L"ambient", ambient);
  14. writeVector3(jobj, L"diffuse", diffuse);
  15. writeVector3(jobj, L"specular", specular);
  16. writeVector3(jobj, L"emissive", emissive);
  17. jobj[L"specularPower"] = web::json::value::number(specularPower);
  18. jobj[L"alpha"] = web::json::value::number(alpha);
  19. if (diffuseTexture){
  20. jobj[L"diffuseTexture"] = diffuseTexture->toJson();
  21. }
  22. if (ambientTexture){
  23. jobj[L"ambientTexture"] = ambientTexture->toJson();
  24. }
  25. if (opacityTexture){
  26. jobj[L"opacityTexture"] = opacityTexture->toJson();
  27. }
  28. if (reflectionTexture){
  29. jobj[L"reflectionTexture"] = reflectionTexture->toJson();
  30. }
  31. if (emissiveTexture){
  32. jobj[L"emissiveTexture"] = emissiveTexture->toJson();
  33. }
  34. if (specularTexture){
  35. jobj[L"specularTexture"] = specularTexture->toJson();
  36. }
  37. if (bumpTexture){
  38. jobj[L"bumpTexture"] = bumpTexture->toJson();
  39. }
  40. // todo : textures
  41. return jobj;
  42. }
  43. BabylonMaterial::BabylonMaterial():
  44. ambient(1,1,1),
  45. diffuse(1,1,1),
  46. specular(1,1,1),
  47. emissive(0,0,0),
  48. specularPower(64),
  49. alpha(1)
  50. {
  51. }
  52. std::wstring utf8ToWstring(const std::string& src){
  53. auto size = MultiByteToWideChar(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), nullptr, 0);
  54. std::wstring result;
  55. result.resize(size, ' ');
  56. MultiByteToWideChar(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), &result[0], size);
  57. return result;
  58. }
  59. FbxDouble3 GetMaterialProperty(const FbxSurfaceMaterial * pMaterial,
  60. const char * pPropertyName,
  61. const char * pFactorPropertyName,
  62. FbxFileTexture*& pTexture)
  63. {
  64. FbxDouble3 lResult(0, 0, 0);
  65. const FbxProperty lProperty = pMaterial->FindProperty(pPropertyName);
  66. const FbxProperty lFactorProperty = pMaterial->FindProperty(pFactorPropertyName);
  67. if (lProperty.IsValid() && lFactorProperty.IsValid())
  68. {
  69. lResult = lProperty.Get<FbxDouble3>();
  70. double lFactor = lFactorProperty.Get<FbxDouble>();
  71. if (lFactor != 1)
  72. {
  73. lResult[0] *= lFactor;
  74. lResult[1] *= lFactor;
  75. lResult[2] *= lFactor;
  76. }
  77. }
  78. if (lProperty.IsValid())
  79. {
  80. const int lTextureCount = lProperty.GetSrcObjectCount<FbxFileTexture>();
  81. if (lTextureCount)
  82. {
  83. FbxFileTexture* lTexture = lProperty.GetSrcObject<FbxFileTexture>();
  84. pTexture = lTexture;
  85. }
  86. }
  87. return lResult;
  88. }
  89. BabylonMaterial::BabylonMaterial(FbxSurfaceMaterial* mat) :
  90. ambient(1, 1, 1),
  91. diffuse(1, 1, 1),
  92. specular(1, 1, 1),
  93. emissive(0, 0, 0),
  94. specularPower(64),
  95. alpha(1){
  96. std::string ansiName = mat->GetName();
  97. name = std::wstring(ansiName.begin(), ansiName.end());
  98. auto rawId = mat->GetUniqueID();
  99. id = getMaterialId(mat);
  100. FbxFileTexture* ambientTex = nullptr;
  101. FbxFileTexture* diffuseTex = nullptr;
  102. FbxFileTexture* specularTex = nullptr;
  103. FbxFileTexture* emissiveTex = nullptr;
  104. FbxFileTexture* reflectionTex = nullptr;
  105. FbxFileTexture* opacityTex = nullptr;
  106. FbxFileTexture* bumpTex = nullptr;
  107. GetMaterialProperty(mat, FbxSurfaceMaterial::sTransparentColor, FbxSurfaceMaterial::sTransparencyFactor, opacityTex)[0];
  108. FbxDouble3 transcolor;
  109. FbxDouble transfactor;
  110. auto transFactorProp = mat->FindProperty(FbxSurfaceMaterial::sTransparencyFactor);
  111. auto transColorProp = mat->FindProperty(FbxSurfaceMaterial::sTransparentColor);
  112. if (transFactorProp.IsValid() && transColorProp.IsValid()){
  113. transfactor = transFactorProp.Get<FbxDouble>();
  114. transcolor = transColorProp.Get<FbxDouble3>();
  115. if (transfactor== 1.0){ // from Maya .fbx
  116. if (transcolor[0] >= DBL_MIN) {
  117. alpha = static_cast<float>(1 - transcolor[0]);
  118. }
  119. else {
  120. alpha = 1;
  121. }
  122. }
  123. else { // from 3dsmax .fbx
  124. if (transfactor>=DBL_MIN){
  125. alpha = static_cast<float>(1 - transfactor);
  126. }
  127. else {
  128. alpha = 1;
  129. }
  130. }
  131. }
  132. ambient = GetMaterialProperty(mat, FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor, ambientTex);
  133. diffuse = GetMaterialProperty(mat, FbxSurfaceMaterial::sDiffuse, FbxSurfaceMaterial::sDiffuseFactor, diffuseTex);
  134. specular = GetMaterialProperty(mat, FbxSurfaceMaterial::sSpecular, FbxSurfaceMaterial::sSpecularFactor, specularTex);
  135. emissive = GetMaterialProperty(mat, FbxSurfaceMaterial::sEmissive, FbxSurfaceMaterial::sEmissiveFactor, emissiveTex);
  136. GetMaterialProperty(mat, FbxSurfaceMaterial::sReflection, FbxSurfaceMaterial::sReflectionFactor, reflectionTex);
  137. auto shininessProp = mat->FindProperty(FbxSurfaceMaterial::sShininess);
  138. if (shininessProp.IsValid()){
  139. specularPower = static_cast<float>(shininessProp.Get<FbxDouble>())*12;
  140. }
  141. auto normalMapProp = mat->FindProperty(FbxSurfaceMaterial::sNormalMap);
  142. if (normalMapProp.IsValid()){
  143. const int lTextureCount = normalMapProp.GetSrcObjectCount<FbxFileTexture>();
  144. if (lTextureCount)
  145. {
  146. FbxFileTexture* lTexture = normalMapProp.GetSrcObject<FbxFileTexture>();
  147. if (lTexture)
  148. {
  149. bumpTex = lTexture;
  150. }
  151. }
  152. }
  153. else{
  154. auto bumpProp = mat->FindProperty(FbxSurfaceMaterial::sBump);
  155. if (bumpProp.IsValid()){
  156. const int lTextureCount = bumpProp.GetSrcObjectCount<FbxFileTexture>();
  157. if (lTextureCount)
  158. {
  159. FbxFileTexture* lTexture = bumpProp.GetSrcObject<FbxFileTexture>();
  160. if (lTexture)
  161. {
  162. bumpTex = lTexture;
  163. }
  164. }
  165. }
  166. }
  167. if (ambientTex){
  168. ambientTexture = std::make_shared<BabylonTexture>(ambientTex);
  169. }
  170. if (diffuseTex){
  171. diffuseTexture = std::make_shared<BabylonTexture>(diffuseTex);
  172. }
  173. if (specularTex){
  174. specularTexture = std::make_shared<BabylonTexture>(specularTex);
  175. }
  176. if (emissiveTex){
  177. emissiveTexture = std::make_shared<BabylonTexture>(emissiveTex);
  178. }
  179. if (reflectionTex){
  180. reflectionTexture = std::make_shared<BabylonTexture>(reflectionTex);
  181. }
  182. if (bumpTex){
  183. bumpTexture = std::make_shared<BabylonTexture>(bumpTex);
  184. }
  185. if (opacityTex){
  186. opacityTexture = std::make_shared<BabylonTexture>(opacityTex);
  187. }
  188. }
  189. BabylonMaterial::~BabylonMaterial()
  190. {
  191. }
  192. web::json::value BabylonMultiMaterial::toJson() const
  193. {
  194. auto jobj = web::json::value::object();
  195. jobj[L"name"] = web::json::value::string(name);
  196. jobj[L"id"] = web::json::value::string(id);
  197. auto jarray = web::json::value::array();
  198. for (auto& mat : materials) {
  199. jarray[jarray.size()] = web::json::value::string(mat);
  200. }
  201. jobj[L"materials"] = jarray;
  202. return jobj;
  203. }
  204. web::json::value BabylonTexture::toJson(){
  205. auto jobj = web::json::value::object();
  206. jobj[L"name"] = web::json::value::string(name);
  207. jobj[L"level"] = web::json::value::number(level);
  208. jobj[L"hasAlpha"] = web::json::value::boolean(hasAlpha);
  209. jobj[L"getAlphaFromRGB"] = web::json::value::boolean(getAlphaFromRGB);
  210. jobj[L"coordinatesMode"] = web::json::value::number(coordinatesMode);
  211. jobj[L"isCube"] = web::json::value::boolean(isCube);
  212. jobj[L"uOffset"] = web::json::value::number(uOffset);
  213. jobj[L"vOffset"] = web::json::value::number(vOffset);
  214. jobj[L"uScale"] = web::json::value::number(uScale);
  215. jobj[L"vScale"] = web::json::value::number(vScale);
  216. jobj[L"uAng"] = web::json::value::number(uAng);
  217. jobj[L"vAng"] = web::json::value::number(vAng);
  218. jobj[L"wAng"] = web::json::value::number(wAng);
  219. jobj[L"wrapU"] = web::json::value::boolean(wrapU);
  220. jobj[L"wrapV"] = web::json::value::boolean(wrapV);
  221. jobj[L"coordinatesIndex"] = web::json::value::number(coordinatesIndex);
  222. jobj[L"isRenderTarget"] = web::json::value::boolean(isRenderTarget);
  223. auto janims = web::json::value::array();
  224. for (auto& anim : animations) {
  225. janims[janims.size()] = anim->toJson();
  226. }
  227. jobj[L"animations"] = janims;
  228. return jobj;
  229. }
  230. BabylonTexture::BabylonTexture(FbxFileTexture* texture){
  231. fullPath = utf8ToWstring(texture->GetFileName());
  232. auto indexOfLastBackslash = fullPath.find_last_of(L'\\');
  233. name = std::wstring(fullPath.begin() + indexOfLastBackslash + 1, fullPath.end());
  234. auto mappingType = texture->GetMappingType();
  235. switch (mappingType)
  236. {
  237. case fbxsdk::FbxTexture::eNull:
  238. break;
  239. case fbxsdk::FbxTexture::ePlanar:
  240. coordinatesMode = 2;
  241. break;
  242. case fbxsdk::FbxTexture::eSpherical:
  243. coordinatesMode = 1;
  244. break;
  245. case fbxsdk::FbxTexture::eCylindrical:
  246. break;
  247. case fbxsdk::FbxTexture::eBox:
  248. coordinatesMode = 5;
  249. break;
  250. case fbxsdk::FbxTexture::eFace:
  251. break;
  252. case fbxsdk::FbxTexture::eUV:
  253. break;
  254. case fbxsdk::FbxTexture::eEnvironment:
  255. break;
  256. default:
  257. break;
  258. }
  259. auto alphaSource = texture->GetAlphaSource();
  260. switch (alphaSource)
  261. {
  262. case fbxsdk::FbxTexture::eNone:
  263. hasAlpha = false;
  264. getAlphaFromRGB = false;
  265. break;
  266. case fbxsdk::FbxTexture::eRGBIntensity:
  267. hasAlpha = true;
  268. getAlphaFromRGB = true;
  269. break;
  270. case fbxsdk::FbxTexture::eBlack:
  271. hasAlpha = true;
  272. getAlphaFromRGB = false;
  273. break;
  274. default:
  275. break;
  276. }
  277. babylon_vector3 rot = texture->Rotation.Get();
  278. babylon_vector3 scaling = texture->Scaling.Get();
  279. babylon_vector2 trans((float)texture->GetTranslationU(), (float)texture->GetTranslationV());
  280. uOffset = trans.x;
  281. vOffset = trans.y;
  282. uScale = scaling.x;
  283. vScale = scaling.y;
  284. uAng = rot.x * Euler2Rad;
  285. vAng = rot.y * Euler2Rad;
  286. wAng = rot.z * Euler2Rad;
  287. auto uwrapMode = texture->GetWrapModeU();
  288. auto vwrapMode = texture->GetWrapModeV();
  289. wrapU = uwrapMode == FbxTexture::eRepeat;
  290. wrapV = vwrapMode == FbxTexture::eRepeat;
  291. }