meshRoad.h

Engine/source/environment/meshRoad.h

More...

Classes:

Public Typedefs

MeshRoadBatchVector 
MeshRoadNodeVector 
MeshRoadSegmentVector 
MeshRoadSliceVector 

Public Functions

Detailed Description

Public Typedefs

typedef Vector< MeshRoadRenderBatch > MeshRoadBatchVector 
typedef Vector< MeshRoadNode > MeshRoadNodeVector 
typedef Vector< MeshRoadSegment > MeshRoadSegmentVector 
typedef Vector< MeshRoadSlice > MeshRoadSliceVector 

Public Functions

operator*(const F32 mul, const MeshRoadSplineNode & 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//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
 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 _MESHROAD_H_
 30#define _MESHROAD_H_
 31
 32#ifndef _SCENEOBJECT_H_
 33#include "scene/sceneObject.h"
 34#endif
 35#ifndef _GFXTEXTUREHANDLE_H_
 36#include "gfx/gfxTextureHandle.h"
 37#endif
 38#ifndef _GFXVERTEXBUFFER_H_
 39#include "gfx/gfxVertexBuffer.h"
 40#endif
 41#ifndef _GFXPRIMITIVEBUFFER_H_
 42#include "gfx/gfxPrimitiveBuffer.h"
 43#endif
 44#ifndef _CLIPPEDPOLYLIST_H_
 45#include "collision/clippedPolyList.h"
 46#endif
 47#ifndef _MATINSTANCE_H_
 48#include "materials/matInstance.h"
 49#endif
 50#ifndef _CONVEX_H_
 51#include "collision/convex.h"
 52#endif
 53
 54#include "math/util/decomposePoly.h"
 55
 56#include "T3D/assets/MaterialAsset.h"
 57
 58//extern U32 gIdxArray[6][2][3];
 59
 60struct MeshRoadHitSegment
 61{
 62   U32 idx;
 63   F32 t;
 64};
 65
 66class MeshRoad;
 67
 68class MeshRoadProfileNode
 69{
 70private:
 71   Point3F  mPos;       // The position of the node.  Only x and y are used.
 72   bool     mSmooth;    // Is the node smoothed?  Determines the normal at the node.
 73
 74public:
 75   MeshRoadProfileNode()            { mSmooth = false; }
 76   MeshRoadProfileNode(Point3F p)      { mPos = p; mSmooth = false; }
 77
 78   void setPosition(F32 x, F32 y)   { mPos.x = x; mPos.y = y; mPos.z = 0.0f; }
 79   Point3F getPosition()            { return mPos; }
 80   void setSmoothing(bool isSmooth) { mSmooth = isSmooth; }
 81   bool isSmooth()                  { return mSmooth; }
 82};
 83
 84//-------------------------------------------------------------------------
 85// MeshRoadProfile Class
 86//-------------------------------------------------------------------------
 87
 88class MeshRoadProfile
 89{
 90private:
 91   friend class GuiMeshRoadEditorCtrl;
 92   friend class MeshRoad;
 93   friend class GuiMeshRoadEditorUndoAction;
 94
 95protected:
 96   MeshRoad*                     mRoad;         // A pointer to the Road this profile belongs to
 97   Vector<MeshRoadProfileNode>   mNodes;        // The list of nodes in the profile
 98   Vector<VectorF>               mNodeNormals;  // The list of normals for each node
 99   Vector<U8>                    mSegMtrls;     // The list of segment materials
100   MatrixF                       mObjToSlice;   // Transform profile from obj to slice space
101   MatrixF                       mSliceToObj;   // Transform profile from slice to obj space
102   Point3F                       mStartPos;     // Start position of profile in world space
103   decompPoly                    mCap;          // The polygon that caps the ends
104
105public:
106   MeshRoadProfile();
107
108   S32 clickOnLine(Point3F &p);                                // In profile space
109   void addPoint(U32 nodeId, Point3F &p);                      // In profile space
110   void removePoint(U32 nodeId);
111   void setNodePosition(U32 nodeId, Point3F pos);              // In profile space
112   void toggleSmoothing(U32 nodeId);
113   void toggleSegMtrl(U32 seg);                                // Toggle between top, bottom, side
114   void generateNormals();
115   void generateEndCap(F32 width);
116   void setProfileDepth(F32 depth);
117   void setTransform(const MatrixF &mat, const Point3F &p);    // Object to slice space transform
118   void getNodeWorldPos(U32 nodeId, Point3F &p);               // Get node position in world space
119   void getNormToSlice(U32 normId, VectorF &n);                // Get normal vector in slice space
120   void getNormWorldPos(U32 normId, Point3F &p);               // Get normal end pos in world space
121   void worldToObj(Point3F &p);                                // Transform from world to obj space
122   void objToWorld(Point3F &p);                                // Transform from obj to world space
123   F32 getProfileLen();
124   F32 getNodePosPercent(U32 nodeId);
125   Vector<MeshRoadProfileNode> getNodes() { return mNodes; }
126   void resetProfile(F32 defaultDepth);                        // Reset profile to 2 default nodes
127};
128
129//-------------------------------------------------------------------------
130// MeshRoadConvex Class
131//-------------------------------------------------------------------------
132
133class MeshRoadConvex : public Convex
134{
135   typedef Convex Parent;
136   friend class MeshRoad;
137
138protected:
139
140   MeshRoad *pRoad;
141
142public:
143
144   U32 faceId;
145   U32 triangleId;
146   U32 segmentId;
147   Point3F verts[4];
148   PlaneF normal;
149   Box3F box;
150
151public:
152
153   MeshRoadConvex():pRoad(NULL), faceId(0), triangleId(0), segmentId(0) { mType = MeshRoadConvexType; }
154
155   MeshRoadConvex( const MeshRoadConvex& cv ) {
156      mType      = MeshRoadConvexType;
157      mObject    = cv.mObject;
158      pRoad      = cv.pRoad;
159      faceId     = cv.faceId;
160      triangleId = cv.triangleId;
161      segmentId  = cv.segmentId;
162      verts[0]   = cv.verts[0];
163      verts[1]   = cv.verts[1];
164      verts[2]   = cv.verts[2];
165      verts[3]   = cv.verts[3];
166      normal     = cv.normal;
167      box        = cv.box;
168   }
169
170   const MatrixF& getTransform() const;
171   Box3F getBoundingBox() const;
172   Box3F getBoundingBox(const MatrixF& mat, const Point3F& scale) const;
173   Point3F support(const VectorF& vec) const;
174   void getFeatures(const MatrixF& mat,const VectorF& n, ConvexFeature* cf);
175   void getPolyList(AbstractPolyList* list);
176};
177
178
179//-------------------------------------------------------------------------
180// MeshRoadSplineNode Class
181//-------------------------------------------------------------------------
182
183class Path;
184class TerrainBlock;
185struct ObjectRenderInst;
186
187class MeshRoadSplineNode
188{
189public:
190   MeshRoadSplineNode() :x(0.0f), y(0.0f), z(0.0f), width(0.0f), depth(0.0f) {}
191
192   F32 x;
193   F32 y;
194   F32 z;
195   F32 width;
196   F32 depth;
197   VectorF normal;
198
199   MeshRoadSplineNode& operator=(const MeshRoadSplineNode&);
200   MeshRoadSplineNode operator+(const MeshRoadSplineNode&) const;
201   MeshRoadSplineNode operator-(const MeshRoadSplineNode&) const;
202   MeshRoadSplineNode operator*(const F32) const;
203
204   F32 len();
205   Point3F getPosition() const { return Point3F(x,y,z); };
206};
207
208inline F32 MeshRoadSplineNode::len()
209{
210   return mSqrt(F32(x*x + y*y + z*z));
211}
212
213inline MeshRoadSplineNode& MeshRoadSplineNode::operator=(const MeshRoadSplineNode &_node)
214{
215   x = _node.x;
216   y = _node.y;
217   z = _node.z;
218   width = _node.width;
219   depth = _node.depth;
220   normal = _node.normal;
221
222   return *this;
223}
224
225inline MeshRoadSplineNode MeshRoadSplineNode::operator+(const MeshRoadSplineNode& _add) const
226{
227   MeshRoadSplineNode result;
228   result.x = x + _add.x;
229   result.y = y + _add.y;
230   result.z = z + _add.z;
231   result.width = width + _add.width;
232   result.depth = depth + _add.depth;
233   result.normal = normal + _add.normal;
234
235   return result;
236}
237
238
239inline MeshRoadSplineNode MeshRoadSplineNode::operator-(const MeshRoadSplineNode& _rSub) const
240{
241   MeshRoadSplineNode result;
242   result.x = x - _rSub.x;
243   result.y = y - _rSub.y;
244   result.z = z - _rSub.z;
245   result.width = width - _rSub.width;
246   result.depth = depth - _rSub.depth;
247   result.normal = normal - _rSub.normal;
248
249   return result;
250}
251
252inline MeshRoadSplineNode operator*(const F32 mul, const MeshRoadSplineNode& multiplicand)
253{
254   return multiplicand * mul;
255}
256
257inline MeshRoadSplineNode MeshRoadSplineNode::operator*(const F32 _mul) const
258{
259   MeshRoadSplineNode result;
260   result.x = x * _mul;
261   result.y = y * _mul;
262   result.z = z * _mul;
263   result.width = width * _mul;
264   result.depth = depth * _mul;
265   result.normal = normal * _mul;
266
267   return result;
268}
269
270//-------------------------------------------------------------------------
271// Structures
272//-------------------------------------------------------------------------
273
274struct MeshRoadRenderBatch
275{
276   U32 startSegmentIdx;
277   U32 endSegmentIdx;
278   U32 startVert;
279   U32 endVert;
280   U32 startIndex;
281   U32 endIndex;
282   U32 totalRows;
283   U32 indexCount;
284
285   U32 vertCount;
286   U32 triangleCount; 
287};
288
289typedef Vector<MeshRoadRenderBatch> MeshRoadBatchVector;
290
291struct MeshRoadNode
292{
293   // The 3D position of the node
294   Point3F point;
295
296   // The width of the River at this node (meters)
297   F32 width;
298
299   // The depth of the River at this node (meters)
300   F32 depth;
301
302   VectorF normal;   
303};
304
305typedef Vector<MeshRoadNode> MeshRoadNodeVector;
306
307struct MeshRoadSlice
308{
309   MeshRoadSlice() 
310   {
311      p0.zero();
312      p1.zero();
313      p2.zero();
314      pb0.zero();
315      pb2.zero();
316
317      uvec.zero();
318      fvec.zero();
319      rvec.zero();
320      
321      width = 0.0f;
322      depth = 0.0f;
323      normal.set(0,0,1);
324      texCoordV = 0.0f;
325      t = 0.0f;
326
327      parentNodeIdx = -1;
328   };
329
330   Point3F p0; // upper left
331   Point3F p1; // upper center
332   Point3F p2; // upper right
333
334   Point3F pb0; // bottom left
335   Point3F pb2; // bottom right
336
337   VectorF uvec;
338   VectorF fvec;
339   VectorF rvec;
340
341   F32 width;    
342   F32 depth;
343   Point3F normal;
344
345   F32 t;
346
347   F32 texCoordV;
348
349   U32 parentNodeIdx;
350
351   Vector<Point3F> verts;
352   Vector<VectorF> norms;
353};
354typedef Vector<MeshRoadSlice> MeshRoadSliceVector;
355
356
357//-------------------------------------------------------------------------
358// MeshRoadSegment Class
359//-------------------------------------------------------------------------
360
361class MeshRoadSegment
362{
363public:
364
365   MeshRoadSegment();
366   MeshRoadSegment( MeshRoadSlice *rs0, MeshRoadSlice *rs1, const MatrixF &roadMat );   
367
368   void set( MeshRoadSlice *rs0, MeshRoadSlice *rs1 );
369
370   F32 TexCoordStart() const { return slice0->texCoordV; }
371   F32 TexCoordEnd() const { return slice1->texCoordV; }
372
373   const Point3F& getP00() const { return slice0->p0; } 
374   const Point3F& getP01() const { return slice1->p0; }
375   const Point3F& getP11() const { return slice1->p2; }
376   const Point3F& getP10() const { return slice0->p2; }
377
378   Point3F getSurfaceCenter() const { return ( slice0->p1 + slice1->p1 ) / 2.0f; }
379   Point3F getSurfaceNormal() const { return -mPlanes[4].getNormal(); }
380
381   bool intersectBox( const Box3F &bounds ) const;
382   bool containsPoint( const Point3F &pnt ) const;
383   F32 distanceToSurface( const Point3F &pnt ) const;
384   F32 length() const { return ( slice1->p1 - slice0->p1 ).len(); }
385
386   // Quick access to the segment's points
387   Point3F& operator[](U32);
388   const Point3F& operator[](U32) const;
389   Point3F& operator[](S32 i)              { return operator[](U32(i)); }
390   const Point3F& operator[](S32 i ) const { return operator[](U32(i)); }
391
392   const Box3F& getWorldBounds() const { return worldbounds; }
393
394   MeshRoadSlice *slice0;
395   MeshRoadSlice *slice1;
396
397protected:
398
399   PlaneF mPlanes[6];
400   U32 mPlaneCount;
401
402   U32 columns;
403   U32 rows;
404
405   U32 startVert;
406   U32 endVert;
407   U32 startIndex;
408   U32 endIndex;   
409
410   U32 numVerts;
411   U32 numTriangles;
412
413   Box3F objectbounds;
414   Box3F worldbounds;
415};
416
417typedef Vector<MeshRoadSegment> MeshRoadSegmentVector;
418
419
420inline Point3F& MeshRoadSegment::operator[](U32 index)
421{
422   AssertFatal(index < 8, "MeshRoadSegment::operator[] - out of bounds array access!");
423
424   MeshRoadSlice *slice = NULL;
425   if ( index > 3 )
426   {
427      slice = slice1;
428      index -= 4;
429   }
430   else
431   {
432      slice = slice0;
433   }
434
435   if ( index == 0 )
436      return slice->p0;
437
438   if ( index == 1 )
439      return slice->p2;
440
441   if ( index == 2 )
442      return slice->pb0;
443
444   else //( index == 3 )
445      return slice->pb2;
446}
447
448inline const Point3F& MeshRoadSegment::operator[](U32 index) const
449{
450   AssertFatal(index < 8, "MeshRoadSegment::operator[] - out of bounds array access!");
451
452   MeshRoadSlice *slice = NULL;
453   if ( index > 3 )
454   {
455      slice = slice1;
456      index -= 4;
457   }
458   else
459   {
460      slice = slice0;
461   }
462
463   if ( index == 0 )
464      return slice->p0;
465
466   if ( index == 1 )
467      return slice->p2;
468
469   if ( index == 2 )
470      return slice->pb0;
471
472   else// ( index == 3 )
473      return slice->pb2;
474}
475
476
477//------------------------------------------------------------------------------
478// MeshRoad Class
479//------------------------------------------------------------------------------
480
481class PhysicsBody;
482struct MeshRoadNodeList;
483
484class MeshRoad : public SceneObject
485{
486private:
487
488   friend class GuiMeshRoadEditorCtrl;
489   friend class GuiMeshRoadEditorUndoAction;
490   friend class MeshRoadConvex;
491   friend class MeshRoadProfile;
492
493   typedef SceneObject     Parent;
494
495   enum 
496   { 
497      MeshRoadMask      = Parent::NextFreeMask,
498      NodeMask          = Parent::NextFreeMask << 1,      
499      RegenMask         = Parent::NextFreeMask << 2,
500      InitialUpdateMask = Parent::NextFreeMask << 3,
501      SelectedMask      = Parent::NextFreeMask << 4,
502      MaterialMask      = Parent::NextFreeMask << 5,
503      ProfileMask       = Parent::NextFreeMask << 6,
504      NextFreeMask      = Parent::NextFreeMask << 7,
505   };   
506
507public:
508
509   MeshRoad();
510   ~MeshRoad();
511
512   DECLARE_CONOBJECT(MeshRoad);
513
514   // ConObject.
515   static void initPersistFields();
516   static void consoleInit();
517
518   // SimObject      
519   bool onAdd();
520   void onRemove();
521   void onEditorEnable();
522   void onEditorDisable();
523   void inspectPostApply();
524   void onStaticModified(const char* slotName, const char*newValue = NULL);
525   void writeFields(Stream &stream, U32 tabStop);
526   bool writeField( StringTableEntry fieldname, const char *value );
527
528   // NetObject
529   U32 packUpdate(NetConnection *, U32, BitStream *);
530   void unpackUpdate(NetConnection *, BitStream *);
531
532   // SceneObject
533   virtual void prepRenderImage( SceneRenderState* sceneState );
534   virtual void setTransform( const MatrixF &mat );
535   virtual void setScale( const VectorF &scale );
536
537   // SceneObject - Collision
538   virtual void buildConvex(const Box3F& box,Convex* convex);
539   virtual bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF &sphere);
540   virtual bool castRay(const Point3F &start, const Point3F &end, RayInfo* info);
541   virtual bool collideBox(const Point3F &start, const Point3F &end, RayInfo* info);
542
543   // MeshRoad
544   void regenerate();   
545   void setBatchSize( U32 level );
546   void setTextureFile( StringTableEntry file );
547   void setTextureRepeat( F32 meters );
548
549   bool collideRay( const Point3F &origin, const Point3F &direction, U32 *nodeIdx = NULL, Point3F *collisionPnt = NULL );
550   bool buildSegmentPolyList( AbstractPolyList* polyList, U32 startSegIdx, U32 endSegIdx, bool capFront, bool capEnd );
551
552   void buildNodesFromList( MeshRoadNodeList* list );
553
554   U32 insertNode( const Point3F &pos, const F32 &width, const F32 &depth, const Point3F &normal, const U32 &idx );
555   U32 addNode( const Point3F &pos, const F32 &width, const F32 &depth, const Point3F &normal );   
556   void deleteNode( U32 idx );
557
558   void setNode( const Point3F &pos, const F32 &width, const F32 &depth, const Point3F &normal, const U32 &idx );
559
560   const MeshRoadNode& getNode( U32 idx );
561   VectorF getNodeNormal( U32 idx );
562   void setNodeNormal( U32 idx, const VectorF &normal );
563   Point3F getNodePosition( U32 idx );
564   void setNodePosition( U32 idx, const Point3F &pos );
565   F32 getNodeWidth( U32 idx );
566   void setNodeWidth( U32 idx, F32 width );   
567   F32 getNodeDepth( U32 idx );
568   void setNodeDepth( U32 idx, F32 depth );
569   MatrixF getNodeTransform( U32 idx );
570   void calcSliceTransform( U32 idx, MatrixF &mat );
571   bool isEndNode( U32 idx ) { return ( mNodes.size() > 0 && ( idx == 0 || idx == mNodes.size() - 1 ) ); }
572
573   U32 getSegmentCount() { return mSegments.size(); }
574   const MeshRoadSegment& getSegment( U32 idx ) { return mSegments[idx]; }
575
576   F32 getRoadLength() const;
577
578   static SimSet* getServerSet();
579
580   /// Protected 'Component' Field setter that will add a component to the list.
581   static bool addNodeFromField( void *object, const char *index, const char *data );
582   static bool addProfileNodeFromField(void *obj, const char *index, const char* data);
583
584   static bool smEditorOpen;
585   static bool smWireframe;
586   static bool smShowBatches;
587   static bool smShowSpline;
588   static bool smShowRoad;
589   static bool smShowRoadProfile;
590   static SimObjectPtr<SimSet> smServerMeshRoadSet;   
591
592protected:
593
594   void _initMaterial();
595
596   void _debugRender( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance* );
597
598   U32 _insertNode( const Point3F &pos, const F32 &width, const F32 &depth, const Point3F &normal, const U32 &idx );
599   U32 _addNode( const Point3F &pos, const F32 &width, const F32 &depth, const Point3F &normal );
600
601   void _regenerate();
602   void _generateSlices();
603   void _generateSegments();
604   void _generateVerts();   
605
606protected:
607
608   MeshRoadSliceVector mSlices;
609   MeshRoadNodeVector mNodes;
610   MeshRoadSegmentVector mSegments;
611   MeshRoadBatchVector mBatches;
612   
613   static GFXStateBlockRef smWireframeSB;
614
615   enum { 
616      Top = 0, 
617      Bottom = 1, 
618      Side = 2,
619      SurfaceCount = 3
620   };
621
622   GFXVertexBufferHandle<GFXVertexPNTT> mVB[SurfaceCount];   
623   GFXPrimitiveBufferHandle mPB[SurfaceCount];      
624
625   DECLARE_NET_MATERIALASSET(MeshRoad, TopMaterial, MeshRoadMask);
626   DECLARE_NET_MATERIALASSET(MeshRoad, BottomMaterial, MeshRoadMask);
627   DECLARE_NET_MATERIALASSET(MeshRoad, SideMaterial, MeshRoadMask);
628
629   //String mMaterialName[SurfaceCount];   
630   SimObjectPtr<Material> mMaterial[SurfaceCount];
631   BaseMatInstance *mMatInst[SurfaceCount];
632
633   U32 mVertCount[SurfaceCount];
634   U32 mTriangleCount[SurfaceCount];   
635
636   MeshRoadProfile mSideProfile;
637      
638   // Fields.
639   F32 mTextureLength;
640   F32 mBreakAngle;
641   S32 mWidthSubdivisions;
642   
643   // Collision and Physics.
644   Convex* mConvexList;
645   Vector<MeshRoadConvex*> mDebugConvex;
646   PhysicsBody *mPhysicsRep;
647private:
648   static bool buildPolyList_TopSurfaceOnly;
649public:
650   bool buildTopPolyList(PolyListContext, AbstractPolyList*);
651};
652
653
654#endif // _MESHROAD_H_
655