ModelResource.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Resource/ModelResource.h>
  6. #include <AnKi/Resource/ResourceManager.h>
  7. #include <AnKi/Resource/MeshResource.h>
  8. #include <AnKi/Util/Xml.h>
  9. #include <AnKi/Util/Logger.h>
  10. namespace anki
  11. {
  12. static Bool attributeIsRequired(VertexAttributeId loc, Pass pass, Bool hasSkin)
  13. {
  14. if(pass == Pass::GB || pass == Pass::FS)
  15. {
  16. return true;
  17. }
  18. else if(!hasSkin)
  19. {
  20. return loc == VertexAttributeId::POSITION;
  21. }
  22. else
  23. {
  24. return loc == VertexAttributeId::POSITION || loc == VertexAttributeId::BONE_INDICES
  25. || loc == VertexAttributeId::BONE_WEIGHTS;
  26. }
  27. }
  28. void ModelPatch::getRenderingInfo(const RenderingKey& key, ModelRenderingInfo& inf) const
  29. {
  30. ANKI_ASSERT(!(!m_model->supportsSkinning() && key.isSkinned()));
  31. const U32 meshLod = min<U32>(key.getLod(), m_meshLodCount - 1);
  32. // Vertex attributes & bindings
  33. {
  34. U32 bufferBindingVisitedMask = 0;
  35. Array<U32, MAX_VERTEX_ATTRIBUTES> realBufferBindingToVirtual;
  36. inf.m_vertexAttributeCount = 0;
  37. inf.m_vertexBufferBindingCount = 0;
  38. for(VertexAttributeId loc : EnumIterable<VertexAttributeId>())
  39. {
  40. if(!m_presentVertexAttributes.get(loc) || !attributeIsRequired(loc, key.getPass(), key.isSkinned()))
  41. {
  42. continue;
  43. }
  44. // Attribute
  45. ModelVertexAttribute& outAttribInfo = inf.m_vertexAttributes[inf.m_vertexAttributeCount++];
  46. outAttribInfo.m_location = loc;
  47. outAttribInfo.m_bufferBinding = m_vertexAttributeInfos[loc].m_bufferBinding;
  48. outAttribInfo.m_relativeOffset = m_vertexAttributeInfos[loc].m_relativeOffset;
  49. outAttribInfo.m_format = m_vertexAttributeInfos[loc].m_format;
  50. // Binding. Also, remove any holes in the bindings
  51. if(!(bufferBindingVisitedMask & (1 << outAttribInfo.m_bufferBinding)))
  52. {
  53. bufferBindingVisitedMask |= 1 << outAttribInfo.m_bufferBinding;
  54. ModelVertexBufferBinding& outBinding = inf.m_vertexBufferBindings[inf.m_vertexBufferBindingCount];
  55. const VertexBufferInfo& inBinding = m_vertexBufferInfos[meshLod][outAttribInfo.m_bufferBinding];
  56. outBinding.m_buffer = inBinding.m_buffer;
  57. ANKI_ASSERT(outBinding.m_buffer.isCreated());
  58. outBinding.m_offset = inBinding.m_offset;
  59. ANKI_ASSERT(outBinding.m_offset != MAX_PTR_SIZE);
  60. outBinding.m_stride = inBinding.m_stride;
  61. ANKI_ASSERT(outBinding.m_stride != MAX_PTR_SIZE);
  62. realBufferBindingToVirtual[outAttribInfo.m_bufferBinding] = inf.m_vertexBufferBindingCount;
  63. ++inf.m_vertexBufferBindingCount;
  64. }
  65. // Change the binding of the attrib
  66. outAttribInfo.m_bufferBinding = realBufferBindingToVirtual[outAttribInfo.m_bufferBinding];
  67. }
  68. ANKI_ASSERT(inf.m_vertexAttributeCount != 0 && inf.m_vertexBufferBindingCount != 0);
  69. }
  70. // Index buff
  71. inf.m_indexBuffer = m_indexBufferInfos[meshLod].m_buffer;
  72. inf.m_indexBufferOffset = 0;
  73. inf.m_indexCount = m_indexBufferInfos[meshLod].m_indexCount;
  74. inf.m_firstIndex = m_indexBufferInfos[meshLod].m_firstIndex;
  75. inf.m_indexType = m_indexType;
  76. // Get program
  77. {
  78. RenderingKey mtlKey = key;
  79. mtlKey.setLod(min(key.getLod(), m_mtl->getLodCount() - 1));
  80. const MaterialVariant& variant = m_mtl->getOrCreateVariant(mtlKey);
  81. inf.m_program = variant.getShaderProgram();
  82. if(m_mtl->supportsSkinning())
  83. {
  84. inf.m_boneTransformsBinding = m_mtl->getBoneTransformsStorageBlockBinding();
  85. inf.m_prevFrameBoneTransformsBinding = m_mtl->getPrevFrameBoneTransformsStorageBlockBinding();
  86. }
  87. else
  88. {
  89. inf.m_boneTransformsBinding = inf.m_prevFrameBoneTransformsBinding = MAX_U32;
  90. }
  91. }
  92. }
  93. void ModelPatch::getRayTracingInfo(U32 lod, ModelRayTracingInfo& info) const
  94. {
  95. ANKI_ASSERT(m_mtl->getSupportedRayTracingTypes() != RayTypeBit::NONE);
  96. info.m_grObjectReferenceCount = 0;
  97. memset(&info.m_descriptor, 0, sizeof(info.m_descriptor));
  98. // Mesh
  99. const MeshResourcePtr& mesh = m_meshes[min(U32(m_meshLodCount - 1), lod)];
  100. info.m_bottomLevelAccelerationStructure = mesh->getBottomLevelAccelerationStructure();
  101. info.m_descriptor.m_mesh = mesh->getMeshGpuDescriptor();
  102. info.m_grObjectReferences[info.m_grObjectReferenceCount++] = mesh->getIndexBuffer();
  103. info.m_grObjectReferences[info.m_grObjectReferenceCount++] = mesh->getVertexBuffer();
  104. // Material
  105. info.m_descriptor.m_material = m_mtl->getMaterialGpuDescriptor();
  106. for(RayType rayType : EnumIterable<RayType>())
  107. {
  108. if(!!(m_mtl->getSupportedRayTracingTypes() & RayTypeBit(1 << rayType)))
  109. {
  110. info.m_shaderGroupHandleIndices[rayType] = m_mtl->getShaderGroupHandleIndex(rayType);
  111. }
  112. else
  113. {
  114. info.m_shaderGroupHandleIndices[rayType] = MAX_U32;
  115. }
  116. }
  117. ConstWeakArray<TextureViewPtr> textureViews = m_mtl->getAllTextureViews();
  118. for(U32 i = 0; i < textureViews.getSize(); ++i)
  119. {
  120. info.m_grObjectReferences[info.m_grObjectReferenceCount++] = textureViews[i];
  121. }
  122. }
  123. Error ModelPatch::init(ModelResource* model, ConstWeakArray<CString> meshFNames, const CString& mtlFName,
  124. U32 subMeshIndex, Bool async, ResourceManager* manager)
  125. {
  126. ANKI_ASSERT(meshFNames.getSize() > 0);
  127. #if ANKI_ENABLE_ASSERTIONS
  128. m_model = model;
  129. #endif
  130. // Load material
  131. ANKI_CHECK(manager->loadResource(mtlFName, m_mtl, async));
  132. // Load meshes
  133. m_meshLodCount = 0;
  134. for(U32 lod = 0; lod < meshFNames.getSize(); lod++)
  135. {
  136. ANKI_CHECK(manager->loadResource(meshFNames[lod], m_meshes[lod], async));
  137. // Sanity check
  138. if(lod > 0 && !m_meshes[lod]->isCompatible(*m_meshes[lod - 1]))
  139. {
  140. ANKI_RESOURCE_LOGE("Meshes not compatible");
  141. return Error::USER_DATA;
  142. }
  143. // Submesh index
  144. if(subMeshIndex != MAX_U32 && subMeshIndex >= m_meshes[lod]->getSubMeshCount())
  145. {
  146. ANKI_RESOURCE_LOGE("Wrong subMeshIndex given");
  147. return Error::USER_DATA;
  148. }
  149. ++m_meshLodCount;
  150. }
  151. // Create the cached items
  152. {
  153. // Vertex attributes
  154. for(VertexAttributeId attrib : EnumIterable<VertexAttributeId>())
  155. {
  156. const MeshResource& mesh = *m_meshes[0].get();
  157. const Bool enabled = mesh.isVertexAttributePresent(attrib);
  158. m_presentVertexAttributes.set(U32(attrib), enabled);
  159. if(!enabled)
  160. {
  161. continue;
  162. }
  163. VertexAttributeInfo& outAttribInfo = m_vertexAttributeInfos[attrib];
  164. U32 bufferBinding, relativeOffset;
  165. mesh.getVertexAttributeInfo(attrib, bufferBinding, outAttribInfo.m_format, relativeOffset);
  166. outAttribInfo.m_bufferBinding = bufferBinding & 0xFu;
  167. outAttribInfo.m_relativeOffset = relativeOffset & 0xFFFFFFu;
  168. }
  169. // Vertex buffers
  170. for(U32 lod = 0; lod < m_meshLodCount; ++lod)
  171. {
  172. const MeshResource& mesh = *m_meshes[lod].get();
  173. for(VertexAttributeId attrib : EnumIterable<VertexAttributeId>())
  174. {
  175. if(!m_presentVertexAttributes.get(attrib))
  176. {
  177. continue;
  178. }
  179. VertexBufferInfo& outVertBufferInfo =
  180. m_vertexBufferInfos[lod][m_vertexAttributeInfos[attrib].m_bufferBinding];
  181. if(!outVertBufferInfo.m_buffer.isCreated())
  182. {
  183. PtrSize offset, stride;
  184. mesh.getVertexBufferInfo(m_vertexAttributeInfos[attrib].m_bufferBinding, outVertBufferInfo.m_buffer,
  185. offset, stride);
  186. outVertBufferInfo.m_offset = offset & 0xFFFFFFFFFFFF;
  187. outVertBufferInfo.m_stride = stride & 0xFFFF;
  188. }
  189. }
  190. }
  191. // Index buffer
  192. for(U32 lod = 0; lod < m_meshLodCount; ++lod)
  193. {
  194. const MeshResource& mesh = *m_meshes[lod].get();
  195. IndexBufferInfo& outIndexBufferInfo = m_indexBufferInfos[lod];
  196. if(subMeshIndex == MAX_U32)
  197. {
  198. IndexType indexType;
  199. PtrSize offset;
  200. mesh.getIndexBufferInfo(outIndexBufferInfo.m_buffer, offset, outIndexBufferInfo.m_indexCount,
  201. indexType);
  202. ANKI_ASSERT(offset == 0);
  203. m_indexType = indexType;
  204. outIndexBufferInfo.m_firstIndex = 0;
  205. }
  206. else
  207. {
  208. IndexType indexType;
  209. PtrSize offset;
  210. mesh.getIndexBufferInfo(outIndexBufferInfo.m_buffer, offset, outIndexBufferInfo.m_indexCount,
  211. indexType);
  212. ANKI_ASSERT(offset == 0);
  213. m_indexType = indexType;
  214. Aabb aabb;
  215. mesh.getSubMeshInfo(subMeshIndex, outIndexBufferInfo.m_firstIndex, outIndexBufferInfo.m_indexCount,
  216. aabb);
  217. }
  218. }
  219. }
  220. return Error::NONE;
  221. }
  222. ModelResource::ModelResource(ResourceManager* manager)
  223. : ResourceObject(manager)
  224. {
  225. }
  226. ModelResource::~ModelResource()
  227. {
  228. auto alloc = getAllocator();
  229. m_modelPatches.destroy(alloc);
  230. }
  231. Error ModelResource::load(const ResourceFilename& filename, Bool async)
  232. {
  233. auto alloc = getAllocator();
  234. // Load
  235. //
  236. XmlElement el;
  237. XmlDocument doc;
  238. ANKI_CHECK(openFileParseXml(filename, doc));
  239. XmlElement rootEl;
  240. ANKI_CHECK(doc.getChildElement("model", rootEl));
  241. // <modelPatches>
  242. XmlElement modelPatchesEl;
  243. ANKI_CHECK(rootEl.getChildElement("modelPatches", modelPatchesEl));
  244. XmlElement modelPatchEl;
  245. ANKI_CHECK(modelPatchesEl.getChildElement("modelPatch", modelPatchEl));
  246. // Count
  247. U32 count = 0;
  248. do
  249. {
  250. ++count;
  251. // Move to next
  252. ANKI_CHECK(modelPatchEl.getNextSiblingElement("modelPatch", modelPatchEl));
  253. } while(modelPatchEl);
  254. // Check number of model patches
  255. if(count < 1)
  256. {
  257. ANKI_RESOURCE_LOGE("Zero number of model patches");
  258. return Error::USER_DATA;
  259. }
  260. m_modelPatches.create(alloc, count);
  261. count = 0;
  262. ANKI_CHECK(modelPatchesEl.getChildElement("modelPatch", modelPatchEl));
  263. do
  264. {
  265. U32 subMeshIndex;
  266. Bool subMeshIndexPresent;
  267. ANKI_CHECK(modelPatchEl.getAttributeNumberOptional("subMeshIndex", subMeshIndex, subMeshIndexPresent));
  268. if(!subMeshIndexPresent)
  269. {
  270. subMeshIndex = MAX_U32;
  271. }
  272. XmlElement materialEl;
  273. ANKI_CHECK(modelPatchEl.getChildElement("material", materialEl));
  274. Array<CString, 3> meshesFnames;
  275. U32 meshesCount = 1;
  276. XmlElement meshEl;
  277. ANKI_CHECK(modelPatchEl.getChildElement("mesh", meshEl));
  278. XmlElement meshEl1;
  279. ANKI_CHECK(modelPatchEl.getChildElementOptional("mesh1", meshEl1));
  280. XmlElement meshEl2;
  281. ANKI_CHECK(modelPatchEl.getChildElementOptional("mesh2", meshEl2));
  282. ANKI_CHECK(meshEl.getText(meshesFnames[0]));
  283. if(meshEl1)
  284. {
  285. ++meshesCount;
  286. ANKI_CHECK(meshEl1.getText(meshesFnames[1]));
  287. }
  288. if(meshEl2)
  289. {
  290. ++meshesCount;
  291. ANKI_CHECK(meshEl2.getText(meshesFnames[2]));
  292. }
  293. CString cstr;
  294. ANKI_CHECK(materialEl.getText(cstr));
  295. ANKI_CHECK(m_modelPatches[count].init(this, ConstWeakArray<CString>(&meshesFnames[0], meshesCount), cstr,
  296. subMeshIndex, async, &getManager()));
  297. if(count > 0 && m_modelPatches[count].supportsSkinning() != m_modelPatches[count - 1].supportsSkinning())
  298. {
  299. ANKI_RESOURCE_LOGE("All model patches should support skinning or all shouldn't support skinning");
  300. return Error::USER_DATA;
  301. }
  302. m_skinning = m_modelPatches[count].supportsSkinning();
  303. // Move to next
  304. ANKI_CHECK(modelPatchEl.getNextSiblingElement("modelPatch", modelPatchEl));
  305. ++count;
  306. } while(modelPatchEl);
  307. ANKI_ASSERT(count == m_modelPatches.getSize());
  308. // Calculate compound bounding volume
  309. m_boundingVolume = m_modelPatches[0].m_meshes[0]->getBoundingShape();
  310. for(auto it = m_modelPatches.getBegin() + 1; it != m_modelPatches.getEnd(); ++it)
  311. {
  312. m_boundingVolume = m_boundingVolume.getCompoundShape((*it).m_meshes[0]->getBoundingShape());
  313. }
  314. return Error::NONE;
  315. }
  316. } // end namespace anki