DecalComponent.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. #pragma once
  6. #include <AnKi/Scene/Components/SceneComponent.h>
  7. #include <AnKi/Resource/ImageAtlasResource.h>
  8. #include <AnKi/Collision/Obb.h>
  9. #include <AnKi/Renderer/RenderQueue.h>
  10. namespace anki {
  11. /// @addtogroup scene
  12. /// @{
  13. /// Decal component. Contains all the relevant info for a deferred decal.
  14. class DecalComponent : public SceneComponent
  15. {
  16. ANKI_SCENE_COMPONENT(DecalComponent)
  17. public:
  18. static constexpr U32 ATLAS_SUB_IMAGE_MARGIN = 16;
  19. DecalComponent(SceneNode* node);
  20. ~DecalComponent();
  21. ANKI_USE_RESULT Error setDiffuseDecal(CString texAtlasFname, CString texAtlasSubtexName, F32 blendFactor)
  22. {
  23. return setLayer(texAtlasFname, texAtlasSubtexName, blendFactor, LayerType::DIFFUSE);
  24. }
  25. ANKI_USE_RESULT Error setSpecularRoughnessDecal(CString texAtlasFname, CString texAtlasSubtexName, F32 blendFactor)
  26. {
  27. return setLayer(texAtlasFname, texAtlasSubtexName, blendFactor, LayerType::SPECULAR_ROUGHNESS);
  28. }
  29. /// Update the internal structures.
  30. void setBoxVolumeSize(const Vec3& sizeXYZ)
  31. {
  32. m_boxSize = sizeXYZ;
  33. m_markedForUpdate = true;
  34. }
  35. const Vec3& getBoxVolumeSize() const
  36. {
  37. return m_boxSize;
  38. }
  39. const Obb& getBoundingVolumeWorldSpace() const
  40. {
  41. return m_obb;
  42. }
  43. void setWorldTransform(const Transform& trf)
  44. {
  45. ANKI_ASSERT(trf.getScale() == 1.0f);
  46. m_trf = trf;
  47. m_markedForUpdate = true;
  48. }
  49. /// Implements SceneComponent::update.
  50. ANKI_USE_RESULT Error update(SceneNode& node, Second, Second, Bool& updated) override
  51. {
  52. updated = m_markedForUpdate;
  53. m_markedForUpdate = false;
  54. if(updated)
  55. {
  56. updateInternal();
  57. }
  58. return Error::NONE;
  59. }
  60. const Mat4& getBiasProjectionViewMatrix() const
  61. {
  62. return m_biasProjViewMat;
  63. }
  64. void getDiffuseAtlasInfo(Vec4& uv, TexturePtr& tex, F32& blendFactor) const
  65. {
  66. uv = m_layers[LayerType::DIFFUSE].m_uv;
  67. tex = m_layers[LayerType::DIFFUSE].m_atlas->getTexture();
  68. blendFactor = m_layers[LayerType::DIFFUSE].m_blendFactor;
  69. }
  70. void getSpecularRoughnessAtlasInfo(Vec4& uv, TexturePtr& tex, F32& blendFactor) const
  71. {
  72. uv = m_layers[LayerType::SPECULAR_ROUGHNESS].m_uv;
  73. if(m_layers[LayerType::SPECULAR_ROUGHNESS].m_atlas)
  74. {
  75. tex = m_layers[LayerType::SPECULAR_ROUGHNESS].m_atlas->getTexture();
  76. }
  77. else
  78. {
  79. tex.reset(nullptr);
  80. }
  81. blendFactor = m_layers[LayerType::SPECULAR_ROUGHNESS].m_blendFactor;
  82. }
  83. void setupDecalQueueElement(DecalQueueElement& el)
  84. {
  85. el.m_diffuseAtlas = (m_layers[LayerType::DIFFUSE].m_atlas)
  86. ? m_layers[LayerType::DIFFUSE].m_atlas->getTextureView().get()
  87. : nullptr;
  88. el.m_specularRoughnessAtlas = (m_layers[LayerType::SPECULAR_ROUGHNESS].m_atlas)
  89. ? m_layers[LayerType::SPECULAR_ROUGHNESS].m_atlas->getTextureView().get()
  90. : nullptr;
  91. el.m_diffuseAtlasUv = m_layers[LayerType::DIFFUSE].m_uv;
  92. el.m_specularRoughnessAtlasUv = m_layers[LayerType::SPECULAR_ROUGHNESS].m_uv;
  93. el.m_diffuseAtlasBlendFactor = m_layers[LayerType::DIFFUSE].m_blendFactor;
  94. el.m_specularRoughnessAtlasBlendFactor = m_layers[LayerType::SPECULAR_ROUGHNESS].m_blendFactor;
  95. el.m_textureMatrix = m_biasProjViewMat;
  96. el.m_obbCenter = m_obb.getCenter().xyz();
  97. el.m_obbExtend = m_obb.getExtend().xyz();
  98. el.m_obbRotation = m_obb.getRotation().getRotationPart();
  99. el.m_debugDrawCallback = [](RenderQueueDrawContext& ctx, ConstWeakArray<void*> userData) {
  100. ANKI_ASSERT(userData.getSize() == 1);
  101. static_cast<const DecalComponent*>(userData[0])->draw(ctx);
  102. };
  103. el.m_debugDrawCallbackUserData = this;
  104. }
  105. private:
  106. enum class LayerType : U8
  107. {
  108. DIFFUSE,
  109. SPECULAR_ROUGHNESS,
  110. COUNT
  111. };
  112. class Layer
  113. {
  114. public:
  115. ImageAtlasResourcePtr m_atlas;
  116. Vec4 m_uv = Vec4(0.0f);
  117. F32 m_blendFactor = 0.0f;
  118. };
  119. SceneNode* m_node = nullptr;
  120. Array<Layer, U(LayerType::COUNT)> m_layers;
  121. Mat4 m_biasProjViewMat = Mat4::getIdentity();
  122. Vec3 m_boxSize = Vec3(1.0f);
  123. Transform m_trf = Transform::getIdentity();
  124. Obb m_obb = Obb(Vec4(0.0f), Mat3x4::getIdentity(), Vec4(0.5f, 0.5f, 0.5f, 0.0f));
  125. ImageResourcePtr m_debugImage;
  126. Bool m_markedForUpdate = true;
  127. ANKI_USE_RESULT Error setLayer(CString texAtlasFname, CString texAtlasSubtexName, F32 blendFactor, LayerType type);
  128. void updateInternal();
  129. void draw(RenderQueueDrawContext& ctx) const;
  130. };
  131. /// @}
  132. } // end namespace anki