DecalComponent.cpp 3.2 KB

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