ModelComponent.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. // Copyright (C) 2009-2023, 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/Scene/Components/ModelComponent.h>
  6. #include <AnKi/Scene/SceneNode.h>
  7. #include <AnKi/Scene/SceneGraph.h>
  8. #include <AnKi/Scene/Components/MoveComponent.h>
  9. #include <AnKi/Scene/Components/SkinComponent.h>
  10. #include <AnKi/Resource/ModelResource.h>
  11. #include <AnKi/Resource/ResourceManager.h>
  12. namespace anki {
  13. ModelComponent::ModelComponent(SceneNode* node)
  14. : SceneComponent(node, getStaticClassId())
  15. , m_node(node)
  16. , m_spatial(this)
  17. {
  18. m_gpuSceneTransformsIndex = U32(SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().allocate(
  19. GpuSceneContiguousArrayType::kTransformPairs));
  20. }
  21. ModelComponent::~ModelComponent()
  22. {
  23. GpuSceneMemoryPool::getSingleton().deferredFree(m_gpuSceneUniforms);
  24. for(const PatchInfo& patch : m_patchInfos)
  25. {
  26. if(patch.m_gpuSceneMeshLodsIndex != kMaxU32)
  27. {
  28. SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().deferredFree(
  29. GpuSceneContiguousArrayType::kMeshLods, patch.m_gpuSceneMeshLodsIndex);
  30. }
  31. }
  32. SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().deferredFree(
  33. GpuSceneContiguousArrayType::kTransformPairs, m_gpuSceneTransformsIndex);
  34. m_spatial.removeFromOctree(SceneGraph::getSingleton().getOctree());
  35. }
  36. void ModelComponent::loadModelResource(CString filename)
  37. {
  38. ModelResourcePtr rsrc;
  39. const Error err = ResourceManager::getSingleton().loadResource(filename, rsrc);
  40. if(err)
  41. {
  42. ANKI_SCENE_LOGE("Failed to load model resource");
  43. return;
  44. }
  45. m_dirty = true;
  46. m_model = std::move(rsrc);
  47. const U32 modelPatchCount = m_model->getModelPatches().getSize();
  48. // GPU scene allocations
  49. for(const PatchInfo& patch : m_patchInfos)
  50. {
  51. if(patch.m_gpuSceneMeshLodsIndex != kMaxU32)
  52. {
  53. SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().deferredFree(
  54. GpuSceneContiguousArrayType::kMeshLods, patch.m_gpuSceneMeshLodsIndex);
  55. }
  56. }
  57. m_patchInfos.resize(modelPatchCount);
  58. for(U32 i = 0; i < modelPatchCount; ++i)
  59. {
  60. m_patchInfos[i].m_gpuSceneMeshLodsIndex =
  61. U32(SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().allocate(
  62. GpuSceneContiguousArrayType::kMeshLods));
  63. }
  64. U32 uniformsSize = 0;
  65. for(U32 i = 0; i < modelPatchCount; ++i)
  66. {
  67. m_patchInfos[i].m_gpuSceneUniformsOffset = uniformsSize;
  68. const U32 size = U32(m_model->getModelPatches()[i].getMaterial()->getPrefilledLocalUniforms().getSizeInBytes());
  69. ANKI_ASSERT((size % 4) == 0);
  70. uniformsSize += size;
  71. }
  72. GpuSceneMemoryPool::getSingleton().deferredFree(m_gpuSceneUniforms);
  73. GpuSceneMemoryPool::getSingleton().allocate(uniformsSize, 4, m_gpuSceneUniforms);
  74. for(U32 i = 0; i < modelPatchCount; ++i)
  75. {
  76. m_patchInfos[i].m_gpuSceneUniformsOffset += U32(m_gpuSceneUniforms.m_offset);
  77. }
  78. // Some other per-patch init
  79. m_presentRenderingTechniques = RenderingTechniqueBit::kNone;
  80. m_castsShadow = false;
  81. for(U32 i = 0; i < modelPatchCount; ++i)
  82. {
  83. m_patchInfos[i].m_techniques = m_model->getModelPatches()[i].getMaterial()->getRenderingTechniques();
  84. m_castsShadow = m_castsShadow || m_model->getModelPatches()[i].getMaterial()->castsShadow();
  85. m_presentRenderingTechniques |= m_model->getModelPatches()[i].getMaterial()->getRenderingTechniques();
  86. }
  87. }
  88. Error ModelComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
  89. {
  90. if(!isEnabled()) [[unlikely]]
  91. {
  92. updated = false;
  93. return Error::kNone;
  94. }
  95. const Bool resourceUpdated = m_dirty;
  96. m_dirty = false;
  97. const Bool moved = info.m_node->movedThisFrame() || m_firstTimeUpdate;
  98. const Bool movedLastFrame = m_movedLastFrame || m_firstTimeUpdate;
  99. m_firstTimeUpdate = false;
  100. m_movedLastFrame = moved;
  101. updated = resourceUpdated || moved || movedLastFrame;
  102. // Upload mesh LODs and uniforms
  103. if(resourceUpdated) [[unlikely]]
  104. {
  105. // Upload the mesh views
  106. const U32 modelPatchCount = m_model->getModelPatches().getSize();
  107. for(U32 i = 0; i < modelPatchCount; ++i)
  108. {
  109. const ModelPatch& patch = m_model->getModelPatches()[i];
  110. const MeshResource& mesh = *patch.getMesh();
  111. Array<GpuSceneMeshLod, kMaxLodCount> meshLods;
  112. for(U32 l = 0; l < mesh.getLodCount(); ++l)
  113. {
  114. GpuSceneMeshLod& meshLod = meshLods[l];
  115. meshLod = {};
  116. meshLod.m_positionScale = mesh.getPositionsScale();
  117. meshLod.m_positionTranslation = mesh.getPositionsTranslation();
  118. for(VertexStreamId stream = VertexStreamId::kPosition; stream <= VertexStreamId::kBoneWeights; ++stream)
  119. {
  120. if(!mesh.isVertexStreamPresent(stream))
  121. {
  122. continue;
  123. }
  124. PtrSize offset;
  125. U32 vertCount;
  126. mesh.getVertexStreamInfo(l, stream, offset, vertCount);
  127. const PtrSize elementSize = getFormatInfo(kMeshRelatedVertexStreamFormats[stream]).m_texelSize;
  128. ANKI_ASSERT((offset % elementSize) == 0);
  129. meshLod.m_vertexOffsets[U32(stream)] = U32(offset / elementSize);
  130. }
  131. U32 firstIndex;
  132. U32 indexCount;
  133. Aabb aabb;
  134. mesh.getSubMeshInfo(l, i, firstIndex, indexCount, aabb);
  135. PtrSize offset;
  136. IndexType indexType;
  137. mesh.getIndexBufferInfo(l, offset, indexCount, indexType);
  138. meshLod.m_indexBufferOffset = U32(offset) / getIndexSize(indexType) + firstIndex;
  139. meshLod.m_indexCount = indexCount;
  140. }
  141. // Copy the last LOD to the rest just in case
  142. for(U32 l = mesh.getLodCount(); l < kMaxLodCount; ++l)
  143. {
  144. meshLods[l] = meshLods[l - 1];
  145. }
  146. const PtrSize offset = m_patchInfos[i].m_gpuSceneMeshLodsIndex * sizeof(meshLods)
  147. + SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().getArrayBase(
  148. GpuSceneContiguousArrayType::kMeshLods);
  149. GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, meshLods.getSizeInBytes(),
  150. &meshLods[0]);
  151. }
  152. // Upload the uniforms
  153. DynamicArray<U32, MemoryPoolPtrWrapper<StackMemoryPool>> allUniforms(info.m_framePool);
  154. allUniforms.resize(U32(m_gpuSceneUniforms.m_size / 4));
  155. U32 count = 0;
  156. for(U32 i = 0; i < modelPatchCount; ++i)
  157. {
  158. const ModelPatch& patch = m_model->getModelPatches()[i];
  159. const MaterialResource& mtl = *patch.getMaterial();
  160. memcpy(&allUniforms[count], mtl.getPrefilledLocalUniforms().getBegin(),
  161. mtl.getPrefilledLocalUniforms().getSizeInBytes());
  162. count += U32(mtl.getPrefilledLocalUniforms().getSizeInBytes() / 4);
  163. }
  164. ANKI_ASSERT(count * 4 == m_gpuSceneUniforms.m_size);
  165. GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, m_gpuSceneUniforms.m_offset,
  166. m_gpuSceneUniforms.m_size, &allUniforms[0]);
  167. }
  168. // Upload transforms
  169. if(moved || movedLastFrame) [[unlikely]]
  170. {
  171. Array<Mat3x4, 2> trfs;
  172. trfs[0] = Mat3x4(info.m_node->getWorldTransform());
  173. trfs[1] = Mat3x4(info.m_node->getPreviousWorldTransform());
  174. const PtrSize offset = m_gpuSceneTransformsIndex * sizeof(trfs)
  175. + SceneGraph::getSingleton().getAllGpuSceneContiguousArrays().getArrayBase(
  176. GpuSceneContiguousArrayType::kTransformPairs);
  177. GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, sizeof(trfs), &trfs[0]);
  178. }
  179. // Spatial update
  180. if(moved || resourceUpdated || m_skinComponent) [[unlikely]]
  181. {
  182. Aabb aabbLocal;
  183. if(m_skinComponent == nullptr) [[likely]]
  184. {
  185. aabbLocal = m_model->getBoundingVolume();
  186. }
  187. else
  188. {
  189. aabbLocal =
  190. m_skinComponent->getBoneBoundingVolumeLocalSpace().getCompoundShape(m_model->getBoundingVolume());
  191. }
  192. const Aabb aabbWorld = aabbLocal.getTransformed(info.m_node->getWorldTransform());
  193. m_spatial.setBoundingShape(aabbWorld);
  194. }
  195. const Bool spatialUpdated = m_spatial.update(SceneGraph::getSingleton().getOctree());
  196. updated = updated || spatialUpdated;
  197. return Error::kNone;
  198. }
  199. void ModelComponent::setupRenderableQueueElements(U32 lod, RenderingTechnique technique,
  200. WeakArray<RenderableQueueElement>& outRenderables) const
  201. {
  202. ANKI_ASSERT(isEnabled());
  203. outRenderables.setArray(nullptr, 0);
  204. const RenderingTechniqueBit requestedRenderingTechniqueMask = RenderingTechniqueBit(1 << technique);
  205. if(!(m_presentRenderingTechniques & requestedRenderingTechniqueMask))
  206. {
  207. return;
  208. }
  209. // Allocate renderables
  210. U32 renderableCount = 0;
  211. for(U32 i = 0; i < m_patchInfos.getSize(); ++i)
  212. {
  213. renderableCount += !!(m_patchInfos[i].m_techniques & requestedRenderingTechniqueMask);
  214. }
  215. if(renderableCount == 0)
  216. {
  217. return;
  218. }
  219. RenderableQueueElement* renderables =
  220. static_cast<RenderableQueueElement*>(SceneGraph::getSingleton().getFrameMemoryPool().allocate(
  221. sizeof(RenderableQueueElement) * renderableCount, alignof(RenderableQueueElement)));
  222. outRenderables.setArray(renderables, renderableCount);
  223. // Fill renderables
  224. const Bool moved = m_node->movedThisFrame() && technique == RenderingTechnique::kGBuffer;
  225. const Bool hasSkin = m_skinComponent != nullptr && m_skinComponent->isEnabled();
  226. RenderingKey key;
  227. key.setLod(lod);
  228. key.setRenderingTechnique(technique);
  229. key.setVelocity(moved);
  230. key.setSkinned(hasSkin);
  231. renderableCount = 0;
  232. for(U32 i = 0; i < m_patchInfos.getSize(); ++i)
  233. {
  234. if(!(m_patchInfos[i].m_techniques & requestedRenderingTechniqueMask))
  235. {
  236. continue;
  237. }
  238. RenderableQueueElement& queueElem = renderables[renderableCount];
  239. const ModelPatch& patch = m_model->getModelPatches()[i];
  240. ModelRenderingInfo modelInf;
  241. patch.getRenderingInfo(key, modelInf);
  242. AllGpuSceneContiguousArrays& gpuArrays = SceneGraph::getSingleton().getAllGpuSceneContiguousArrays();
  243. queueElem.m_program = modelInf.m_program.get();
  244. queueElem.m_worldTransformsOffset = U32(m_gpuSceneTransformsIndex * sizeof(Mat3x4) * 2
  245. + gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kTransformPairs));
  246. queueElem.m_uniformsOffset = m_patchInfos[i].m_gpuSceneUniformsOffset;
  247. queueElem.m_geometryOffset =
  248. U32(m_patchInfos[i].m_gpuSceneMeshLodsIndex * sizeof(GpuSceneMeshLod) * kMaxLodCount
  249. + lod * sizeof(GpuSceneMeshLod));
  250. queueElem.m_geometryOffset += U32(gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kMeshLods));
  251. queueElem.m_boneTransformsOffset = (hasSkin) ? m_skinComponent->getBoneTransformsGpuSceneOffset() : 0;
  252. queueElem.m_indexCount = modelInf.m_indexCount;
  253. queueElem.m_firstIndex = U32(modelInf.m_indexBufferOffset / 2 + modelInf.m_firstIndex);
  254. queueElem.m_indexed = true;
  255. queueElem.m_primitiveTopology = PrimitiveTopology::kTriangles;
  256. queueElem.m_aabbMin = m_spatial.getAabbWorldSpace().getMin().xyz();
  257. queueElem.m_aabbMax = m_spatial.getAabbWorldSpace().getMax().xyz();
  258. queueElem.computeMergeKey();
  259. ++renderableCount;
  260. }
  261. }
  262. void ModelComponent::setupRayTracingInstanceQueueElements(U32 lod, RenderingTechnique technique,
  263. WeakArray<RayTracingInstanceQueueElement>& outInstances) const
  264. {
  265. ANKI_ASSERT(isEnabled());
  266. outInstances.setArray(nullptr, 0);
  267. const RenderingTechniqueBit requestedRenderingTechniqueMask = RenderingTechniqueBit(1 << technique);
  268. if(!(m_presentRenderingTechniques & requestedRenderingTechniqueMask))
  269. {
  270. return;
  271. }
  272. // Allocate instances
  273. U32 instanceCount = 0;
  274. for(U32 i = 0; i < m_patchInfos.getSize(); ++i)
  275. {
  276. instanceCount += !!(m_patchInfos[i].m_techniques & requestedRenderingTechniqueMask);
  277. }
  278. if(instanceCount == 0)
  279. {
  280. return;
  281. }
  282. RayTracingInstanceQueueElement* instances =
  283. static_cast<RayTracingInstanceQueueElement*>(SceneGraph::getSingleton().getFrameMemoryPool().allocate(
  284. sizeof(RayTracingInstanceQueueElement) * instanceCount, alignof(RayTracingInstanceQueueElement)));
  285. outInstances.setArray(instances, instanceCount);
  286. RenderingKey key;
  287. key.setLod(lod);
  288. key.setRenderingTechnique(technique);
  289. instanceCount = 0;
  290. for(U32 i = 0; i < m_patchInfos.getSize(); ++i)
  291. {
  292. if(!(m_patchInfos[i].m_techniques & requestedRenderingTechniqueMask))
  293. {
  294. continue;
  295. }
  296. RayTracingInstanceQueueElement& queueElem = instances[instanceCount];
  297. const ModelPatch& patch = m_model->getModelPatches()[i];
  298. AllGpuSceneContiguousArrays& gpuArrays = SceneGraph::getSingleton().getAllGpuSceneContiguousArrays();
  299. ModelRayTracingInfo modelInf;
  300. patch.getRayTracingInfo(key, modelInf);
  301. queueElem.m_bottomLevelAccelerationStructure = modelInf.m_bottomLevelAccelerationStructure.get();
  302. queueElem.m_shaderGroupHandleIndex = modelInf.m_shaderGroupHandleIndex;
  303. queueElem.m_worldTransformsOffset = U32(m_gpuSceneTransformsIndex * sizeof(Mat3x4) * 2
  304. + gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kTransformPairs));
  305. queueElem.m_uniformsOffset = m_patchInfos[i].m_gpuSceneUniformsOffset;
  306. queueElem.m_geometryOffset =
  307. U32(m_patchInfos[i].m_gpuSceneMeshLodsIndex * sizeof(GpuSceneMeshLod) * kMaxLodCount
  308. + lod * sizeof(GpuSceneMeshLod));
  309. queueElem.m_geometryOffset += U32(gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kMeshLods));
  310. queueElem.m_indexBufferOffset = U32(modelInf.m_indexBufferOffset);
  311. const Transform positionTransform(patch.getMesh()->getPositionsTranslation().xyz0(), Mat3x4::getIdentity(),
  312. patch.getMesh()->getPositionsScale());
  313. queueElem.m_transform = Mat3x4(m_node->getWorldTransform()).combineTransformations(Mat3x4(positionTransform));
  314. ++instanceCount;
  315. }
  316. }
  317. void ModelComponent::onOtherComponentRemovedOrAdded(SceneComponent* other, Bool added)
  318. {
  319. ANKI_ASSERT(other);
  320. if(other->getClassId() != SkinComponent::getStaticClassId())
  321. {
  322. return;
  323. }
  324. const Bool alreadyHasSkinComponent = m_skinComponent != nullptr;
  325. if(added && !alreadyHasSkinComponent)
  326. {
  327. m_skinComponent = static_cast<SkinComponent*>(other);
  328. m_dirty = true;
  329. }
  330. else if(!added && other == m_skinComponent)
  331. {
  332. m_skinComponent = nullptr;
  333. m_dirty = true;
  334. }
  335. }
  336. } // end namespace anki