123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #ifndef _FORESTCELL_H_
- #define _FORESTCELL_H_
- #ifndef _FORESTITEM_H_
- #include "forest/forestItem.h"
- #endif
- #ifndef _H_FOREST_
- #include "forest/forest.h"
- #endif
- #ifndef _BITVECTOR_H_
- #include "core/bitVector.h"
- #endif
- class ForestCellBatch;
- class SceneRenderState;
- class Frustum;
- class IForestCellCollision;
- class PhysicsBody;
- //class ForestRayInfo;
- ///
- class ForestCell
- {
- friend class Forest;
- protected:
- /// The area which this cell represents in the world.
- RectF mRect;
- /// If items have been added or removed the dirty flag
- /// is set so that the bounds can be rebuilt on the next
- /// request.
- bool mIsDirty;
- /// The combined bounding box of all the items
- /// in or children of this cell.
- Box3F mBounds;
- /// All the items in this cell.
- Vector<ForestItem> mItems;
- /// A vector of the current batches
- /// associated with this cell.
- Vector<ForestCellBatch*> mBatches;
- /// The largest item in this cell.
- ForestItem mLargestItem;
-
- /// PhysicsBody for client and server for all trees in this ForestCell,
- /// if it is a leaf cell.
- PhysicsBody *mPhysicsRep[2];
- /// The quad tree cells below this one which
- /// may contain sub elements.
- ForestCell* mSubCells[4];
- /// The zone overlap for this cell.
- /// @note The bit for the outdoor zone is never set.
- BitVector mZoneOverlap;
- /// Whether this cell is fully contained inside interior zones.
- bool mIsInteriorOnly;
- ///
- inline U32 _getSubCell( F32 x, F32 y ) const
- {
- bool left = x < ( mRect.point.x + ( mRect.extent.x / 2.0f ) );
- bool top = y < ( mRect.point.y + ( mRect.extent.y / 2.0f ) );
- if ( left && top ) return 0;
- if ( left && !top ) return 1;
- if ( !left && top ) return 2;
- return 3;
- }
- ///
- inline RectF _makeChildRect( U32 index ) const
- {
- RectF rect( mRect.point, mRect.extent / 2.0f );
- if ( index == 1 || index == 3 )
- rect.point.y += rect.extent.y;
- if ( index > 1 )
- rect.point.x += rect.extent.x;
- return rect;
- }
- void _updateBounds();
- ///
- void _updateZoning( const SceneZoneSpaceManager *zoneManager );
- public:
- /// The maximum amount of objects allowed in a
- /// cell before we repartition it.
- static const U32 MaxItems = 200;
- ForestCell( const RectF &rect );
- virtual ~ForestCell();
- /// Returns the 2D rectangle of quad tree bounds for this
- /// cell. It is fixed and does not change during runtime.
- const RectF& getRect() const { return mRect; }
- /// The bounds of the cell generated by combining the
- /// bounds of all the contained items or child cells.
- const Box3F& getBounds() const;
- /// Set flag so this cells bounds will be recalculated the next call to getBounds.
- void invalidateBounds() { mIsDirty = true; }
- /// Returns true if this cell has no items and no child cells.
- bool isEmpty() const { return isLeaf() && mItems.empty(); }
- /// Returns true if this cell does not have child cells.
- /// It should directly contain items.
- bool isLeaf() const { return !mSubCells[0]; }
- /// Returns true if this cell has child cells.
- /// This is the same as !isLeaf() but exists for clarity.
- bool isBranch() const { return mSubCells[0] != NULL; }
- /// Returns a bit vector of what zones overlap this cell.
- const BitVector& getZoneOverlap() const { return mZoneOverlap; }
- ///
- bool castRay( const Point3F &start, const Point3F &end, RayInfo *outInfo, bool rendered ) const;
- bool hasBatches() const { return !mBatches.empty(); }
- void buildBatches();
- void freeBatches();
- S32 renderBatches( SceneRenderState *state, Frustum *culler );
- S32 render( TSRenderState *rdata, const Frustum *culler );
- /// The find function does a binary search thru the sorted
- /// item list. If the key is found then the index is the
- /// position of the item. If the key is not found the index
- /// is the correct insertion position for adding the new item.
- ///
- /// @param key The item key to search for.
- ///
- /// @param outIndex The item index or insertion index if
- /// the item was not found.
- ///
- /// @return Returns true if the item index is found.
- ///
- bool findIndexByKey( ForestItemKey key, U32 *outIndex ) const;
- const ForestItem& getLargestItem() const { return mLargestItem; }
- const ForestItem& insertItem( ForestItemKey key,
- ForestItemData *data,
- const MatrixF &xfm,
- F32 scale );
- bool removeItem( ForestItemKey key, const Point3F &keyPos, bool deleteIfEmpty = false );
- /// Returns the child cell at the position. The position is
- /// assumed to be within this cell.
- ForestCell* getChildAt( const Point3F &pos ) const;
- /// Returns the child cells.
- void getChildren( Vector<ForestCell*> *outCells ) const { outCells->merge( mSubCells, 4 ); }
- void getChildren( Vector<const ForestCell*> *outCells ) const { outCells->merge( mSubCells, 4 ); }
- /// Returns the items from this one cell.
- const Vector<ForestItem>& getItems() const { return mItems; }
- /// Returns the items from this cell and all its sub-cells.
- void getItems( Vector<ForestItem> *outItems ) const;
- void clearPhysicsRep( Forest *forest );
- void buildPhysicsRep( Forest *forest );
- };
- inline const Box3F& ForestCell::getBounds() const
- {
- if ( mIsDirty )
- const_cast<ForestCell*>( this )->_updateBounds();
- return mBounds;
- }
- inline ForestCell* ForestCell::getChildAt( const Point3F &pos ) const
- {
- U32 index = _getSubCell( pos.x, pos.y );
- return mSubCells[index];
- }
- #endif // _FORESTCELL_H_
|