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