ModelNode.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  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/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. {
  19. /// Feedback component.
  20. class ModelNode::FeedbackComponent : public SceneComponent
  21. {
  22. ANKI_SCENE_COMPONENT(ModelNode::FeedbackComponent)
  23. public:
  24. FeedbackComponent(SceneNode* node)
  25. : SceneComponent(node, getStaticClassId(), true)
  26. {
  27. }
  28. ANKI_USE_RESULT Error update(SceneNode& node, Second prevTime, Second crntTime, Bool& updated) override
  29. {
  30. updated = false;
  31. static_cast<ModelNode&>(node).feedbackUpdate();
  32. return Error::NONE;
  33. }
  34. };
  35. ANKI_SCENE_COMPONENT_STATICS(ModelNode::FeedbackComponent)
  36. class ModelNode::RenderProxy
  37. {
  38. public:
  39. ModelNode* m_node = nullptr;
  40. };
  41. ModelNode::ModelNode(SceneGraph* scene, CString name)
  42. : SceneNode(scene, name)
  43. {
  44. newComponent<ModelComponent>();
  45. newComponent<SkinComponent>();
  46. newComponent<MoveComponent>();
  47. newComponent<FeedbackComponent>();
  48. newComponent<SpatialComponent>();
  49. newComponent<RenderComponent>(); // One of many
  50. m_renderProxies.create(getAllocator(), 1);
  51. }
  52. ModelNode::~ModelNode()
  53. {
  54. m_renderProxies.destroy(getAllocator());
  55. }
  56. void ModelNode::feedbackUpdate()
  57. {
  58. const ModelComponent& modelc = getFirstComponentOfType<ModelComponent>();
  59. const SkinComponent& skinc = getFirstComponentOfType<SkinComponent>();
  60. const MoveComponent& movec = getFirstComponentOfType<MoveComponent>();
  61. if(!modelc.isEnabled())
  62. {
  63. // Disable everything
  64. ANKI_ASSERT(!"TODO");
  65. return;
  66. }
  67. const Timestamp globTimestamp = getGlobalTimestamp();
  68. Bool updateSpatial = false;
  69. // Model update
  70. if(modelc.getTimestamp() == globTimestamp)
  71. {
  72. m_aabbLocal = modelc.getModelResource()->getBoundingVolume();
  73. updateSpatial = true;
  74. if(modelc.getModelResource()->getModelPatches().getSize() == countComponentsOfType<RenderComponent>())
  75. {
  76. // Easy, just re-init the render components
  77. initRenderComponents();
  78. }
  79. else
  80. {
  81. // Need to create more render components, can't do it at the moment, deffer it
  82. m_deferredRenderComponentUpdate = true;
  83. }
  84. }
  85. // Skin update
  86. if(skinc.isEnabled() && skinc.getTimestamp() == globTimestamp)
  87. {
  88. m_aabbLocal = skinc.getBoneBoundingVolumeLocalSpace();
  89. updateSpatial = true;
  90. }
  91. // Move update
  92. if(movec.getTimestamp() == globTimestamp)
  93. {
  94. getFirstComponentOfType<SpatialComponent>().setSpatialOrigin(movec.getWorldTransform().getOrigin().xyz());
  95. updateSpatial = true;
  96. }
  97. // Spatial update
  98. if(updateSpatial)
  99. {
  100. const Aabb aabbWorld = m_aabbLocal.getTransformed(movec.getWorldTransform());
  101. getFirstComponentOfType<SpatialComponent>().setAabbWorldSpace(aabbWorld);
  102. }
  103. }
  104. Error ModelNode::frameUpdate(Second prevUpdateTime, Second crntTime)
  105. {
  106. if(ANKI_LIKELY(!m_deferredRenderComponentUpdate))
  107. {
  108. return Error::NONE;
  109. }
  110. m_deferredRenderComponentUpdate = false;
  111. const ModelComponent& modelc = getFirstComponentOfType<ModelComponent>();
  112. const U32 modelPatchCount = modelc.getModelResource()->getModelPatches().getSize();
  113. const U32 renderComponentCount = countComponentsOfType<RenderComponent>();
  114. if(modelPatchCount > renderComponentCount)
  115. {
  116. const U32 diff = modelPatchCount - renderComponentCount;
  117. for(U32 i = 0; i < diff; ++i)
  118. {
  119. newComponent<RenderComponent>();
  120. }
  121. m_renderProxies.resize(getAllocator(), modelPatchCount);
  122. }
  123. else
  124. {
  125. ANKI_ASSERT(!"TODO");
  126. }
  127. ANKI_ASSERT(countComponentsOfType<RenderComponent>() == modelPatchCount);
  128. // Now you can init the render components
  129. initRenderComponents();
  130. return Error::NONE;
  131. }
  132. void ModelNode::initRenderComponents()
  133. {
  134. const ModelComponent& modelc = getFirstComponentOfType<ModelComponent>();
  135. const ModelResourcePtr& model = modelc.getModelResource();
  136. ANKI_ASSERT(modelc.getModelResource()->getModelPatches().getSize() == countComponentsOfType<RenderComponent>());
  137. ANKI_ASSERT(modelc.getModelResource()->getModelPatches().getSize() == m_renderProxies.getSize());
  138. for(U32 patchIdx = 0; patchIdx < model->getModelPatches().getSize(); ++patchIdx)
  139. {
  140. RenderComponent& rc = getNthComponentOfType<RenderComponent>(patchIdx);
  141. rc.initRaster(
  142. [](RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData) {
  143. const RenderProxy& proxy = *static_cast<const RenderProxy*>(userData[0]);
  144. const U32 modelPatchIdx = U32(&proxy - &proxy.m_node->m_renderProxies[0]);
  145. proxy.m_node->draw(ctx, userData, modelPatchIdx);
  146. },
  147. &m_renderProxies[patchIdx], modelc.getRenderMergeKeys()[patchIdx]);
  148. rc.setFlagsFromMaterial(model->getModelPatches()[patchIdx].getMaterial());
  149. if(model->getModelPatches()[patchIdx].getSupportedRayTracingTypes() != RayTypeBit::NONE)
  150. {
  151. rc.initRayTracing(
  152. [](U32 lod, const void* userData, RayTracingInstanceQueueElement& el) {
  153. const RenderProxy& proxy = *static_cast<const RenderProxy*>(userData);
  154. const U32 modelPatchIdx = U32(&proxy - &proxy.m_node->m_renderProxies[0]);
  155. proxy.m_node->setupRayTracingInstanceQueueElement(lod, modelPatchIdx, el);
  156. },
  157. &m_renderProxies[patchIdx]);
  158. }
  159. m_renderProxies[patchIdx].m_node = this;
  160. }
  161. }
  162. void ModelNode::draw(RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData, U32 modelPatchIdx) const
  163. {
  164. const U32 instanceCount = userData.getSize();
  165. ANKI_ASSERT(instanceCount > 0 && instanceCount <= MAX_INSTANCE_COUNT);
  166. ANKI_ASSERT(ctx.m_key.getInstanceCount() == instanceCount);
  167. CommandBufferPtr& cmdb = ctx.m_commandBuffer;
  168. if(ANKI_LIKELY(!ctx.m_debugDraw))
  169. {
  170. const ModelComponent& modelc = getFirstComponentOfType<ModelComponent>();
  171. const ModelPatch& patch = modelc.getModelResource()->getModelPatches()[modelPatchIdx];
  172. const SkinComponent& skinc = getFirstComponentOfType<SkinComponent>();
  173. // Transforms
  174. Array<Mat4, MAX_INSTANCE_COUNT> trfs;
  175. Array<Mat4, MAX_INSTANCE_COUNT> prevTrfs;
  176. const MoveComponent& movec = getFirstComponentOfType<MoveComponent>();
  177. trfs[0] = Mat4(movec.getWorldTransform());
  178. prevTrfs[0] = Mat4(movec.getPreviousWorldTransform());
  179. Bool moved = trfs[0] != prevTrfs[0];
  180. for(U32 i = 1; i < instanceCount; ++i)
  181. {
  182. const ModelNode& otherNode = *static_cast<const RenderProxy*>(userData[i])->m_node;
  183. const U32 otherNodeModelPatchIdx =
  184. U32(static_cast<const RenderProxy*>(userData[i]) - &otherNode.m_renderProxies[0]);
  185. (void)otherNodeModelPatchIdx;
  186. ANKI_ASSERT(otherNodeModelPatchIdx == modelPatchIdx);
  187. const MoveComponent& otherNodeMovec = otherNode.getFirstComponentOfType<MoveComponent>();
  188. trfs[i] = Mat4(otherNodeMovec.getWorldTransform());
  189. prevTrfs[i] = Mat4(otherNodeMovec.getPreviousWorldTransform());
  190. moved = moved || (trfs[i] != prevTrfs[i]);
  191. }
  192. ctx.m_key.setVelocity(moved && ctx.m_key.getPass() == Pass::GB);
  193. ctx.m_key.setSkinned(skinc.isEnabled());
  194. ModelRenderingInfo modelInf;
  195. patch.getRenderingInfo(ctx.m_key, modelInf);
  196. // Bones storage
  197. if(skinc.isEnabled())
  198. {
  199. const U32 boneCount = skinc.getBoneTransforms().getSize();
  200. StagingGpuMemoryToken token, tokenPrev;
  201. void* trfs = ctx.m_stagingGpuAllocator->allocateFrame(boneCount * sizeof(Mat4),
  202. StagingGpuMemoryType::STORAGE, token);
  203. memcpy(trfs, &skinc.getBoneTransforms()[0], boneCount * sizeof(Mat4));
  204. trfs = ctx.m_stagingGpuAllocator->allocateFrame(boneCount * sizeof(Mat4), StagingGpuMemoryType::STORAGE,
  205. tokenPrev);
  206. memcpy(trfs, &skinc.getPreviousFrameBoneTransforms()[0], boneCount * sizeof(Mat4));
  207. ANKI_ASSERT(modelInf.m_boneTransformsBinding < MAX_U32);
  208. cmdb->bindStorageBuffer(patch.getMaterial()->getDescriptorSetIndex(), modelInf.m_boneTransformsBinding,
  209. token.m_buffer, token.m_offset, token.m_range);
  210. ANKI_ASSERT(modelInf.m_prevFrameBoneTransformsBinding < MAX_U32);
  211. cmdb->bindStorageBuffer(patch.getMaterial()->getDescriptorSetIndex(),
  212. modelInf.m_prevFrameBoneTransformsBinding, tokenPrev.m_buffer, tokenPrev.m_offset,
  213. tokenPrev.m_range);
  214. }
  215. // Program
  216. cmdb->bindShaderProgram(modelInf.m_program);
  217. // Uniforms
  218. RenderComponent::allocateAndSetupUniforms(
  219. modelc.getModelResource()->getModelPatches()[modelPatchIdx].getMaterial(), ctx,
  220. ConstWeakArray<Mat4>(&trfs[0], instanceCount), ConstWeakArray<Mat4>(&prevTrfs[0], instanceCount),
  221. *ctx.m_stagingGpuAllocator);
  222. // Set attributes
  223. for(U i = 0; i < modelInf.m_vertexAttributeCount; ++i)
  224. {
  225. const ModelVertexAttribute& attrib = modelInf.m_vertexAttributes[i];
  226. ANKI_ASSERT(attrib.m_format != Format::NONE);
  227. cmdb->setVertexAttribute(U32(attrib.m_location), attrib.m_bufferBinding, attrib.m_format,
  228. attrib.m_relativeOffset);
  229. }
  230. // Set vertex buffers
  231. for(U32 i = 0; i < modelInf.m_vertexBufferBindingCount; ++i)
  232. {
  233. const ModelVertexBufferBinding& binding = modelInf.m_vertexBufferBindings[i];
  234. cmdb->bindVertexBuffer(i, binding.m_buffer, binding.m_offset, binding.m_stride, VertexStepRate::VERTEX);
  235. }
  236. // Index buffer
  237. cmdb->bindIndexBuffer(modelInf.m_indexBuffer, modelInf.m_indexBufferOffset, IndexType::U16);
  238. // Draw
  239. cmdb->drawElements(PrimitiveTopology::TRIANGLES, modelInf.m_indexCount, instanceCount, modelInf.m_firstIndex, 0,
  240. 0);
  241. }
  242. else
  243. {
  244. // Draw the bounding volumes
  245. Mat4* const mvps = ctx.m_frameAllocator.newArray<Mat4>(instanceCount);
  246. for(U32 i = 0; i < instanceCount; ++i)
  247. {
  248. const ModelNode& otherNode = *static_cast<const RenderProxy*>(userData[i])->m_node;
  249. const Aabb& box = otherNode.getFirstComponentOfType<SpatialComponent>().getAabbWorldSpace();
  250. const Vec4 tsl = (box.getMin() + box.getMax()) / 2.0f;
  251. const Vec3 scale = (box.getMax().xyz() - box.getMin().xyz()) / 2.0f;
  252. // Set non uniform scale. Add a margin to avoid flickering
  253. Mat3 nonUniScale = Mat3::getZero();
  254. constexpr F32 MARGIN = 1.02f;
  255. nonUniScale(0, 0) = scale.x() * MARGIN;
  256. nonUniScale(1, 1) = scale.y() * MARGIN;
  257. nonUniScale(2, 2) = scale.z() * MARGIN;
  258. mvps[i] = ctx.m_viewProjectionMatrix * Mat4(tsl.xyz1(), Mat3::getIdentity() * nonUniScale, 1.0f);
  259. }
  260. const Bool enableDepthTest = ctx.m_debugDrawFlags.get(RenderQueueDebugDrawFlag::DEPTH_TEST_ON);
  261. if(enableDepthTest)
  262. {
  263. cmdb->setDepthCompareOperation(CompareOperation::LESS);
  264. }
  265. else
  266. {
  267. cmdb->setDepthCompareOperation(CompareOperation::ALWAYS);
  268. }
  269. getSceneGraph().getDebugDrawer().drawCubes(
  270. ConstWeakArray<Mat4>(mvps, instanceCount), Vec4(1.0f, 0.0f, 1.0f, 1.0f), 2.0f,
  271. ctx.m_debugDrawFlags.get(RenderQueueDebugDrawFlag::DITHERED_DEPTH_TEST_ON), 2.0f,
  272. *ctx.m_stagingGpuAllocator, cmdb);
  273. ctx.m_frameAllocator.deleteArray(mvps, instanceCount);
  274. // Bones
  275. const SkinComponent& skinc = getFirstComponentOfType<SkinComponent>();
  276. if(skinc.isEnabled())
  277. {
  278. const SkinComponent& skinc = getComponentAt<SkinComponent>(0);
  279. SkeletonResourcePtr skeleton = skinc.getSkeleronResource();
  280. const U32 boneCount = skinc.getBoneTransforms().getSize();
  281. DynamicArrayAuto<Vec3> lines(ctx.m_frameAllocator);
  282. lines.resizeStorage(boneCount * 2);
  283. DynamicArrayAuto<Vec3> chidlessLines(ctx.m_frameAllocator);
  284. for(U32 i = 0; i < boneCount; ++i)
  285. {
  286. const Bone& bone = skeleton->getBones()[i];
  287. ANKI_ASSERT(bone.getIndex() == i);
  288. const Vec4 point(0.0f, 0.0f, 0.0f, 1.0f);
  289. const Bone* parent = bone.getParent();
  290. Mat4 m = (parent)
  291. ? skinc.getBoneTransforms()[parent->getIndex()] * parent->getVertexTransform().getInverse()
  292. : Mat4::getIdentity();
  293. const Vec3 a = (m * point).xyz();
  294. m = skinc.getBoneTransforms()[i] * bone.getVertexTransform().getInverse();
  295. const Vec3 b = (m * point).xyz();
  296. lines.emplaceBack(a);
  297. lines.emplaceBack(b);
  298. if(bone.getChildren().getSize() == 0)
  299. {
  300. // If there are not children try to draw something for that bone as well
  301. chidlessLines.emplaceBack(b);
  302. const F32 len = (b - a).getLength();
  303. const Vec3 c = b + (b - a).getNormalized() * len;
  304. chidlessLines.emplaceBack(c);
  305. }
  306. }
  307. const Mat4 mvp =
  308. ctx.m_viewProjectionMatrix * Mat4(getFirstComponentOfType<MoveComponent>().getWorldTransform());
  309. getSceneGraph().getDebugDrawer().drawLines(
  310. ConstWeakArray<Mat4>(&mvp, 1), Vec4(1.0f), 20.0f,
  311. ctx.m_debugDrawFlags.get(RenderQueueDebugDrawFlag::DITHERED_DEPTH_TEST_ON), lines,
  312. *ctx.m_stagingGpuAllocator, cmdb);
  313. getSceneGraph().getDebugDrawer().drawLines(
  314. ConstWeakArray<Mat4>(&mvp, 1), Vec4(0.7f, 0.7f, 0.7f, 1.0f), 5.0f,
  315. ctx.m_debugDrawFlags.get(RenderQueueDebugDrawFlag::DITHERED_DEPTH_TEST_ON), chidlessLines,
  316. *ctx.m_stagingGpuAllocator, cmdb);
  317. }
  318. // Restore state
  319. if(!enableDepthTest)
  320. {
  321. cmdb->setDepthCompareOperation(CompareOperation::LESS);
  322. }
  323. }
  324. }
  325. void ModelNode::setupRayTracingInstanceQueueElement(U32 lod, U32 modelPatchIdx,
  326. RayTracingInstanceQueueElement& el) const
  327. {
  328. const ModelComponent& modelc = getFirstComponentOfType<ModelComponent>();
  329. const ModelPatch& patch = modelc.getModelResource()->getModelPatches()[modelPatchIdx];
  330. ModelRayTracingInfo info;
  331. patch.getRayTracingInfo(lod, info);
  332. memset(&el, 0, sizeof(el));
  333. // AS
  334. el.m_bottomLevelAccelerationStructure = info.m_bottomLevelAccelerationStructure.get();
  335. // Set the descriptor
  336. el.m_modelDescriptor = info.m_descriptor;
  337. const MoveComponent& movec = getFirstComponentOfType<MoveComponent>();
  338. const Mat3x4 worldTrf(movec.getWorldTransform());
  339. memcpy(&el.m_modelDescriptor.m_worldTransform, &worldTrf, sizeof(worldTrf));
  340. el.m_modelDescriptor.m_worldRotation = movec.getWorldTransform().getRotation().getRotationPart();
  341. // Handles
  342. for(RayType type : EnumIterable<RayType>())
  343. {
  344. if(!!(patch.getMaterial()->getSupportedRayTracingTypes() & RayTypeBit(1 << type)))
  345. {
  346. el.m_shaderGroupHandleIndices[type] = info.m_shaderGroupHandleIndices[type];
  347. }
  348. else
  349. {
  350. el.m_shaderGroupHandleIndices[type] = MAX_U32;
  351. }
  352. }
  353. // References
  354. ANKI_ASSERT(info.m_grObjectReferenceCount <= el.m_grObjects.getSize());
  355. el.m_grObjectCount = info.m_grObjectReferenceCount;
  356. for(U32 i = 0; i < info.m_grObjectReferenceCount; ++i)
  357. {
  358. el.m_grObjects[i] = info.m_grObjectReferences[i].get();
  359. }
  360. }
  361. } // end namespace anki