forestCell.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _FORESTCELL_H_
  23. #define _FORESTCELL_H_
  24. #ifndef _FORESTITEM_H_
  25. #include "forest/forestItem.h"
  26. #endif
  27. #ifndef _H_FOREST_
  28. #include "forest/forest.h"
  29. #endif
  30. #ifndef _BITVECTOR_H_
  31. #include "core/bitVector.h"
  32. #endif
  33. class ForestCellBatch;
  34. class SceneRenderState;
  35. class Frustum;
  36. class IForestCellCollision;
  37. class PhysicsBody;
  38. //class ForestRayInfo;
  39. ///
  40. class ForestCell
  41. {
  42. friend class Forest;
  43. protected:
  44. /// The area which this cell represents in the world.
  45. RectF mRect;
  46. /// If items have been added or removed the dirty flag
  47. /// is set so that the bounds can be rebuilt on the next
  48. /// request.
  49. bool mIsDirty;
  50. /// The combined bounding box of all the items
  51. /// in or children of this cell.
  52. Box3F mBounds;
  53. /// All the items in this cell.
  54. Vector<ForestItem> mItems;
  55. /// A vector of the current batches
  56. /// associated with this cell.
  57. Vector<ForestCellBatch*> mBatches;
  58. /// The largest item in this cell.
  59. ForestItem mLargestItem;
  60. /// PhysicsBody for client and server for all trees in this ForestCell,
  61. /// if it is a leaf cell.
  62. PhysicsBody *mPhysicsRep[2];
  63. /// The quad tree cells below this one which
  64. /// may contain sub elements.
  65. ForestCell* mSubCells[4];
  66. /// The zone overlap for this cell.
  67. /// @note The bit for the outdoor zone is never set.
  68. BitVector mZoneOverlap;
  69. /// Whether this cell is fully contained inside interior zones.
  70. bool mIsInteriorOnly;
  71. ///
  72. inline U32 _getSubCell( F32 x, F32 y ) const
  73. {
  74. bool left = x < ( mRect.point.x + ( mRect.extent.x / 2.0f ) );
  75. bool top = y < ( mRect.point.y + ( mRect.extent.y / 2.0f ) );
  76. if ( left && top ) return 0;
  77. if ( left && !top ) return 1;
  78. if ( !left && top ) return 2;
  79. return 3;
  80. }
  81. ///
  82. inline RectF _makeChildRect( U32 index ) const
  83. {
  84. RectF rect( mRect.point, mRect.extent / 2.0f );
  85. if ( index == 1 || index == 3 )
  86. rect.point.y += rect.extent.y;
  87. if ( index > 1 )
  88. rect.point.x += rect.extent.x;
  89. return rect;
  90. }
  91. void _updateBounds();
  92. ///
  93. void _updateZoning( const SceneZoneSpaceManager *zoneManager );
  94. public:
  95. /// The maximum amount of objects allowed in a
  96. /// cell before we repartition it.
  97. static const U32 MaxItems = 200;
  98. ForestCell( const RectF &rect );
  99. virtual ~ForestCell();
  100. /// Returns the 2D rectangle of quad tree bounds for this
  101. /// cell. It is fixed and does not change during runtime.
  102. const RectF& getRect() const { return mRect; }
  103. /// The bounds of the cell generated by combining the
  104. /// bounds of all the contained items or child cells.
  105. const Box3F& getBounds() const;
  106. /// Set flag so this cells bounds will be recalculated the next call to getBounds.
  107. void invalidateBounds() { mIsDirty = true; }
  108. /// Returns true if this cell has no items and no child cells.
  109. bool isEmpty() const { return isLeaf() && mItems.empty(); }
  110. /// Returns true if this cell does not have child cells.
  111. /// It should directly contain items.
  112. bool isLeaf() const { return !mSubCells[0]; }
  113. /// Returns true if this cell has child cells.
  114. /// This is the same as !isLeaf() but exists for clarity.
  115. bool isBranch() const { return mSubCells[0] != NULL; }
  116. /// Returns a bit vector of what zones overlap this cell.
  117. const BitVector& getZoneOverlap() const { return mZoneOverlap; }
  118. ///
  119. bool castRay( const Point3F &start, const Point3F &end, RayInfo *outInfo, bool rendered ) const;
  120. bool hasBatches() const { return !mBatches.empty(); }
  121. void buildBatches();
  122. void freeBatches();
  123. S32 renderBatches( SceneRenderState *state, Frustum *culler );
  124. S32 render( TSRenderState *rdata, const Frustum *culler );
  125. /// The find function does a binary search thru the sorted
  126. /// item list. If the key is found then the index is the
  127. /// position of the item. If the key is not found the index
  128. /// is the correct insertion position for adding the new item.
  129. ///
  130. /// @param key The item key to search for.
  131. ///
  132. /// @param outIndex The item index or insertion index if
  133. /// the item was not found.
  134. ///
  135. /// @return Returns true if the item index is found.
  136. ///
  137. bool findIndexByKey( ForestItemKey key, U32 *outIndex ) const;
  138. const ForestItem& getLargestItem() const { return mLargestItem; }
  139. const ForestItem& insertItem( ForestItemKey key,
  140. ForestItemData *data,
  141. const MatrixF &xfm,
  142. F32 scale );
  143. bool removeItem( ForestItemKey key, const Point3F &keyPos, bool deleteIfEmpty = false );
  144. /// Returns the child cell at the position. The position is
  145. /// assumed to be within this cell.
  146. ForestCell* getChildAt( const Point3F &pos ) const;
  147. /// Returns the child cells.
  148. void getChildren( Vector<ForestCell*> *outCells ) const { outCells->merge( mSubCells, 4 ); }
  149. void getChildren( Vector<const ForestCell*> *outCells ) const { outCells->merge( mSubCells, 4 ); }
  150. /// Returns the items from this one cell.
  151. const Vector<ForestItem>& getItems() const { return mItems; }
  152. /// Returns the items from this cell and all its sub-cells.
  153. void getItems( Vector<ForestItem> *outItems ) const;
  154. void clearPhysicsRep( Forest *forest );
  155. void buildPhysicsRep( Forest *forest );
  156. };
  157. inline const Box3F& ForestCell::getBounds() const
  158. {
  159. if ( mIsDirty )
  160. const_cast<ForestCell*>( this )->_updateBounds();
  161. return mBounds;
  162. }
  163. inline ForestCell* ForestCell::getChildAt( const Point3F &pos ) const
  164. {
  165. U32 index = _getSubCell( pos.x, pos.y );
  166. return mSubCells[index];
  167. }
  168. #endif // _FORESTCELL_H_