BabylonMaterial.cpp 11 KB

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