forestCell.h

Engine/source/forest/forestCell.h

More...

Classes:

Detailed Description

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