ModelNode.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. // Copyright (C) 2009-2022, 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/ModelNode.h>
  6. #include <AnKi/Scene/SceneGraph.h>
  7. #include <AnKi/Scene/DebugDrawer.h>
  8. #include <AnKi/Scene/Components/MoveComponent.h>
  9. #include <AnKi/Scene/Components/SkinComponent.h>
  10. #include <AnKi/Scene/Components/SpatialComponent.h>
  11. #include <AnKi/Scene/Components/RenderComponent.h>
  12. #include <AnKi/Scene/Components/ModelComponent.h>
  13. #include <AnKi/Resource/ModelResource.h>
  14. #include <AnKi/Resource/ResourceManager.h>
  15. #include <AnKi/Resource/SkeletonResource.h>
  16. #include <AnKi/Physics/PhysicsWorld.h>
  17. namespace anki {
  18. /// Feedback component.
  19. class ModelNode::FeedbackComponent : public SceneComponent
  20. {
  21. ANKI_SCENE_COMPONENT(ModelNode::FeedbackComponent)
  22. public:
  23. FeedbackComponent(SceneNode* node)
  24. : SceneComponent(node, getStaticClassId(), true)
  25. {
  26. }
  27. Error update(SceneComponentUpdateInfo& info, Bool& updated)
  28. {
  29. updated = false;
  30. static_cast<ModelNode&>(*info.m_node).feedbackUpdate();
  31. return Error::kNone;
  32. }
  33. };
  34. ANKI_SCENE_COMPONENT_STATICS(ModelNode::FeedbackComponent)
  35. class ModelNode::RenderProxy
  36. {
  37. public:
  38. ModelNode* m_node = nullptr;
  39. /// Uncompresses the mesh positions to the local view. The scale should be uniform because it will be applied to
  40. /// normals and tangents and non-uniform data will cause problems.
  41. Mat4 m_compressedToModelTransform = Mat4::getIdentity();
  42. };
  43. ModelNode::ModelNode(SceneGraph* scene, CString name)
  44. : SceneNode(scene, name)
  45. {
  46. newComponent<ModelComponent>();
  47. newComponent<SkinComponent>();
  48. newComponent<MoveComponent>();
  49. newComponent<FeedbackComponent>();
  50. newComponent<SpatialComponent>();
  51. newComponent<RenderComponent>(); // One of many
  52. m_renderProxies.create(getMemoryPool(), 1);
  53. }
  54. ModelNode::~ModelNode()
  55. {
  56. m_renderProxies.destroy(getMemoryPool());
  57. }
  58. void ModelNode::feedbackUpdate()
  59. {
  60. const ModelComponent& modelc = getFirstComponentOfType<ModelComponent>();
  61. const SkinComponent& skinc = getFirstComponentOfType<SkinComponent>();
  62. const MoveComponent& movec = getFirstComponentOfType<MoveComponent>();
  63. if(!modelc.isEnabled())
  64. {
  65. // Disable everything
  66. ANKI_ASSERT(!"TODO");
  67. return;
  68. }
  69. const Timestamp globTimestamp = getGlobalTimestamp();
  70. Bool updateSpatial = false;
  71. // Model update
  72. if(modelc.getTimestamp() == globTimestamp)
  73. {
  74. m_aabbLocal = modelc.getModelResource()->getBoundingVolume();
  75. updateSpatial = true;
  76. if(modelc.getModelResource()->getModelPatches().getSize() == countComponentsOfType<RenderComponent>())
  77. {
  78. // Easy, just re-init the render components
  79. initRenderComponents();
  80. }
  81. else
  82. {
  83. // Need to create more render components, can't do it at the moment, deffer it
  84. m_deferredRenderComponentUpdate = true;
  85. }
  86. }
  87. // Skin update
  88. if(skinc.isEnabled() && skinc.getTimestamp() == globTimestamp)
  89. {
  90. m_aabbLocal = skinc.getBoneBoundingVolumeLocalSpace();
  91. updateSpatial = true;
  92. }
  93. // Move update
  94. if(movec.getTimestamp() == globTimestamp)
  95. {
  96. getFirstComponentOfType<SpatialComponent>().setSpatialOrigin(movec.getWorldTransform().getOrigin().xyz());
  97. updateSpatial = true;
  98. }
  99. // Spatial update
  100. if(updateSpatial)
  101. {
  102. const Aabb aabbWorld = m_aabbLocal.getTransformed(movec.getWorldTransform());
  103. getFirstComponentOfType<SpatialComponent>().setAabbWorldSpace(aabbWorld);
  104. }
  105. }
  106. Error ModelNode::frameUpdate([[maybe_unused]] Second prevUpdateTime, [[maybe_unused]] Second crntTime)
  107. {
  108. if(ANKI_LIKELY(!m_deferredRenderComponentUpdate))
  109. {
  110. return Error::kNone;
  111. }
  112. m_deferredRenderComponentUpdate = false;
  113. const ModelComponent& modelc = getFirstComponentOfType<ModelComponent>();
  114. const U32 modelPatchCount = modelc.getModelResource()->getModelPatches().getSize();
  115. const U32 renderComponentCount = countComponentsOfType<RenderComponent>();
  116. if(modelPatchCount > renderComponentCount)
  117. {
  118. const U32 diff = modelPatchCount - renderComponentCount;
  119. for(U32 i = 0; i < diff; ++i)
  120. {
  121. newComponent<RenderComponent>();
  122. }
  123. m_renderProxies.resize(getMemoryPool(), modelPatchCount);
  124. }
  125. else
  126. {
  127. ANKI_ASSERT(!"TODO");
  128. }
  129. ANKI_ASSERT(countComponentsOfType<RenderComponent>() == modelPatchCount);
  130. // Now you can init the render components
  131. initRenderComponents();
  132. return Error::kNone;
  133. }
  134. void ModelNode::initRenderComponents()
  135. {
  136. const ModelComponent& modelc = getFirstComponentOfType<ModelComponent>();
  137. const ModelResourcePtr& model = modelc.getModelResource();
  138. ANKI_ASSERT(modelc.getModelResource()->getModelPatches().getSize() == countComponentsOfType<RenderComponent>());
  139. ANKI_ASSERT(modelc.getModelResource()->getModelPatches().getSize() == m_renderProxies.getSize());
  140. for(U32 patchIdx = 0; patchIdx < model->getModelPatches().getSize(); ++patchIdx)
  141. {
  142. const ModelPatch& modelPatch = model->getModelPatches()[patchIdx];
  143. RenderComponent& rc = getNthComponentOfType<RenderComponent>(patchIdx);
  144. rc.initRaster(
  145. [](RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData) {
  146. const RenderProxy& proxy = *static_cast<const RenderProxy*>(userData[0]);
  147. const U32 modelPatchIdx = U32(&proxy - &proxy.m_node->m_renderProxies[0]);
  148. proxy.m_node->draw(ctx, userData, modelPatchIdx);
  149. },
  150. &m_renderProxies[patchIdx], modelc.getRenderMergeKeys()[patchIdx]);
  151. rc.setFlagsFromMaterial(modelPatch.getMaterial());
  152. if(!!(modelPatch.getMaterial()->getRenderingTechniques() & RenderingTechniqueBit::kAllRt))
  153. {
  154. rc.initRayTracing(
  155. [](U32 lod, const void* userData, RayTracingInstanceQueueElement& el) {
  156. const RenderProxy& proxy = *static_cast<const RenderProxy*>(userData);
  157. const U32 modelPatchIdx = U32(&proxy - &proxy.m_node->m_renderProxies[0]);
  158. proxy.m_node->setupRayTracingInstanceQueueElement(lod, modelPatchIdx, el);
  159. },
  160. &m_renderProxies[patchIdx]);
  161. }
  162. // Init the proxy
  163. RenderProxy& proxy = m_renderProxies[patchIdx];
  164. proxy.m_node = this;
  165. const MeshResource& meshResource = *modelPatch.getMesh();
  166. proxy.m_compressedToModelTransform.setTranslationPart(meshResource.getPositionsTranslation().xyz1());
  167. proxy.m_compressedToModelTransform(0, 0) = meshResource.getPositionsScale();
  168. proxy.m_compressedToModelTransform(1, 1) = meshResource.getPositionsScale();
  169. proxy.m_compressedToModelTransform(2, 2) = meshResource.getPositionsScale();
  170. }
  171. }
  172. void ModelNode::draw(RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData, U32 modelPatchIdx) const
  173. {
  174. const U32 instanceCount = userData.getSize();
  175. ANKI_ASSERT(instanceCount > 0 && instanceCount <= kMaxInstanceCount);
  176. ANKI_ASSERT(ctx.m_key.getInstanceCount() == instanceCount);
  177. CommandBufferPtr& cmdb = ctx.m_commandBuffer;
  178. if(ANKI_LIKELY(!ctx.m_debugDraw))
  179. {
  180. const ModelComponent& modelc = getFirstComponentOfType<ModelComponent>();
  181. const ModelPatch& patch = modelc.getModelResource()->getModelPatches()[modelPatchIdx];
  182. const SkinComponent& skinc = getFirstComponentOfType<SkinComponent>();
  183. // Transforms
  184. auto computeTranform = [&](const Transform& trf) -> Mat3x4 {
  185. if(skinc.isEnabled())
  186. {
  187. return Mat3x4(trf);
  188. }
  189. else
  190. {
  191. // Bake the decompression in the model matrix
  192. const Mat4 m4 = Mat4(trf) * m_renderProxies[modelPatchIdx].m_compressedToModelTransform;
  193. const Mat3x4 out(m4);
  194. return out;
  195. }
  196. };
  197. Array<Mat3x4, kMaxInstanceCount> trfs;
  198. Array<Mat3x4, kMaxInstanceCount> prevTrfs;
  199. const MoveComponent& movec = getFirstComponentOfType<MoveComponent>();
  200. trfs[0] = computeTranform(movec.getWorldTransform());
  201. prevTrfs[0] = computeTranform(movec.getPreviousWorldTransform());
  202. Bool moved = trfs[0] != prevTrfs[0];
  203. for(U32 i = 1; i < instanceCount; ++i)
  204. {
  205. const ModelNode& otherNode = *static_cast<const RenderProxy*>(userData[i])->m_node;
  206. [[maybe_unused]] const U32 otherNodeModelPatchIdx =
  207. U32(static_cast<const RenderProxy*>(userData[i]) - &otherNode.m_renderProxies[0]);
  208. ANKI_ASSERT(otherNodeModelPatchIdx == modelPatchIdx);
  209. const MoveComponent& otherNodeMovec = otherNode.getFirstComponentOfType<MoveComponent>();
  210. trfs[i] = computeTranform(otherNodeMovec.getWorldTransform());
  211. prevTrfs[i] = computeTranform(otherNodeMovec.getPreviousWorldTransform());
  212. moved = moved || (trfs[i] != prevTrfs[i]);
  213. }
  214. ctx.m_key.setVelocity(moved && ctx.m_key.getRenderingTechnique() == RenderingTechnique::kGBuffer);
  215. ctx.m_key.setSkinned(skinc.isEnabled());
  216. ModelRenderingInfo modelInf;
  217. patch.getRenderingInfo(ctx.m_key, modelInf);
  218. // Bones storage
  219. if(skinc.isEnabled())
  220. {
  221. const U32 boneCount = skinc.getBoneTransforms().getSize();
  222. StagingGpuMemoryToken token, tokenPrev;
  223. void* trfs = ctx.m_stagingGpuAllocator->allocateFrame(boneCount * sizeof(Mat4),
  224. StagingGpuMemoryType::kStorage, token);
  225. memcpy(trfs, &skinc.getBoneTransforms()[0], boneCount * sizeof(Mat4));
  226. trfs = ctx.m_stagingGpuAllocator->allocateFrame(boneCount * sizeof(Mat4), StagingGpuMemoryType::kStorage,
  227. tokenPrev);
  228. memcpy(trfs, &skinc.getPreviousFrameBoneTransforms()[0], boneCount * sizeof(Mat4));
  229. cmdb->bindStorageBuffer(kMaterialSetLocal, kMaterialBindingBoneTransforms, token.m_buffer, token.m_offset,
  230. token.m_range);
  231. cmdb->bindStorageBuffer(kMaterialSetLocal, kMaterialBindingPreviousBoneTransforms, tokenPrev.m_buffer,
  232. tokenPrev.m_offset, tokenPrev.m_range);
  233. }
  234. // Program
  235. cmdb->bindShaderProgram(modelInf.m_program);
  236. // Uniforms
  237. const Vec4 positionScaleAndTransform(
  238. m_renderProxies[modelPatchIdx].m_compressedToModelTransform(0, 0),
  239. m_renderProxies[modelPatchIdx].m_compressedToModelTransform.getTranslationPart().xyz());
  240. RenderComponent::allocateAndSetupUniforms(
  241. modelc.getModelResource()->getModelPatches()[modelPatchIdx].getMaterial(), ctx,
  242. ConstWeakArray<Mat3x4>(&trfs[0], instanceCount), ConstWeakArray<Mat3x4>(&prevTrfs[0], instanceCount),
  243. *ctx.m_stagingGpuAllocator, positionScaleAndTransform);
  244. // Bind attributes & vertex buffers
  245. for(VertexStreamId streamId :
  246. EnumIterable<VertexStreamId>(VertexStreamId::kMeshRelatedFirst, VertexStreamId::kMeshRelatedCount))
  247. {
  248. if(modelInf.m_vertexBufferOffsets[streamId] == kMaxPtrSize)
  249. {
  250. continue;
  251. }
  252. const U32 attribLocation = U32(streamId);
  253. const U32 bufferBinding = U32(streamId);
  254. const Format fmt = kMeshRelatedVertexStreamFormats[streamId];
  255. const U32 relativeOffset = 0;
  256. const U32 vertexStride = getFormatInfo(fmt).m_texelSize;
  257. cmdb->setVertexAttribute(attribLocation, bufferBinding, fmt, relativeOffset);
  258. cmdb->bindVertexBuffer(bufferBinding, getExternalSubsystems().m_unifiedGeometryMemPool->getBuffer(),
  259. modelInf.m_vertexBufferOffsets[streamId], vertexStride, VertexStepRate::kVertex);
  260. }
  261. // Bind index buffer
  262. cmdb->bindIndexBuffer(getExternalSubsystems().m_unifiedGeometryMemPool->getBuffer(),
  263. modelInf.m_indexBufferOffset, IndexType::kU16);
  264. // Draw
  265. cmdb->drawElements(PrimitiveTopology::kTriangles, modelInf.m_indexCount, instanceCount, modelInf.m_firstIndex,
  266. 0, 0);
  267. }
  268. else
  269. {
  270. // Draw the bounding volumes
  271. Mat4* const mvps = newArray<Mat4>(*ctx.m_framePool, instanceCount);
  272. for(U32 i = 0; i < instanceCount; ++i)
  273. {
  274. const ModelNode& otherNode = *static_cast<const RenderProxy*>(userData[i])->m_node;
  275. const Aabb& box = otherNode.getFirstComponentOfType<SpatialComponent>().getAabbWorldSpace();
  276. const Vec4 tsl = (box.getMin() + box.getMax()) / 2.0f;
  277. const Vec3 scale = (box.getMax().xyz() - box.getMin().xyz()) / 2.0f;
  278. // Set non uniform scale. Add a margin to avoid flickering
  279. Mat3 nonUniScale = Mat3::getZero();
  280. constexpr F32 kMargin = 1.02f;
  281. nonUniScale(0, 0) = scale.x() * kMargin;
  282. nonUniScale(1, 1) = scale.y() * kMargin;
  283. nonUniScale(2, 2) = scale.z() * kMargin;
  284. mvps[i] = ctx.m_viewProjectionMatrix * Mat4(tsl.xyz1(), Mat3::getIdentity() * nonUniScale, 1.0f);
  285. }
  286. const Bool enableDepthTest = ctx.m_debugDrawFlags.get(RenderQueueDebugDrawFlag::kDepthTestOn);
  287. if(enableDepthTest)
  288. {
  289. cmdb->setDepthCompareOperation(CompareOperation::kLess);
  290. }
  291. else
  292. {
  293. cmdb->setDepthCompareOperation(CompareOperation::kAlways);
  294. }
  295. getSceneGraph().getDebugDrawer().drawCubes(
  296. ConstWeakArray<Mat4>(mvps, instanceCount), Vec4(1.0f, 0.0f, 1.0f, 1.0f), 2.0f,
  297. ctx.m_debugDrawFlags.get(RenderQueueDebugDrawFlag::kDitheredDepthTestOn), 2.0f, *ctx.m_stagingGpuAllocator,
  298. cmdb);
  299. deleteArray(*ctx.m_framePool, mvps, instanceCount);
  300. // Bones
  301. const SkinComponent& skinc = getFirstComponentOfType<SkinComponent>();
  302. if(skinc.isEnabled())
  303. {
  304. const SkinComponent& skinc = getComponentAt<SkinComponent>(0);
  305. SkeletonResourcePtr skeleton = skinc.getSkeleronResource();
  306. const U32 boneCount = skinc.getBoneTransforms().getSize();
  307. DynamicArrayRaii<Vec3> lines(ctx.m_framePool);
  308. lines.resizeStorage(boneCount * 2);
  309. DynamicArrayRaii<Vec3> chidlessLines(ctx.m_framePool);
  310. for(U32 i = 0; i < boneCount; ++i)
  311. {
  312. const Bone& bone = skeleton->getBones()[i];
  313. ANKI_ASSERT(bone.getIndex() == i);
  314. const Vec4 point(0.0f, 0.0f, 0.0f, 1.0f);
  315. const Bone* parent = bone.getParent();
  316. Mat4 m = (parent)
  317. ? skinc.getBoneTransforms()[parent->getIndex()] * parent->getVertexTransform().getInverse()
  318. : Mat4::getIdentity();
  319. const Vec3 a = (m * point).xyz();
  320. m = skinc.getBoneTransforms()[i] * bone.getVertexTransform().getInverse();
  321. const Vec3 b = (m * point).xyz();
  322. lines.emplaceBack(a);
  323. lines.emplaceBack(b);
  324. if(bone.getChildren().getSize() == 0)
  325. {
  326. // If there are not children try to draw something for that bone as well
  327. chidlessLines.emplaceBack(b);
  328. const F32 len = (b - a).getLength();
  329. const Vec3 c = b + (b - a).getNormalized() * len;
  330. chidlessLines.emplaceBack(c);
  331. }
  332. }
  333. const Mat4 mvp =
  334. ctx.m_viewProjectionMatrix * Mat4(getFirstComponentOfType<MoveComponent>().getWorldTransform());
  335. getSceneGraph().getDebugDrawer().drawLines(
  336. ConstWeakArray<Mat4>(&mvp, 1), Vec4(1.0f), 20.0f,
  337. ctx.m_debugDrawFlags.get(RenderQueueDebugDrawFlag::kDitheredDepthTestOn), lines,
  338. *ctx.m_stagingGpuAllocator, cmdb);
  339. getSceneGraph().getDebugDrawer().drawLines(
  340. ConstWeakArray<Mat4>(&mvp, 1), Vec4(0.7f, 0.7f, 0.7f, 1.0f), 5.0f,
  341. ctx.m_debugDrawFlags.get(RenderQueueDebugDrawFlag::kDitheredDepthTestOn), chidlessLines,
  342. *ctx.m_stagingGpuAllocator, cmdb);
  343. }
  344. // Restore state
  345. if(!enableDepthTest)
  346. {
  347. cmdb->setDepthCompareOperation(CompareOperation::kLess);
  348. }
  349. }
  350. }
  351. void ModelNode::setupRayTracingInstanceQueueElement(U32 lod, U32 modelPatchIdx,
  352. RayTracingInstanceQueueElement& el) const
  353. {
  354. const ModelComponent& modelc = getFirstComponentOfType<ModelComponent>();
  355. const ModelPatch& patch = modelc.getModelResource()->getModelPatches()[modelPatchIdx];
  356. RenderingKey key(RenderingTechnique::kRtShadow, lod, 1, false, false);
  357. ModelRayTracingInfo info;
  358. patch.getRayTracingInfo(key, info);
  359. memset(&el, 0, sizeof(el));
  360. el.m_bottomLevelAccelerationStructure = info.m_bottomLevelAccelerationStructure.get();
  361. const MoveComponent& movec = getFirstComponentOfType<MoveComponent>();
  362. const Mat4 m4 = Mat4(movec.getWorldTransform()) * m_renderProxies[modelPatchIdx].m_compressedToModelTransform;
  363. el.m_transform = Mat3x4(m4);
  364. el.m_shaderGroupHandleIndex = info.m_shaderGroupHandleIndex;
  365. }
  366. } // end namespace anki