forestCell.h
Engine/source/forest/forestCell.h
Classes:
class
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