terrCell.h

Engine/source/terrain/terrCell.h

More...

Classes:

class

The TerrCell is a single quadrant of the terrain geometry quadtree.

Public Functions

The TerrainCell vertex format optimized to 32 bytes for optimal vertex cache performance.

Detailed Description

Public Functions

GFXDeclareVertexFormat(TerrVertex )

The TerrainCell vertex format optimized to 32 bytes for optimal vertex cache performance.

  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 _TERRCELL_H_
 25#define _TERRCELL_H_
 26
 27#ifndef _GFXVERTEXBUFFER_H_
 28#include "gfx/gfxVertexBuffer.h"
 29#endif
 30#ifndef _GFXPRIMITIVEBUFFER_H_
 31#include "gfx/gfxPrimitiveBuffer.h"
 32#endif
 33#ifndef _TDICTIONARY_H_
 34#include "core/util/tDictionary.h"
 35#endif
 36#ifndef _MORIENTEDBOX_H_
 37#include "math/mOrientedBox.h"
 38#endif
 39#ifndef _BITVECTOR_H_
 40#include "core/bitVector.h"
 41#endif
 42
 43class TerrainBlock;
 44class TerrainCellMaterial;
 45class Frustum;
 46class SceneRenderState;
 47class SceneZoneSpaceManager;
 48
 49
 50/// The TerrainCell vertex format optimized to
 51/// 32 bytes for optimal vertex cache performance.
 52GFXDeclareVertexFormat( TerrVertex )
 53{
 54   /// The position.
 55   Point3F point;
 56
 57   /// The normal.
 58   Point3F normal;
 59
 60   /// The height for calculating the
 61   /// tangent vector on the GPU.
 62   F32 tangentZ;
 63
 64   /// The empty flag state which is either 
 65   /// -1 or 1 so we can do the special 
 66   /// interpolation trick.
 67   F32 empty;
 68};
 69
 70
 71/// The TerrCell is a single quadrant of the terrain geometry quadtree.
 72class TerrCell
 73{
 74protected:
 75
 76   /// The handle to the static vertex buffer which holds the 
 77   /// vertices for this cell.
 78   GFXVertexBufferHandle<TerrVertex> mVertexBuffer;
 79
 80   /// The handle to the static primitive buffer for this cell.
 81   /// It is only used if this cell has any empty squares
 82   GFXPrimitiveBufferHandle mPrimBuffer;
 83
 84   ///
 85   Point2I mPoint;
 86   
 87   ///
 88   U32 mSize;
 89
 90   /// The level of this cell within the quadtree (of cells) where
 91   /// zero is the root and one is a direct child of the root, etc.
 92   U32 mLevel;
 93
 94   /// Statics used in VB and PB generation.   
 95   static const U32 smVBStride;
 96   static const U32 smMinCellSize;
 97   static const U32 smVBSize;
 98   static const U32 smPBSize;
 99   static const U32 smTriCount;
100
101   /// Triangle count for our own primitive buffer, if any
102   U32 mTriCount;
103
104   /// Indicates if this cell has any empty squares
105   bool mHasEmpty;
106
107   /// A list of all empty vertices for this cell
108   Vector<U32> mEmptyVertexList;
109
110   /// The terrain this cell is based on.
111   TerrainBlock *mTerrain;
112
113   /// The material used to render the cell.
114   TerrainCellMaterial *mMaterial;
115
116   /// The bounding box of this cell in 
117   /// TerrainBlock object space.
118   Box3F mBounds;
119
120   /// The OBB of this cell in world space.
121   OrientedBox3F mOBB;
122
123   /// The bounding radius of this cell.
124   F32 mRadius;
125
126   /// The child cells of this one.
127   TerrCell *mChildren[4];
128
129   /// This bit flag tells us which materials effect
130   /// this cell and is used for optimizing rendering.
131   /// @see TerrainFile::mMaterialAlphaMap
132   U64 mMaterials;
133
134   /// Whether this cell is fully contained inside interior zones.
135   bool mIsInteriorOnly;
136
137   /// The zone overlap for this cell.
138   /// @note The bit for the outdoor zone is never set.
139   BitVector mZoneOverlap;
140
141   ///
142   void _updateBounds();
143
144   /// Update #mOBB from the current terrain transform state.
145   void _updateOBB();
146
147   //
148   void _init( TerrainBlock *terrain,
149               const Point2I &point,
150               U32 size,
151               U32 level );
152
153   // 
154   void _updateVertexBuffer();
155
156   //
157   void _updatePrimitiveBuffer();
158
159   // 
160   void _updateMaterials();
161
162   //
163   bool _isVertIndexEmpty( U32 index ) const;
164
165public:
166
167   TerrCell();
168   virtual ~TerrCell();
169
170   static TerrCell* init( TerrainBlock *terrain );
171
172   void getRenderPrimitive(   GFXPrimitive *prim,
173                              GFXVertexBufferHandleBase *vertBuff,
174                              GFXPrimitiveBufferHandle  *primBuff ) const;
175
176   void updateGrid( const RectI &gridRect, bool opacityOnly = false );
177
178   /// Update the world-space OBBs used for culling.
179   void updateOBBs();
180
181   ///
182   void updateZoning( const SceneZoneSpaceManager *zoneManager );
183
184   void cullCells( const SceneRenderState *state,
185                   const Point3F &objLodPos,
186                   Vector<TerrCell*> *outCells );
187
188   const Box3F& getBounds() const { return mBounds; }
189
190   /// Returns the object space sphere bounds.
191   SphereF getSphereBounds() const { return SphereF( mBounds.getCenter(), mRadius ); }
192
193   F32 getSqDistanceTo( const Point3F &pt ) const;
194
195   F32 getDistanceTo( const Point3F &pt ) const;
196
197   U64 getMaterials() const { return mMaterials; }
198
199   /// Returns a bit vector of what zones overlap this cell.
200   const BitVector& getZoneOverlap() const { return mZoneOverlap; }
201   
202   /// Forces the loading of the materials for this
203   /// cell and all its child cells.
204   void preloadMaterials();
205
206   TerrainCellMaterial* getMaterial();
207
208   /// Return true if this is a leaf cell, i.e. a cell without children.
209   bool isLeaf() const { return !mChildren[ 0 ]; }
210
211   /// Deletes the materials for this cell 
212   /// and all its children.  They will be
213   /// recreate on the next request.
214   void deleteMaterials();
215
216   U32 getSize() const { return mSize; }
217
218   Point2I getPoint() const { return mPoint; }   
219
220   /// Initializes a primitive buffer for rendering any cell.
221   static void createPrimBuffer( GFXPrimitiveBufferHandle *primBuffer );
222
223   /// Debug Rendering
224   /// @{
225
226   /// Renders the debug bounds for this cell.
227   void renderBounds() const;
228
229   /// @}
230};
231
232inline F32 TerrCell::getDistanceTo( const Point3F &pt ) const
233{
234   return ( mBounds.getCenter() - pt ).len() - mRadius;
235}
236
237inline bool TerrCell::_isVertIndexEmpty( U32 index ) const
238{
239   for ( U32 i = 0; i < mEmptyVertexList.size(); ++i )
240   {
241      if ( mEmptyVertexList[i] == index )
242      {
243         return true;
244      }
245   }
246   return false;
247}
248
249#endif // _TERRCELL_H_
250