DecalComponent.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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/DecalComponent.h>
  6. #include <AnKi/Scene/SceneGraph.h>
  7. #include <AnKi/Resource/ResourceManager.h>
  8. #include <AnKi/Shaders/Include/ClusteredShadingTypes.h>
  9. namespace anki {
  10. DecalComponent::DecalComponent(SceneNode* node)
  11. : SceneComponent(node, getStaticClassId())
  12. , m_node(node)
  13. , m_spatial(this)
  14. {
  15. m_gpuSceneIndex =
  16. node->getSceneGraph().getAllGpuSceneContiguousArrays().allocate(GpuSceneContiguousArrayType::kDecals);
  17. }
  18. DecalComponent::~DecalComponent()
  19. {
  20. m_spatial.removeFromOctree(m_node->getSceneGraph().getOctree());
  21. }
  22. void DecalComponent::onDestroy(SceneNode& node)
  23. {
  24. node.getSceneGraph().getAllGpuSceneContiguousArrays().deferredFree(GpuSceneContiguousArrayType::kDecals,
  25. m_gpuSceneIndex);
  26. }
  27. void DecalComponent::setLayer(CString fname, F32 blendFactor, LayerType type)
  28. {
  29. Layer& l = m_layers[type];
  30. ImageResourcePtr rsrc;
  31. const Error err = getExternalSubsystems(*m_node).m_resourceManager->loadResource(fname, rsrc);
  32. if(err)
  33. {
  34. ANKI_SCENE_LOGE("Failed to load image");
  35. return;
  36. }
  37. m_dirty = true;
  38. l.m_image = std::move(rsrc);
  39. l.m_bindlessTextureIndex = l.m_image->getTextureView()->getOrCreateBindlessTextureIndex();
  40. l.m_blendFactor = blendFactor;
  41. }
  42. Error DecalComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
  43. {
  44. updated = m_dirty || info.m_node->movedThisFrame();
  45. if(updated)
  46. {
  47. m_dirty = false;
  48. const Vec3 halfBoxSize = m_boxSize / 2.0f;
  49. // Calculate the texture matrix
  50. const Mat4 worldTransform(info.m_node->getWorldTransform());
  51. const Mat4 viewMat = worldTransform.getInverse();
  52. const Mat4 projMat = Mat4::calculateOrthographicProjectionMatrix(halfBoxSize.x(), -halfBoxSize.x(),
  53. halfBoxSize.y(), -halfBoxSize.y(),
  54. kClusterObjectFrustumNearPlane, m_boxSize.z());
  55. const Mat4 biasMat4(0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
  56. 1.0f);
  57. m_biasProjViewMat = biasMat4 * projMat * viewMat;
  58. // Update the spatial
  59. const Vec4 center(0.0f, 0.0f, -halfBoxSize.z(), 0.0f);
  60. const Vec4 extend(halfBoxSize.x(), halfBoxSize.y(), halfBoxSize.z(), 0.0f);
  61. const Obb obbL(center, Mat3x4::getIdentity(), extend);
  62. m_obb = obbL.getTransformed(info.m_node->getWorldTransform());
  63. m_spatial.setBoundingShape(m_obb);
  64. // Upload to the GPU scene
  65. GpuSceneDecal gpuDecal;
  66. gpuDecal.m_diffuseTexture = m_layers[LayerType::kDiffuse].m_bindlessTextureIndex;
  67. gpuDecal.m_roughnessMetalnessTexture = m_layers[LayerType::kRoughnessMetalness].m_bindlessTextureIndex;
  68. gpuDecal.m_diffuseBlendFactor = m_layers[LayerType::kDiffuse].m_blendFactor;
  69. gpuDecal.m_roughnessMetalnessFactor = m_layers[LayerType::kRoughnessMetalness].m_blendFactor;
  70. gpuDecal.m_textureMatrix = m_biasProjViewMat;
  71. const Mat4 trf(m_obb.getCenter().xyz1(), m_obb.getRotation().getRotationPart(), 1.0f);
  72. gpuDecal.m_invertedTransform = trf.getInverse();
  73. gpuDecal.m_obbExtend = m_obb.getExtend().xyz();
  74. const PtrSize offset = m_gpuSceneIndex * sizeof(GpuSceneDecal)
  75. + info.m_node->getSceneGraph().getAllGpuSceneContiguousArrays().getArrayBase(
  76. GpuSceneContiguousArrayType::kDecals);
  77. GpuSceneMicroPatcher::getSingleton().newCopy(*info.m_framePool, offset, sizeof(gpuDecal), &gpuDecal);
  78. }
  79. const Bool spatialUpdated = m_spatial.update(info.m_node->getSceneGraph().getOctree());
  80. updated = updated || spatialUpdated;
  81. return Error::kNone;
  82. }
  83. } // end namespace anki