DecalComponent.h 4.3 KB

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