2
0

ModelComponent.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  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(
  19. node->getSceneGraph().getAllGpuSceneContiguousArrays().allocate(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. m_node->getSceneGraph().getAllGpuSceneContiguousArrays().deferredFree(
  29. GpuSceneContiguousArrayType::kMeshLods, patch.m_gpuSceneMeshLodsIndex);
  30. }
  31. }
  32. m_node->getSceneGraph().getAllGpuSceneContiguousArrays().deferredFree(GpuSceneContiguousArrayType::kTransformPairs,
  33. m_gpuSceneTransformsIndex);
  34. m_patchInfos.destroy(m_node->getMemoryPool());
  35. m_spatial.removeFromOctree(m_node->getSceneGraph().getOctree());
  36. }
  37. void ModelComponent::loadModelResource(CString filename)
  38. {
  39. ModelResourcePtr rsrc;
  40. const Error err = getExternalSubsystems(*m_node).m_resourceManager->loadResource(filename, rsrc);
  41. if(err)
  42. {
  43. ANKI_SCENE_LOGE("Failed to load model resource");
  44. return;
  45. }
  46. m_dirty = true;
  47. m_model = std::move(rsrc);
  48. const U32 modelPatchCount = m_model->getModelPatches().getSize();
  49. // GPU scene allocations
  50. for(const PatchInfo& patch : m_patchInfos)
  51. {
  52. if(patch.m_gpuSceneMeshLodsIndex != kMaxU32)
  53. {
  54. m_node->getSceneGraph().getAllGpuSceneContiguousArrays().deferredFree(
  55. GpuSceneContiguousArrayType::kMeshLods, patch.m_gpuSceneMeshLodsIndex);
  56. }
  57. }
  58. m_patchInfos.resize(m_node->getMemoryPool(), modelPatchCount);
  59. for(U32 i = 0; i < modelPatchCount; ++i)
  60. {
  61. m_patchInfos[i].m_gpuSceneMeshLodsIndex = U32(
  62. m_node->getSceneGraph().getAllGpuSceneContiguousArrays().allocate(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. + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
  148. GpuSceneContiguousArrayType::kMeshLods);
  149. GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, meshLods.getSizeInBytes(),
  150. &meshLods[0]);
  151. }
  152. // Upload the uniforms
  153. DynamicArrayRaii<U32> allUniforms(info.m_framePool, U32(m_gpuSceneUniforms.m_size / 4));
  154. U32 count = 0;
  155. for(U32 i = 0; i < modelPatchCount; ++i)
  156. {
  157. const ModelPatch& patch = m_model->getModelPatches()[i];
  158. const MaterialResource& mtl = *patch.getMaterial();
  159. memcpy(&allUniforms[count], mtl.getPrefilledLocalUniforms().getBegin(),
  160. mtl.getPrefilledLocalUniforms().getSizeInBytes());
  161. count += U32(mtl.getPrefilledLocalUniforms().getSizeInBytes() / 4);
  162. }
  163. ANKI_ASSERT(count * 4 == m_gpuSceneUniforms.m_size);
  164. GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, m_gpuSceneUniforms.m_offset,
  165. m_gpuSceneUniforms.m_size, &allUniforms[0]);
  166. }
  167. // Upload transforms
  168. if(moved || movedLastFrame) [[unlikely]]
  169. {
  170. Array<Mat3x4, 2> trfs;
  171. trfs[0] = Mat3x4(info.m_node->getWorldTransform());
  172. trfs[1] = Mat3x4(info.m_node->getPreviousWorldTransform());
  173. const PtrSize offset = m_gpuSceneTransformsIndex * sizeof(trfs)
  174. + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
  175. GpuSceneContiguousArrayType::kTransformPairs);
  176. GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, sizeof(trfs), &trfs[0]);
  177. }
  178. // Spatial update
  179. if(moved || resourceUpdated || m_skinComponent) [[unlikely]]
  180. {
  181. Aabb aabbLocal;
  182. if(m_skinComponent == nullptr) [[likely]]
  183. {
  184. aabbLocal = m_model->getBoundingVolume();
  185. }
  186. else
  187. {
  188. aabbLocal =
  189. m_skinComponent->getBoneBoundingVolumeLocalSpace().getCompoundShape(m_model->getBoundingVolume());
  190. }
  191. const Aabb aabbWorld = aabbLocal.getTransformed(info.m_node->getWorldTransform());
  192. m_spatial.setBoundingShape(aabbWorld);
  193. }
  194. const Bool spatialUpdated = m_spatial.update(info.m_node->getSceneGraph().getOctree());
  195. updated = updated || spatialUpdated;
  196. return Error::kNone;
  197. }
  198. void ModelComponent::setupRenderableQueueElements(U32 lod, RenderingTechnique technique, StackMemoryPool& tmpPool,
  199. WeakArray<RenderableQueueElement>& outRenderables) const
  200. {
  201. ANKI_ASSERT(isEnabled());
  202. outRenderables.setArray(nullptr, 0);
  203. const RenderingTechniqueBit requestedRenderingTechniqueMask = RenderingTechniqueBit(1 << technique);
  204. if(!(m_presentRenderingTechniques & requestedRenderingTechniqueMask))
  205. {
  206. return;
  207. }
  208. // Allocate renderables
  209. U32 renderableCount = 0;
  210. for(U32 i = 0; i < m_patchInfos.getSize(); ++i)
  211. {
  212. renderableCount += !!(m_patchInfos[i].m_techniques & requestedRenderingTechniqueMask);
  213. }
  214. if(renderableCount == 0)
  215. {
  216. return;
  217. }
  218. RenderableQueueElement* renderables = static_cast<RenderableQueueElement*>(
  219. tmpPool.allocate(sizeof(RenderableQueueElement) * renderableCount, alignof(RenderableQueueElement)));
  220. outRenderables.setArray(renderables, renderableCount);
  221. // Fill renderables
  222. const Bool moved = m_node->movedThisFrame() && technique == RenderingTechnique::kGBuffer;
  223. const Bool hasSkin = m_skinComponent != nullptr && m_skinComponent->isEnabled();
  224. RenderingKey key;
  225. key.setLod(lod);
  226. key.setRenderingTechnique(technique);
  227. key.setVelocity(moved);
  228. key.setSkinned(hasSkin);
  229. renderableCount = 0;
  230. for(U32 i = 0; i < m_patchInfos.getSize(); ++i)
  231. {
  232. if(!(m_patchInfos[i].m_techniques & requestedRenderingTechniqueMask))
  233. {
  234. continue;
  235. }
  236. RenderableQueueElement& queueElem = renderables[renderableCount];
  237. const ModelPatch& patch = m_model->getModelPatches()[i];
  238. ModelRenderingInfo modelInf;
  239. patch.getRenderingInfo(key, modelInf);
  240. AllGpuSceneContiguousArrays& gpuArrays = m_node->getSceneGraph().getAllGpuSceneContiguousArrays();
  241. queueElem.m_program = modelInf.m_program.get();
  242. queueElem.m_worldTransformsOffset = U32(m_gpuSceneTransformsIndex * sizeof(Mat3x4) * 2
  243. + gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kTransformPairs));
  244. queueElem.m_uniformsOffset = m_patchInfos[i].m_gpuSceneUniformsOffset;
  245. queueElem.m_geometryOffset =
  246. U32(m_patchInfos[i].m_gpuSceneMeshLodsIndex * sizeof(GpuSceneMeshLod) * kMaxLodCount
  247. + lod * sizeof(GpuSceneMeshLod));
  248. queueElem.m_geometryOffset += U32(gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kMeshLods));
  249. queueElem.m_boneTransformsOffset = (hasSkin) ? m_skinComponent->getBoneTransformsGpuSceneOffset() : 0;
  250. queueElem.m_indexCount = modelInf.m_indexCount;
  251. queueElem.m_firstIndex = U32(modelInf.m_indexBufferOffset / 2 + modelInf.m_firstIndex);
  252. queueElem.m_indexed = true;
  253. queueElem.m_primitiveTopology = PrimitiveTopology::kTriangles;
  254. queueElem.m_aabbMin = m_spatial.getAabbWorldSpace().getMin().xyz();
  255. queueElem.m_aabbMax = m_spatial.getAabbWorldSpace().getMax().xyz();
  256. queueElem.computeMergeKey();
  257. ++renderableCount;
  258. }
  259. }
  260. void ModelComponent::setupRayTracingInstanceQueueElements(U32 lod, RenderingTechnique technique,
  261. StackMemoryPool& tmpPool,
  262. WeakArray<RayTracingInstanceQueueElement>& outInstances) const
  263. {
  264. ANKI_ASSERT(isEnabled());
  265. outInstances.setArray(nullptr, 0);
  266. const RenderingTechniqueBit requestedRenderingTechniqueMask = RenderingTechniqueBit(1 << technique);
  267. if(!(m_presentRenderingTechniques & requestedRenderingTechniqueMask))
  268. {
  269. return;
  270. }
  271. // Allocate instances
  272. U32 instanceCount = 0;
  273. for(U32 i = 0; i < m_patchInfos.getSize(); ++i)
  274. {
  275. instanceCount += !!(m_patchInfos[i].m_techniques & requestedRenderingTechniqueMask);
  276. }
  277. if(instanceCount == 0)
  278. {
  279. return;
  280. }
  281. RayTracingInstanceQueueElement* instances = static_cast<RayTracingInstanceQueueElement*>(tmpPool.allocate(
  282. sizeof(RayTracingInstanceQueueElement) * instanceCount, alignof(RayTracingInstanceQueueElement)));
  283. outInstances.setArray(instances, instanceCount);
  284. RenderingKey key;
  285. key.setLod(lod);
  286. key.setRenderingTechnique(technique);
  287. instanceCount = 0;
  288. for(U32 i = 0; i < m_patchInfos.getSize(); ++i)
  289. {
  290. if(!(m_patchInfos[i].m_techniques & requestedRenderingTechniqueMask))
  291. {
  292. continue;
  293. }
  294. RayTracingInstanceQueueElement& queueElem = instances[instanceCount];
  295. const ModelPatch& patch = m_model->getModelPatches()[i];
  296. AllGpuSceneContiguousArrays& gpuArrays = m_node->getSceneGraph().getAllGpuSceneContiguousArrays();
  297. ModelRayTracingInfo modelInf;
  298. patch.getRayTracingInfo(key, modelInf);
  299. queueElem.m_bottomLevelAccelerationStructure = modelInf.m_bottomLevelAccelerationStructure.get();
  300. queueElem.m_shaderGroupHandleIndex = modelInf.m_shaderGroupHandleIndex;
  301. queueElem.m_worldTransformsOffset = U32(m_gpuSceneTransformsIndex * sizeof(Mat3x4) * 2
  302. + gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kTransformPairs));
  303. queueElem.m_uniformsOffset = m_patchInfos[i].m_gpuSceneUniformsOffset;
  304. queueElem.m_geometryOffset =
  305. U32(m_patchInfos[i].m_gpuSceneMeshLodsIndex * sizeof(GpuSceneMeshLod) * kMaxLodCount
  306. + lod * sizeof(GpuSceneMeshLod));
  307. queueElem.m_geometryOffset += U32(gpuArrays.getArrayBase(GpuSceneContiguousArrayType::kMeshLods));
  308. queueElem.m_indexBufferOffset = U32(modelInf.m_indexBufferOffset);
  309. const Transform positionTransform(patch.getMesh()->getPositionsTranslation().xyz0(), Mat3x4::getIdentity(),
  310. patch.getMesh()->getPositionsScale());
  311. queueElem.m_transform = Mat3x4(m_node->getWorldTransform()).combineTransformations(Mat3x4(positionTransform));
  312. ++instanceCount;
  313. }
  314. }
  315. void ModelComponent::onOtherComponentRemovedOrAdded(SceneComponent* other, Bool added)
  316. {
  317. ANKI_ASSERT(other);
  318. if(other->getClassId() != SkinComponent::getStaticClassId())
  319. {
  320. return;
  321. }
  322. const Bool alreadyHasSkinComponent = m_skinComponent != nullptr;
  323. if(added && !alreadyHasSkinComponent)
  324. {
  325. m_skinComponent = static_cast<SkinComponent*>(other);
  326. m_dirty = true;
  327. }
  328. else if(!added && other == m_skinComponent)
  329. {
  330. m_skinComponent = nullptr;
  331. m_dirty = true;
  332. }
  333. }
  334. } // end namespace anki