SpatialComponent.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <anki/scene/Common.h>
  7. #include <anki/scene/SceneComponent.h>
  8. #include <anki/Collision.h>
  9. #include <anki/util/Bitset.h>
  10. #include <anki/util/Enum.h>
  11. #include <anki/util/List.h>
  12. namespace anki
  13. {
  14. // Forward
  15. class Sector;
  16. /// @addtogroup scene
  17. /// @{
  18. /// Spatial component for scene nodes. It indicates scene nodes that need to
  19. /// be placed in the a sector and they participate in the visibility tests
  20. class SpatialComponent : public SceneComponent
  21. {
  22. public:
  23. static Bool classof(const SceneComponent& c)
  24. {
  25. return c.getType() == Type::SPATIAL;
  26. }
  27. SpatialComponent(SceneNode* node, const CollisionShape* shape);
  28. ~SpatialComponent();
  29. const CollisionShape& getSpatialCollisionShape() const
  30. {
  31. return *m_shape;
  32. }
  33. const Aabb& getAabb() const
  34. {
  35. return m_aabb;
  36. }
  37. List<Sector*>& getSectorInfo()
  38. {
  39. return m_sectorInfo;
  40. }
  41. const List<Sector*>& getSectorInfo() const
  42. {
  43. return m_sectorInfo;
  44. }
  45. /// Get optimal collision shape for visibility tests
  46. const CollisionShape& getVisibilityCollisionShape()
  47. {
  48. const CollisionShape& cs = getSpatialCollisionShape();
  49. if(cs.getType() == CollisionShape::Type::SPHERE)
  50. {
  51. return cs;
  52. }
  53. else
  54. {
  55. return m_aabb;
  56. }
  57. }
  58. /// Check if it's confined in a single sector.
  59. Bool getSingleSector() const
  60. {
  61. return m_bits.bitsEnabled(Flag::SINGLE_SECTOR);
  62. }
  63. /// Confine it or not in a single sector.
  64. void setSingleSector(Bool yes)
  65. {
  66. m_bits.enableBits(Flag::SINGLE_SECTOR, yes);
  67. }
  68. /// Used for sorting spatials. In most object the origin is the center of
  69. /// mess but for cameras the origin is the eye point
  70. const Vec4& getSpatialOrigin() const
  71. {
  72. ANKI_ASSERT(m_origin.x() != MAX_F32);
  73. return m_origin;
  74. }
  75. void setSpatialOrigin(const Vec4& origin)
  76. {
  77. m_origin = origin;
  78. }
  79. /// The derived class has to manually call this method when the collision
  80. /// shape got updated
  81. void markForUpdate()
  82. {
  83. m_bits.enableBits(Flag::MARKED_FOR_UPDATE);
  84. }
  85. /// Set if visible by a camera
  86. void setVisibleByCamera(Bool visible)
  87. {
  88. m_bits.enableBits(Flag::VISIBLE_CAMERA, visible);
  89. }
  90. /// Check if visible by camera
  91. Bool getVisibleByCamera() const
  92. {
  93. return m_bits.bitsEnabled(Flag::VISIBLE_CAMERA);
  94. }
  95. /// @name SceneComponent overrides
  96. /// @{
  97. ANKI_USE_RESULT Error update(SceneNode&, F32, F32, Bool& updated) override;
  98. /// @}
  99. private:
  100. /// Spatial flags
  101. enum class Flag : U8
  102. {
  103. NONE = 0,
  104. VISIBLE_CAMERA = 1 << 1,
  105. VISIBLE_LIGHT = 1 << 2,
  106. VISIBLE_ANY = VISIBLE_CAMERA | VISIBLE_LIGHT,
  107. MARKED_FOR_UPDATE = 1 << 3,
  108. SINGLE_SECTOR = 1 << 4
  109. };
  110. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(Flag, friend)
  111. const CollisionShape* m_shape;
  112. Bitset<Flag> m_bits;
  113. Aabb m_aabb; ///< A faster shape
  114. Vec4 m_origin = Vec4(MAX_F32, MAX_F32, MAX_F32, 0.0);
  115. List<Sector*> m_sectorInfo;
  116. };
  117. /// @}
  118. } // end namespace anki