2
0

AssImpMaterialWrapper.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <assimp/scene.h>
  9. #include <assimp/material.h>
  10. #include <AzCore/Debug/Trace.h>
  11. #include <AzCore/Math/Sha1.h>
  12. #include <AzCore/Debug/Trace.h>
  13. #include <AzToolsFramework/Debug/TraceContext.h>
  14. #include <SceneAPI/SDKWrapper/AssImpMaterialWrapper.h>
  15. #include <SceneAPI/SceneCore/Utilities/Reporting.h>
  16. namespace AZ
  17. {
  18. namespace AssImpSDKWrapper
  19. {
  20. AssImpMaterialWrapper::AssImpMaterialWrapper(aiMaterial* aiMaterial)
  21. :m_assImpMaterial(aiMaterial)
  22. {
  23. AZ_Assert(aiMaterial, "Asset Importer Material cannot be null");
  24. }
  25. aiMaterial* AssImpMaterialWrapper::GetAssImpMaterial() const
  26. {
  27. return m_assImpMaterial;
  28. }
  29. AZStd::string AssImpMaterialWrapper::GetName() const
  30. {
  31. return m_assImpMaterial->GetName().C_Str();
  32. }
  33. AZ::u64 AssImpMaterialWrapper::GetUniqueId() const
  34. {
  35. AZStd::string fingerprintString;
  36. fingerprintString.append(GetName());
  37. AZStd::string extraInformation = AZStd::string::format("%i%i%i%i%i%i", m_assImpMaterial->GetTextureCount(aiTextureType_DIFFUSE),
  38. m_assImpMaterial->GetTextureCount(aiTextureType_SPECULAR), m_assImpMaterial->GetTextureCount(aiTextureType_NORMALS), m_assImpMaterial->GetTextureCount(aiTextureType_SHININESS),
  39. m_assImpMaterial->GetTextureCount(aiTextureType_AMBIENT), m_assImpMaterial->GetTextureCount(aiTextureType_EMISSIVE));
  40. fingerprintString.append(extraInformation);
  41. AZ::Sha1 sha;
  42. sha.ProcessBytes(AZStd::as_bytes(AZStd::span(fingerprintString)));
  43. AZ::u32 digest[5]; //sha1 populate a 5 element array of AZ:u32
  44. sha.GetDigest(digest);
  45. return (static_cast<AZ::u64>(digest[0]) << 32) | digest[1];
  46. }
  47. AZ::Vector3 AssImpMaterialWrapper::GetDiffuseColor() const
  48. {
  49. aiColor3D color(1.f, 1.f, 1.f);
  50. if (m_assImpMaterial->Get(AI_MATKEY_COLOR_DIFFUSE, color) == aiReturn::aiReturn_FAILURE)
  51. {
  52. AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Unable to get diffuse property from material %.*s. Using default.\n", AZ_STRING_ARG(GetName()));
  53. }
  54. return AZ::Vector3(color.r, color.g, color.b);
  55. }
  56. AZ::Vector3 AssImpMaterialWrapper::GetSpecularColor() const
  57. {
  58. aiColor3D color(0.f, 0.f, 0.f);
  59. if (m_assImpMaterial->Get(AI_MATKEY_COLOR_SPECULAR, color) == aiReturn::aiReturn_FAILURE)
  60. {
  61. AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Unable to get specular property from material %.*s. Using default.\n", AZ_STRING_ARG(GetName()));
  62. }
  63. return AZ::Vector3(color.r, color.g, color.b);
  64. }
  65. AZ::Vector3 AssImpMaterialWrapper::GetEmissiveColor() const
  66. {
  67. aiColor3D color(0.f, 0.f, 0.f);
  68. if (m_assImpMaterial->Get(AI_MATKEY_COLOR_EMISSIVE, color) == aiReturn::aiReturn_FAILURE)
  69. {
  70. AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Unable to get emissive property from material %.*s. Using default.\n", AZ_STRING_ARG(GetName()));
  71. }
  72. return AZ::Vector3(color.r, color.g, color.b);
  73. }
  74. float AssImpMaterialWrapper::GetOpacity() const
  75. {
  76. float opacity = 1.0f;
  77. if (m_assImpMaterial->Get(AI_MATKEY_OPACITY, opacity) == aiReturn::aiReturn_FAILURE)
  78. {
  79. AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Unable to get opacity from material %.*s. Using default.\n", AZ_STRING_ARG(GetName()));
  80. }
  81. return opacity;
  82. }
  83. float AssImpMaterialWrapper::GetShininess() const
  84. {
  85. float shininess = 0.0f;
  86. if (m_assImpMaterial->Get(AI_MATKEY_SHININESS, shininess) == aiReturn::aiReturn_FAILURE)
  87. {
  88. AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Unable to get shininess from material %.*s. Using default.\n", AZ_STRING_ARG(GetName()));
  89. }
  90. return shininess;
  91. }
  92. AZStd::optional<bool> AssImpMaterialWrapper::GetUseColorMap() const
  93. {
  94. // AssImp stores values as floats, so load as float and convert to bool.
  95. float useMap = 0.0f;
  96. if (m_assImpMaterial->Get(AI_MATKEY_USE_COLOR_MAP, useMap) != aiReturn::aiReturn_FAILURE)
  97. {
  98. return useMap != 0.0f;
  99. }
  100. return AZStd::nullopt;
  101. }
  102. AZStd::optional<AZ::Vector3> AssImpMaterialWrapper::GetBaseColor() const
  103. {
  104. aiColor3D color(1.f, 1.f, 1.f);
  105. if (m_assImpMaterial->Get(AI_MATKEY_BASE_COLOR, color) != aiReturn::aiReturn_FAILURE)
  106. {
  107. return AZ::Vector3(color.r, color.g, color.b);
  108. }
  109. return AZStd::nullopt;
  110. }
  111. AZStd::optional<bool> AssImpMaterialWrapper::GetUseMetallicMap() const
  112. {
  113. // AssImp stores values as floats, so load as float and convert to bool.
  114. float useMap = 0.0f;
  115. if (m_assImpMaterial->Get(AI_MATKEY_USE_METALLIC_MAP, useMap) != aiReturn::aiReturn_FAILURE)
  116. {
  117. return useMap != 0.0f;
  118. }
  119. return AZStd::nullopt;
  120. }
  121. AZStd::optional<float> AssImpMaterialWrapper::GetMetallicFactor() const
  122. {
  123. float metallic = 0.0f;
  124. if (m_assImpMaterial->Get(AI_MATKEY_METALLIC_FACTOR, metallic) != aiReturn::aiReturn_FAILURE)
  125. {
  126. return metallic;
  127. }
  128. return AZStd::nullopt;
  129. }
  130. AZStd::optional<bool> AssImpMaterialWrapper::GetUseRoughnessMap() const
  131. {
  132. // AssImp stores values as floats, so load as float and convert to bool.
  133. float useMap = 0.0f;
  134. if (m_assImpMaterial->Get(AI_MATKEY_USE_ROUGHNESS_MAP, useMap) != aiReturn::aiReturn_FAILURE)
  135. {
  136. return useMap != 0.0f;
  137. }
  138. return AZStd::nullopt;
  139. }
  140. AZStd::optional<float> AssImpMaterialWrapper::GetRoughnessFactor() const
  141. {
  142. float roughness = 0.0f;
  143. if (m_assImpMaterial->Get(AI_MATKEY_ROUGHNESS_FACTOR, roughness) != aiReturn::aiReturn_FAILURE)
  144. {
  145. return roughness;
  146. }
  147. return AZStd::nullopt;
  148. }
  149. AZStd::optional<bool> AssImpMaterialWrapper::GetUseEmissiveMap() const
  150. {
  151. // AssImp stores values as floats, so load as float and convert to bool.
  152. float useMap = 0.0f;
  153. if (m_assImpMaterial->Get(AI_MATKEY_USE_EMISSIVE_MAP, useMap) != aiReturn::aiReturn_FAILURE)
  154. {
  155. return useMap != 0.0f;
  156. }
  157. return AZStd::nullopt;
  158. }
  159. AZStd::optional<float> AssImpMaterialWrapper::GetEmissiveIntensity() const
  160. {
  161. float emissiveIntensity = 0.0f;
  162. if (m_assImpMaterial->Get(AI_MATKEY_EMISSIVE_INTENSITY, emissiveIntensity) != aiReturn::aiReturn_FAILURE)
  163. {
  164. return emissiveIntensity;
  165. }
  166. return AZStd::nullopt;
  167. }
  168. AZStd::optional<bool> AssImpMaterialWrapper::GetUseAOMap() const
  169. {
  170. // AssImp stores values as floats, so load as float and convert to bool.
  171. float useMap = 0.0f;
  172. if (m_assImpMaterial->Get(AI_MATKEY_USE_AO_MAP, useMap) != aiReturn::aiReturn_FAILURE)
  173. {
  174. return useMap != 0.0f;
  175. }
  176. return AZStd::nullopt;
  177. }
  178. AZStd::string AssImpMaterialWrapper::GetTextureFileName(MaterialMapType textureType) const
  179. {
  180. /// Engine currently doesn't support multiple textures. Right now we only use first texture.
  181. unsigned int textureIndex = 0;
  182. aiString absTexturePath;
  183. switch (textureType)
  184. {
  185. case MaterialMapType::Diffuse:
  186. if (m_assImpMaterial->GetTextureCount(aiTextureType_DIFFUSE) > textureIndex)
  187. {
  188. m_assImpMaterial->GetTexture(aiTextureType_DIFFUSE, textureIndex, &absTexturePath);
  189. }
  190. break;
  191. case MaterialMapType::Specular:
  192. if (m_assImpMaterial->GetTextureCount(aiTextureType_SPECULAR) > textureIndex)
  193. {
  194. m_assImpMaterial->GetTexture(aiTextureType_SPECULAR, textureIndex, &absTexturePath);
  195. }
  196. break;
  197. case MaterialMapType::Bump:
  198. if (m_assImpMaterial->GetTextureCount(aiTextureType_HEIGHT) > textureIndex)
  199. {
  200. m_assImpMaterial->GetTexture(aiTextureType_HEIGHT, textureIndex, &absTexturePath);
  201. }
  202. break;
  203. case MaterialMapType::Normal:
  204. if (m_assImpMaterial->GetTextureCount(aiTextureType_NORMALS) > textureIndex)
  205. {
  206. m_assImpMaterial->GetTexture(aiTextureType_NORMALS, textureIndex, &absTexturePath);
  207. }
  208. else if (m_assImpMaterial->GetTextureCount(aiTextureType_NORMAL_CAMERA) > textureIndex)
  209. {
  210. m_assImpMaterial->GetTexture(aiTextureType_NORMAL_CAMERA, textureIndex, &absTexturePath);
  211. }
  212. break;
  213. case MaterialMapType::Metallic:
  214. if (m_assImpMaterial->GetTextureCount(aiTextureType_METALNESS) > textureIndex)
  215. {
  216. m_assImpMaterial->GetTexture(aiTextureType_METALNESS, textureIndex, &absTexturePath);
  217. }
  218. break;
  219. case MaterialMapType::Roughness:
  220. if (m_assImpMaterial->GetTextureCount(aiTextureType_DIFFUSE_ROUGHNESS) > textureIndex)
  221. {
  222. m_assImpMaterial->GetTexture(aiTextureType_DIFFUSE_ROUGHNESS, textureIndex, &absTexturePath);
  223. }
  224. break;
  225. case MaterialMapType::AmbientOcclusion:
  226. if (m_assImpMaterial->GetTextureCount(aiTextureType_AMBIENT_OCCLUSION) > textureIndex)
  227. {
  228. m_assImpMaterial->GetTexture(aiTextureType_AMBIENT_OCCLUSION, textureIndex, &absTexturePath);
  229. }
  230. break;
  231. case MaterialMapType::Emissive:
  232. if (m_assImpMaterial->GetTextureCount(aiTextureType_EMISSION_COLOR) > textureIndex)
  233. {
  234. m_assImpMaterial->GetTexture(aiTextureType_EMISSION_COLOR, textureIndex, &absTexturePath);
  235. }
  236. break;
  237. case MaterialMapType::BaseColor:
  238. if (m_assImpMaterial->GetTextureCount(aiTextureType_BASE_COLOR) > textureIndex)
  239. {
  240. m_assImpMaterial->GetTexture(aiTextureType_BASE_COLOR, textureIndex, &absTexturePath);
  241. }
  242. // If the base color texture isn't available, fall back to using the diffuse texture.
  243. // Before PBR support was added, the renderer just defaulted to using the diffuse texture
  244. // in the base color texture property of the material.
  245. else if (m_assImpMaterial->GetTextureCount(aiTextureType_DIFFUSE) > textureIndex)
  246. {
  247. m_assImpMaterial->GetTexture(aiTextureType_DIFFUSE, textureIndex, &absTexturePath);
  248. }
  249. break;
  250. default:
  251. AZ_TraceContext("Unknown value", aznumeric_cast<int>(textureType));
  252. AZ_TracePrintf(SceneAPI::Utilities::WarningWindow, "Unrecognized MaterialMapType retrieved");
  253. return AZStd::string();
  254. }
  255. return AZStd::string(absTexturePath.C_Str());
  256. }
  257. } // namespace AssImpSDKWrapper
  258. } // namespace AZ