BabylonMaterial.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  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(BabylonMaterial && moved) :
  190. name(std::move(moved.name)),
  191. id(std::move(moved.id)),
  192. backFaceCulling(std::move(moved.backFaceCulling)),
  193. wireframe(std::move(moved.wireframe)),
  194. ambient(std::move(moved.ambient)),
  195. diffuse(std::move(moved.diffuse)),
  196. specular(std::move(moved.specular)),
  197. emissive(std::move(moved.emissive)),
  198. specularPower(std::move(moved.specularPower)),
  199. alpha(std::move(moved.alpha)),
  200. diffuseTexture(std::move(moved.diffuseTexture)),
  201. ambientTexture(std::move(moved.ambientTexture)),
  202. opacityTexture(std::move(moved.opacityTexture)),
  203. reflectionTexture(std::move(moved.reflectionTexture)),
  204. emissiveTexture(std::move(moved.emissiveTexture)),
  205. specularTexture(std::move(moved.specularTexture)),
  206. bumpTexture(std::move(moved.bumpTexture))
  207. {
  208. }
  209. BabylonMaterial::~BabylonMaterial()
  210. {
  211. }
  212. BabylonMultiMaterial::BabylonMultiMaterial(BabylonMultiMaterial && moved) :
  213. name(std::move(moved.name)),
  214. id(std::move(moved.id)),
  215. materials(std::move(moved.materials))
  216. {
  217. }
  218. web::json::value BabylonMultiMaterial::toJson() const
  219. {
  220. auto jobj = web::json::value::object();
  221. jobj[L"name"] = web::json::value::string(name);
  222. jobj[L"id"] = web::json::value::string(id);
  223. auto jarray = web::json::value::array();
  224. for (auto& mat : materials) {
  225. jarray[jarray.size()] = web::json::value::string(mat);
  226. }
  227. jobj[L"materials"] = jarray;
  228. return jobj;
  229. }
  230. BabylonTexture::BabylonTexture(BabylonTexture && moved) :
  231. name(std::move(moved.name)),
  232. fullPath(std::move(moved.fullPath)),
  233. uvset(std::move(moved.uvset)),
  234. level(std::move(moved.level)),
  235. hasAlpha(std::move(moved.hasAlpha)),
  236. getAlphaFromRGB(std::move(moved.getAlphaFromRGB)),
  237. coordinatesMode(std::move(moved.coordinatesMode)),
  238. isCube(std::move(moved.isCube)),
  239. uOffset(std::move(moved.uOffset)),
  240. vOffset(std::move(moved.vOffset)),
  241. uScale(std::move(moved.uScale)),
  242. vScale(std::move(moved.vScale)),
  243. uAng(std::move(moved.uAng)),
  244. vAng(std::move(moved.vAng)),
  245. wAng(std::move(moved.wAng)),
  246. wrapU(std::move(moved.wrapU)),
  247. wrapV(std::move(moved.wrapV)),
  248. coordinatesIndex(std::move(moved.coordinatesIndex)),
  249. isRenderTarget(std::move(moved.isRenderTarget)),
  250. animations(std::move(moved.animations))
  251. {
  252. }
  253. web::json::value BabylonTexture::toJson(){
  254. auto jobj = web::json::value::object();
  255. jobj[L"name"] = web::json::value::string(name);
  256. jobj[L"level"] = web::json::value::number(level);
  257. jobj[L"hasAlpha"] = web::json::value::boolean(hasAlpha);
  258. jobj[L"getAlphaFromRGB"] = web::json::value::boolean(getAlphaFromRGB);
  259. jobj[L"coordinatesMode"] = web::json::value::number(coordinatesMode);
  260. jobj[L"isCube"] = web::json::value::boolean(isCube);
  261. jobj[L"uOffset"] = web::json::value::number(uOffset);
  262. jobj[L"vOffset"] = web::json::value::number(vOffset);
  263. jobj[L"uScale"] = web::json::value::number(uScale);
  264. jobj[L"vScale"] = web::json::value::number(vScale);
  265. jobj[L"uAng"] = web::json::value::number(uAng);
  266. jobj[L"vAng"] = web::json::value::number(vAng);
  267. jobj[L"wAng"] = web::json::value::number(wAng);
  268. jobj[L"wrapU"] = web::json::value::boolean(wrapU);
  269. jobj[L"wrapV"] = web::json::value::boolean(wrapV);
  270. jobj[L"coordinatesIndex"] = web::json::value::number(coordinatesIndex);
  271. jobj[L"isRenderTarget"] = web::json::value::boolean(isRenderTarget);
  272. auto janims = web::json::value::array();
  273. for (auto& anim : animations) {
  274. janims[janims.size()] = anim->toJson();
  275. }
  276. jobj[L"animations"] = janims;
  277. return jobj;
  278. }
  279. BabylonTexture::BabylonTexture(FbxFileTexture* texture){
  280. fullPath = utf8ToWstring(texture->GetFileName());
  281. auto indexOfLastBackslash = fullPath.find_last_of(L'\\');
  282. name = std::wstring(fullPath.begin() + indexOfLastBackslash + 1, fullPath.end());
  283. auto mappingType = texture->GetMappingType();
  284. switch (mappingType)
  285. {
  286. case fbxsdk::FbxTexture::eNull:
  287. break;
  288. case fbxsdk::FbxTexture::ePlanar:
  289. coordinatesMode = 2;
  290. break;
  291. case fbxsdk::FbxTexture::eSpherical:
  292. coordinatesMode = 1;
  293. break;
  294. case fbxsdk::FbxTexture::eCylindrical:
  295. break;
  296. case fbxsdk::FbxTexture::eBox:
  297. coordinatesMode = 5;
  298. break;
  299. case fbxsdk::FbxTexture::eFace:
  300. break;
  301. case fbxsdk::FbxTexture::eUV:
  302. break;
  303. case fbxsdk::FbxTexture::eEnvironment:
  304. break;
  305. default:
  306. break;
  307. }
  308. auto alphaSource = texture->GetAlphaSource();
  309. switch (alphaSource)
  310. {
  311. case fbxsdk::FbxTexture::eNone:
  312. hasAlpha = false;
  313. getAlphaFromRGB = false;
  314. break;
  315. case fbxsdk::FbxTexture::eRGBIntensity:
  316. hasAlpha = true;
  317. getAlphaFromRGB = true;
  318. break;
  319. case fbxsdk::FbxTexture::eBlack:
  320. hasAlpha = true;
  321. getAlphaFromRGB = false;
  322. break;
  323. default:
  324. break;
  325. }
  326. babylon_vector3 rot = texture->Rotation.Get();
  327. babylon_vector3 scaling = texture->Scaling.Get();
  328. babylon_vector2 trans((float)texture->GetTranslationU(), (float)texture->GetTranslationV());
  329. uOffset = trans.x;
  330. vOffset = trans.y;
  331. uScale = scaling.x;
  332. vScale = scaling.y;
  333. std::string strFileName = texture->GetFileName();
  334. auto lastDot = strFileName.find_last_of('.');
  335. auto ext = strFileName.substr(lastDot);
  336. if (_stricmp(ext.c_str(), ".dds") == 0) {
  337. vScale *= -1;
  338. }
  339. uAng = static_cast<float>(rot.x * Euler2Rad);
  340. vAng = static_cast<float>(rot.y * Euler2Rad);
  341. wAng = static_cast<float>(rot.z * Euler2Rad);
  342. auto uwrapMode = texture->GetWrapModeU();
  343. auto vwrapMode = texture->GetWrapModeV();
  344. wrapU = uwrapMode == FbxTexture::eRepeat;
  345. wrapV = vwrapMode == FbxTexture::eRepeat;
  346. uvset = texture->UVSet.Get();
  347. }