river.h

Engine/source/environment/river.h

More...

Classes:

Public Typedefs

RiverBatchVector 
RiverNodeVector 
RiverSegmentVector 
RiverSliceVector 

Public Functions

Detailed Description

Public Typedefs

typedef Vector< RiverRenderBatch > RiverBatchVector 
typedef Vector< RiverNode > RiverNodeVector 
typedef Vector< RiverSegment > RiverSegmentVector 
typedef Vector< RiverSlice > RiverSliceVector 

Public Variables

Point3F sSegmentPointCompareReference 

Public Functions

operator*(const F32 mul, const RiverSplineNode & multiplicand)

  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 _RIVER_H_
 25#define _RIVER_H_
 26
 27#ifndef _SCENEOBJECT_H_
 28#include "scene/sceneObject.h"
 29#endif
 30#ifndef _GFXTEXTUREHANDLE_H_
 31#include "gfx/gfxTextureHandle.h"
 32#endif
 33#ifndef _GFXVERTEXBUFFER_H_
 34#include "gfx/gfxVertexBuffer.h"
 35#endif
 36#ifndef _GFXPRIMITIVEBUFFER_H_
 37#include "gfx/gfxPrimitiveBuffer.h"
 38#endif
 39#ifndef _CLIPPEDPOLYLIST_H_
 40#include "collision/clippedPolyList.h"
 41#endif
 42#ifndef _GFXSTATEBLOCK_H_
 43#include "gfx/gfxStateBlock.h"
 44#endif
 45#ifndef _WATEROBJECT_H_
 46#include "waterObject.h"
 47#endif
 48
 49
 50
 51//-------------------------------------------------------------------------
 52// RiverSplineNode Class
 53//-------------------------------------------------------------------------
 54
 55class Path;
 56class TerrainBlock;
 57struct ObjectRenderInst;
 58
 59class RiverSplineNode
 60{
 61public:
 62   RiverSplineNode() :x(0.0f), y(0.0f), z(0.0f), width(0.0f), depth(0.0f) {}
 63
 64   F32 x;
 65   F32 y;
 66   F32 z;
 67   F32 width;
 68   F32 depth;
 69   VectorF normal;
 70
 71   RiverSplineNode& operator=(const RiverSplineNode&);
 72   RiverSplineNode operator+(const RiverSplineNode&) const;
 73   RiverSplineNode operator-(const RiverSplineNode&) const;
 74   RiverSplineNode operator*(const F32) const;
 75
 76   F32 len();
 77};
 78
 79inline F32 RiverSplineNode::len()
 80{
 81   return mSqrt(F32(x*x + y*y + z*z));
 82}
 83
 84inline RiverSplineNode& RiverSplineNode::operator=(const RiverSplineNode &_node)
 85{
 86   x = _node.x;
 87   y = _node.y;
 88   z = _node.z;
 89   width = _node.width;
 90   depth = _node.depth;
 91   normal = _node.normal;
 92   
 93   return *this;
 94}
 95
 96inline RiverSplineNode RiverSplineNode::operator+(const RiverSplineNode& _add) const
 97{
 98   RiverSplineNode result;
 99   result.x = x + _add.x;
100   result.y = y + _add.y;
101   result.z = z + _add.z;
102   result.width = width + _add.width;
103   result.depth = depth + _add.depth;
104   result.normal = normal + _add.normal;
105   
106   return result;
107}
108
109
110inline RiverSplineNode RiverSplineNode::operator-(const RiverSplineNode& _rSub) const
111{
112   RiverSplineNode result;
113   result.x = x - _rSub.x;
114   result.y = y - _rSub.y;
115   result.z = z - _rSub.z;
116   result.width = width - _rSub.width;
117   result.depth = depth - _rSub.depth;
118   result.normal = normal - _rSub.normal;
119   
120   return result;
121}
122
123inline RiverSplineNode operator*(const F32 mul, const RiverSplineNode& multiplicand)
124{
125   return multiplicand * mul;
126}
127
128inline RiverSplineNode RiverSplineNode::operator*(const F32 _mul) const
129{
130   RiverSplineNode result;
131   result.x = x * _mul;
132   result.y = y * _mul;
133   result.z = z * _mul;
134   result.width = width * _mul;
135   result.depth = depth * _mul;
136   result.normal = normal * _mul;
137
138   return result;
139}
140
141//-------------------------------------------------------------------------
142// Structures
143//-------------------------------------------------------------------------
144
145struct RiverRenderBatch
146{
147   U32 startSegmentIdx;
148   U32 endSegmentIdx;
149   U32 startVert;
150   U32 endVert;
151   U32 startIndex;
152   U32 endIndex;
153   U32 totalRows;
154   U32 indexCount;
155   
156   U32 vertCount;
157   U32 triangleCount; 
158};
159
160typedef Vector<RiverRenderBatch> RiverBatchVector;
161
162struct RiverNode
163{
164   // The 3D position of the node
165   Point3F point;
166
167   // The width of the River at this node (meters)
168   F32 width;
169
170   // The depth of the River at this node (meters)
171   F32 depth;
172
173   VectorF normal;
174};
175
176typedef Vector<RiverNode> RiverNodeVector;
177
178struct RiverSlice
179{
180   RiverSlice() 
181   {
182      p0.zero();
183      p1.zero();
184      p2.zero();
185      pb0.zero();
186      pb2.zero();
187
188      uvec.zero();
189      fvec.zero();
190      rvec.zero();
191
192      normal.zero();
193
194      width = 0.0f;
195      depth = 0.0f;
196      texCoordV = 0.0f;
197
198      parentNodeIdx = -1;
199   };
200
201   Point3F p0; // upper left
202   Point3F p1; // upper center
203   Point3F p2; // upper right
204
205   Point3F pb0; // bottom left
206   Point3F pb2; // bottom right
207
208   VectorF uvec;
209   VectorF fvec;
210   VectorF rvec;
211
212   VectorF normal;
213
214   F32 width;    
215   F32 depth;
216
217   F32 texCoordV;
218
219   U32 parentNodeIdx;
220};
221typedef Vector<RiverSlice> RiverSliceVector;
222
223//-------------------------------------------------------------------------
224// RiverSegment Class
225//-------------------------------------------------------------------------
226
227static Point3F sSegmentPointCompareReference;
228
229class RiverSegment
230{
231public:
232
233   RiverSegment();
234   RiverSegment( RiverSlice *rs0, RiverSlice *rs1 );   
235
236   void set( RiverSlice *rs0, RiverSlice *rs1 );
237
238   F32 TexCoordStart() { return slice0->texCoordV; }
239   F32 TexCoordEnd() { return slice1->texCoordV; }
240
241   Point3F getP00() const { return slice0->p0; } 
242   Point3F getP01() const { return slice1->p0; }
243   Point3F getP11() const { return slice1->p2; }
244   Point3F getP10() const { return slice0->p2; }
245
246   // NOTE:
247   // For purposes of collision testing against a RiverSegment we represent
248   // it as a set of 6 planes (one for each face) much like a frustum.
249   // This is actually a flawed representation that will be more incorrect
250   // the more twist/bend exists between the two RiverSlices making up 
251   // the segment. Basically we treat the four points that make up a "face"
252   // as if they were coplanar.
253
254   Point3F getSurfaceCenter() const { return (slice0->p1 + slice1->p1) / 2; }
255   Point3F getSurfaceNormal() const { return ( -mPlanes[4].getNormal() ); }
256   Point3F getFaceCenter( U32 faceIdx ) const;
257
258   bool intersectBox( const Box3F &bounds ) const;
259   bool containsPoint( const Point3F &pnt ) const;
260   F32 distanceToSurface( const Point3F &pnt ) const;
261
262   // Quick access to the segment's points
263   Point3F& operator[](U32);
264   const Point3F& operator[](U32) const;
265   Point3F& operator[](S32 i)              { return operator[](U32(i)); }
266   const Point3F& operator[](S32 i ) const { return operator[](U32(i)); }
267   
268   RiverSlice *slice0;
269   RiverSlice *slice1;
270
271   PlaneF mPlanes[6];
272   U32 mPlaneCount;
273
274   U32 columns;
275   U32 rows;
276
277   U32 startVert;
278   U32 endVert;
279   U32 startIndex;
280   U32 endIndex;   
281
282   U32 numVerts;
283   U32 numTriangles;
284
285   Box3F worldbounds;
286
287protected:
288
289   PlaneF _getBestPlane( const Point3F *p0, const Point3F *p1, const Point3F *p2, const Point3F *p3 );
290};
291typedef Vector<RiverSegment> RiverSegmentVector;
292
293inline Point3F& RiverSegment::operator[](U32 index)
294{
295   AssertFatal(index < 8, "RiverSegment::operator[] - out of bounds array access!");
296
297   RiverSlice *slice = NULL;
298   if ( index > 3 )
299   {
300      slice = slice1;
301      index -= 4;
302   }
303   else
304   {
305      slice = slice0;
306   }
307
308   if ( index == 0 )
309      return slice->p0;
310
311   if ( index == 1 )
312      return slice->p2;
313
314   if ( index == 2 )
315      return slice->pb0;
316
317   else //( index == 3 )
318      return slice->pb2;
319}
320
321inline const Point3F& RiverSegment::operator[](U32 index) const
322{
323   AssertFatal(index < 8, "RiverSegment::operator[] - out of bounds array access!");
324
325   RiverSlice *slice = NULL;
326   if ( index > 3 )
327   {
328      slice = slice1;
329      index -= 4;
330   }
331   else
332   {
333      slice = slice0;
334   }
335
336   if ( index == 0 )
337      return slice->p0;
338
339   if ( index == 1 )
340      return slice->p2;
341
342   if ( index == 2 )
343      return slice->pb0;
344
345   else// ( index == 3 )
346      return slice->pb2;
347}
348
349//------------------------------------------------------------------------------
350// River Class
351//------------------------------------------------------------------------------
352
353class ParticleEmitter;
354class ParticleEmitterData;
355struct RiverNodeList;
356
357class River : public WaterObject
358{
359private:
360
361   friend class GuiRiverEditorCtrl;
362   friend class GuiRiverEditorUndoAction;
363
364   typedef WaterObject Parent;      
365
366protected:
367
368   enum 
369   { 
370      RiverMask       = Parent::NextFreeMask,
371      NodeMask          = Parent::NextFreeMask << 1,      
372      RegenMask         = Parent::NextFreeMask << 2,
373      InitialUpdateMask = Parent::NextFreeMask << 3,
374      SelectedMask      = Parent::NextFreeMask << 4,
375      MaterialMask      = Parent::NextFreeMask << 5,
376      NextFreeMask      = Parent::NextFreeMask << 6,
377   };  
378
379public:   
380
381   River();
382   ~River();
383
384   DECLARE_CONOBJECT(River);
385   
386   // ConObject.
387   static void initPersistFields();
388   static void consoleInit();
389
390   // SimObject      
391   bool onAdd();
392   void onRemove();
393   void inspectPostApply();
394   void onStaticModified(const char* slotName, const char*newValue = NULL);
395   void writeFields(Stream &stream, U32 tabStop);
396   bool writeField( StringTableEntry fieldname, const char *value );
397
398   // NetObject
399   U32 packUpdate(NetConnection *, U32, BitStream *);
400   void unpackUpdate(NetConnection *, BitStream *);
401
402   // SceneObject   
403   virtual void setTransform( const MatrixF &mat );
404   virtual void setScale( const VectorF &scale );
405   virtual bool castRay(const Point3F &start, const Point3F &end, RayInfo* info);
406   virtual bool collideBox(const Point3F &start, const Point3F &end, RayInfo* info);
407   virtual bool containsPoint( const Point3F& point ) const { return containsPoint( point, NULL ); }
408   virtual bool buildPolyList( PolyListContext context, AbstractPolyList* polyList, const Box3F& box, const SphereF& sphere );
409
410   // WaterObject
411   virtual F32 getWaterCoverage( const Box3F &worldBox ) const;   
412   virtual F32 getSurfaceHeight( const Point2F &pos ) const;
413   virtual VectorF getFlow( const Point3F &pos ) const;   
414   virtual void onReflectionInfoChanged();
415   virtual void updateUnderwaterEffect( SceneRenderState *state );
416   
417   virtual bool isUnderwater( const Point3F &pnt ) const;
418   F32 distanceToSurface( const Point3F &pnt, U32 segmentIdx );
419   bool containsPoint( const Point3F &worldPos, U32 *nodeIdx ) const;
420
421   // Cast a ray against the river -- THE TOP SURFACE ONLY
422   bool collideRay( const Point3F &origin, const Point3F &direction, U32 *nodeIdx = NULL, Point3F *collisionPnt = NULL ) const;
423
424   void regenerate();
425   void setMetersPerSegment( F32 meters );
426   void setBatchSize( U32 level );
427   void setShowNodes( bool enabled );
428   void setMaxDivisionSize( F32 meters );
429   void setColumnCount( S32 count );
430
431   U32 insertNode( const Point3F &pos, const F32 &width, const F32 &depth, const VectorF &normal, const U32 &idx );
432   U32 addNode( const Point3F &pos, const F32 &width, const F32 &depth, const VectorF &normal );   
433   void setNode( const Point3F &pos, const F32 &width, const F32 &depth, const VectorF &normal, const U32 &idx );
434   void deleteNode( U32 idx );
435
436   void buildNodesFromList( RiverNodeList* list );
437
438   bool getClosestNode( const Point3F &pos, U32 &idx ) const;
439
440   Point3F getNodePosition( U32 idx ) const;
441   void setNodePosition( U32 idx, const Point3F &pos );
442
443   MatrixF getNodeTransform( U32 idx ) const;
444
445   F32 getNodeWidth( U32 idx ) const;
446   void setNodeWidth( U32 idx, F32 width );   
447
448   F32 getNodeDepth( U32 idx ) const;
449   void setNodeDepth( U32 idx, F32 depth );
450
451   void setNodeHeight( U32 idx, F32 height );
452
453   void setNodeNormal( U32 idx, const VectorF &normal );
454   VectorF getNodeNormal( U32 idx ) const;   
455
456   /// Protected 'Component' Field setter that will add a component to the list.
457   static bool addNodeFromField( void *object, const char *index, const char *data );
458
459   static SimSet* getServerSet();
460
461   static bool smEditorOpen;
462   static bool smWireframe;
463   static bool smShowWalls;
464   static bool smShowNodes;
465   static bool smShowSpline;
466   static bool smShowRiver;
467   static SimObjectPtr<SimSet> smServerRiverSet;
468
469protected:
470
471   void _loadRenderData();
472   bool _setRenderData();
473
474   void _render( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *matInst );
475
476   void _makeRenderBatches( const Point3F &cameraPos );
477   void _makeHighLODBuffers();
478
479   U32 _insertNode( const Point3F &pos, const F32 &width, const F32 &depth, const VectorF &normal, const U32 &idx );
480   U32 _addNode( const Point3F &pos, const F32 &width, const F32 &depth, const VectorF &normal );
481
482   void _regenerate();
483   void _generateSlices();
484   void _generateSegments();
485   void _generateVerts();
486
487   bool _getTerrainHeight( const Point2F &pos, F32 &height );
488   bool _getTerrainHeight( F32 x, F32 y, F32 &height ); 
489
490   // WaterObject
491   virtual void setShaderParams( SceneRenderState *state, BaseMatInstance *mat, const WaterMatParams &paramHandles );   
492   virtual void innerRender( SceneRenderState *state );
493   virtual void _getWaterPlane( const Point3F &camPos, PlaneF &outPlane, Point3F &outPos );
494
495protected:
496
497   RiverSliceVector mSlices;
498
499   RiverNodeVector mNodes;
500
501   RiverSegmentVector mSegments;
502
503   GFXVertexBufferHandle<GFXWaterVertex> mVB_high;  // the high detail vertex buffer
504   GFXVertexBufferHandle<GFXWaterVertex> mVB_low;   // the low detail vertex buffer
505
506   GFXPrimitiveBufferHandle mPB_high;  // the high detail prim buffer
507   GFXPrimitiveBufferHandle mPB_low;   // the low detail prim buffer  
508
509   RiverBatchVector mHighLODBatches;
510   RiverBatchVector mLowLODBatches;
511
512   U32 mLowVertCount;
513   U32 mHighVertCount;
514
515   U32 mLowTriangleCount;   
516   U32 mHighTriangleCount;
517
518   // Fields.
519   U32 mSegmentsPerBatch;
520   F32 mMetersPerSegment;
521   F32 mDepthScale;
522   F32 mFlowMagnitude;
523   F32 mLodDistance;
524
525   // Divide segments that are greater than this length
526   // into sections of this size, or as close as possible
527   // while maintaining an equal division size.
528   F32 mMaxDivisionSize;
529   F32 mMinDivisionSize;
530   U32 mColumnCount;    
531};
532
533#endif // _RIVER_H_
534