123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658 |
- //-----------------------------------------------------------------------------
- // 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.
- //-----------------------------------------------------------------------------
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- // Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
- // Copyright (C) 2015 Faust Logic, Inc.
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- #ifndef _MESHROAD_H_
- #define _MESHROAD_H_
- #ifndef _SCENEOBJECT_H_
- #include "scene/sceneObject.h"
- #endif
- #ifndef _GFXTEXTUREHANDLE_H_
- #include "gfx/gfxTextureHandle.h"
- #endif
- #ifndef _GFXVERTEXBUFFER_H_
- #include "gfx/gfxVertexBuffer.h"
- #endif
- #ifndef _GFXPRIMITIVEBUFFER_H_
- #include "gfx/gfxPrimitiveBuffer.h"
- #endif
- #ifndef _CLIPPEDPOLYLIST_H_
- #include "collision/clippedPolyList.h"
- #endif
- #ifndef _MATINSTANCE_H_
- #include "materials/matInstance.h"
- #endif
- #ifndef _CONVEX_H_
- #include "collision/convex.h"
- #endif
- #include "math/util/decomposePoly.h"
- #include "T3D/assets/MaterialAsset.h"
- //extern U32 gIdxArray[6][2][3];
- struct MeshRoadHitSegment
- {
- U32 idx;
- F32 t;
- };
- class MeshRoad;
- class MeshRoadProfileNode
- {
- private:
- Point3F mPos; // The position of the node. Only x and y are used.
- bool mSmooth; // Is the node smoothed? Determines the normal at the node.
- public:
- MeshRoadProfileNode() { mSmooth = false; }
- MeshRoadProfileNode(Point3F p) { mPos = p; mSmooth = false; }
- void setPosition(F32 x, F32 y) { mPos.x = x; mPos.y = y; mPos.z = 0.0f; }
- Point3F getPosition() { return mPos; }
- void setSmoothing(bool isSmooth) { mSmooth = isSmooth; }
- bool isSmooth() { return mSmooth; }
- };
- //-------------------------------------------------------------------------
- // MeshRoadProfile Class
- //-------------------------------------------------------------------------
- class MeshRoadProfile
- {
- private:
- friend class GuiMeshRoadEditorCtrl;
- friend class MeshRoad;
- friend class GuiMeshRoadEditorUndoAction;
- protected:
- MeshRoad* mRoad; // A pointer to the Road this profile belongs to
- Vector<MeshRoadProfileNode> mNodes; // The list of nodes in the profile
- Vector<VectorF> mNodeNormals; // The list of normals for each node
- Vector<U8> mSegMtrls; // The list of segment materials
- MatrixF mObjToSlice; // Transform profile from obj to slice space
- MatrixF mSliceToObj; // Transform profile from slice to obj space
- Point3F mStartPos; // Start position of profile in world space
- decompPoly mCap; // The polygon that caps the ends
- public:
- MeshRoadProfile();
- S32 clickOnLine(Point3F &p); // In profile space
- void addPoint(U32 nodeId, Point3F &p); // In profile space
- void removePoint(U32 nodeId);
- void setNodePosition(U32 nodeId, Point3F pos); // In profile space
- void toggleSmoothing(U32 nodeId);
- void toggleSegMtrl(U32 seg); // Toggle between top, bottom, side
- void generateNormals();
- void generateEndCap(F32 width);
- void setProfileDepth(F32 depth);
- void setTransform(const MatrixF &mat, const Point3F &p); // Object to slice space transform
- void getNodeWorldPos(U32 nodeId, Point3F &p); // Get node position in world space
- void getNormToSlice(U32 normId, VectorF &n); // Get normal vector in slice space
- void getNormWorldPos(U32 normId, Point3F &p); // Get normal end pos in world space
- void worldToObj(Point3F &p); // Transform from world to obj space
- void objToWorld(Point3F &p); // Transform from obj to world space
- F32 getProfileLen();
- F32 getNodePosPercent(U32 nodeId);
- Vector<MeshRoadProfileNode> getNodes() { return mNodes; }
- void resetProfile(F32 defaultDepth); // Reset profile to 2 default nodes
- };
- //-------------------------------------------------------------------------
- // MeshRoadConvex Class
- //-------------------------------------------------------------------------
- class MeshRoadConvex : public Convex
- {
- typedef Convex Parent;
- friend class MeshRoad;
- protected:
- MeshRoad *pRoad;
- public:
- U32 faceId;
- U32 triangleId;
- U32 segmentId;
- Point3F verts[4];
- PlaneF normal;
- Box3F box;
- public:
- MeshRoadConvex():pRoad(NULL), faceId(0), triangleId(0), segmentId(0) { mType = MeshRoadConvexType; }
- MeshRoadConvex( const MeshRoadConvex& cv ) {
- mType = MeshRoadConvexType;
- mObject = cv.mObject;
- pRoad = cv.pRoad;
- faceId = cv.faceId;
- triangleId = cv.triangleId;
- segmentId = cv.segmentId;
- verts[0] = cv.verts[0];
- verts[1] = cv.verts[1];
- verts[2] = cv.verts[2];
- verts[3] = cv.verts[3];
- normal = cv.normal;
- box = cv.box;
- }
- const MatrixF& getTransform() const;
- Box3F getBoundingBox() const;
- Box3F getBoundingBox(const MatrixF& mat, const Point3F& scale) const;
- Point3F support(const VectorF& vec) const;
- void getFeatures(const MatrixF& mat,const VectorF& n, ConvexFeature* cf);
- void getPolyList(AbstractPolyList* list);
- };
- //-------------------------------------------------------------------------
- // MeshRoadSplineNode Class
- //-------------------------------------------------------------------------
- class Path;
- class TerrainBlock;
- struct ObjectRenderInst;
- class MeshRoadSplineNode
- {
- public:
- MeshRoadSplineNode() :x(0.0f), y(0.0f), z(0.0f), width(0.0f), depth(0.0f) {}
- F32 x;
- F32 y;
- F32 z;
- F32 width;
- F32 depth;
- VectorF normal;
- MeshRoadSplineNode& operator=(const MeshRoadSplineNode&);
- MeshRoadSplineNode operator+(const MeshRoadSplineNode&) const;
- MeshRoadSplineNode operator-(const MeshRoadSplineNode&) const;
- MeshRoadSplineNode operator*(const F32) const;
- F32 len();
- Point3F getPosition() const { return Point3F(x,y,z); };
- };
- inline F32 MeshRoadSplineNode::len()
- {
- return mSqrt(F32(x*x + y*y + z*z));
- }
- inline MeshRoadSplineNode& MeshRoadSplineNode::operator=(const MeshRoadSplineNode &_node)
- {
- x = _node.x;
- y = _node.y;
- z = _node.z;
- width = _node.width;
- depth = _node.depth;
- normal = _node.normal;
- return *this;
- }
- inline MeshRoadSplineNode MeshRoadSplineNode::operator+(const MeshRoadSplineNode& _add) const
- {
- MeshRoadSplineNode result;
- result.x = x + _add.x;
- result.y = y + _add.y;
- result.z = z + _add.z;
- result.width = width + _add.width;
- result.depth = depth + _add.depth;
- result.normal = normal + _add.normal;
- return result;
- }
- inline MeshRoadSplineNode MeshRoadSplineNode::operator-(const MeshRoadSplineNode& _rSub) const
- {
- MeshRoadSplineNode result;
- result.x = x - _rSub.x;
- result.y = y - _rSub.y;
- result.z = z - _rSub.z;
- result.width = width - _rSub.width;
- result.depth = depth - _rSub.depth;
- result.normal = normal - _rSub.normal;
- return result;
- }
- inline MeshRoadSplineNode operator*(const F32 mul, const MeshRoadSplineNode& multiplicand)
- {
- return multiplicand * mul;
- }
- inline MeshRoadSplineNode MeshRoadSplineNode::operator*(const F32 _mul) const
- {
- MeshRoadSplineNode result;
- result.x = x * _mul;
- result.y = y * _mul;
- result.z = z * _mul;
- result.width = width * _mul;
- result.depth = depth * _mul;
- result.normal = normal * _mul;
- return result;
- }
- //-------------------------------------------------------------------------
- // Structures
- //-------------------------------------------------------------------------
- struct MeshRoadRenderBatch
- {
- U32 startSegmentIdx;
- U32 endSegmentIdx;
- U32 startVert;
- U32 endVert;
- U32 startIndex;
- U32 endIndex;
- U32 totalRows;
- U32 indexCount;
- U32 vertCount;
- U32 triangleCount;
- };
- typedef Vector<MeshRoadRenderBatch> MeshRoadBatchVector;
- struct MeshRoadNode
- {
- // The 3D position of the node
- Point3F point;
- // The width of the River at this node (meters)
- F32 width;
- // The depth of the River at this node (meters)
- F32 depth;
- VectorF normal;
- };
- typedef Vector<MeshRoadNode> MeshRoadNodeVector;
- struct MeshRoadSlice
- {
- MeshRoadSlice()
- {
- p0.zero();
- p1.zero();
- p2.zero();
- pb0.zero();
- pb2.zero();
- uvec.zero();
- fvec.zero();
- rvec.zero();
-
- width = 0.0f;
- depth = 0.0f;
- normal.set(0,0,1);
- texCoordV = 0.0f;
- t = 0.0f;
- parentNodeIdx = -1;
- };
- Point3F p0; // upper left
- Point3F p1; // upper center
- Point3F p2; // upper right
- Point3F pb0; // bottom left
- Point3F pb2; // bottom right
- VectorF uvec;
- VectorF fvec;
- VectorF rvec;
- F32 width;
- F32 depth;
- Point3F normal;
- F32 t;
- F32 texCoordV;
- U32 parentNodeIdx;
- Vector<Point3F> verts;
- Vector<VectorF> norms;
- };
- typedef Vector<MeshRoadSlice> MeshRoadSliceVector;
- //-------------------------------------------------------------------------
- // MeshRoadSegment Class
- //-------------------------------------------------------------------------
- class MeshRoadSegment
- {
- public:
- MeshRoadSegment();
- MeshRoadSegment( MeshRoadSlice *rs0, MeshRoadSlice *rs1, const MatrixF &roadMat );
- void set( MeshRoadSlice *rs0, MeshRoadSlice *rs1 );
- F32 TexCoordStart() const { return slice0->texCoordV; }
- F32 TexCoordEnd() const { return slice1->texCoordV; }
- const Point3F& getP00() const { return slice0->p0; }
- const Point3F& getP01() const { return slice1->p0; }
- const Point3F& getP11() const { return slice1->p2; }
- const Point3F& getP10() const { return slice0->p2; }
- Point3F getSurfaceCenter() const { return ( slice0->p1 + slice1->p1 ) / 2.0f; }
- Point3F getSurfaceNormal() const { return -mPlanes[4].getNormal(); }
- bool intersectBox( const Box3F &bounds ) const;
- bool containsPoint( const Point3F &pnt ) const;
- F32 distanceToSurface( const Point3F &pnt ) const;
- F32 length() const { return ( slice1->p1 - slice0->p1 ).len(); }
- // Quick access to the segment's points
- Point3F& operator[](U32);
- const Point3F& operator[](U32) const;
- Point3F& operator[](S32 i) { return operator[](U32(i)); }
- const Point3F& operator[](S32 i ) const { return operator[](U32(i)); }
- const Box3F& getWorldBounds() const { return worldbounds; }
- MeshRoadSlice *slice0;
- MeshRoadSlice *slice1;
- protected:
- PlaneF mPlanes[6];
- U32 mPlaneCount;
- U32 columns;
- U32 rows;
- U32 startVert;
- U32 endVert;
- U32 startIndex;
- U32 endIndex;
- U32 numVerts;
- U32 numTriangles;
- Box3F objectbounds;
- Box3F worldbounds;
- };
- typedef Vector<MeshRoadSegment> MeshRoadSegmentVector;
- inline Point3F& MeshRoadSegment::operator[](U32 index)
- {
- AssertFatal(index < 8, "MeshRoadSegment::operator[] - out of bounds array access!");
- MeshRoadSlice *slice = NULL;
- if ( index > 3 )
- {
- slice = slice1;
- index -= 4;
- }
- else
- {
- slice = slice0;
- }
- if ( index == 0 )
- return slice->p0;
- if ( index == 1 )
- return slice->p2;
- if ( index == 2 )
- return slice->pb0;
- else //( index == 3 )
- return slice->pb2;
- }
- inline const Point3F& MeshRoadSegment::operator[](U32 index) const
- {
- AssertFatal(index < 8, "MeshRoadSegment::operator[] - out of bounds array access!");
- MeshRoadSlice *slice = NULL;
- if ( index > 3 )
- {
- slice = slice1;
- index -= 4;
- }
- else
- {
- slice = slice0;
- }
- if ( index == 0 )
- return slice->p0;
- if ( index == 1 )
- return slice->p2;
- if ( index == 2 )
- return slice->pb0;
- else// ( index == 3 )
- return slice->pb2;
- }
- //------------------------------------------------------------------------------
- // MeshRoad Class
- //------------------------------------------------------------------------------
- class PhysicsBody;
- struct MeshRoadNodeList;
- class MeshRoad : public SceneObject
- {
- private:
- friend class GuiMeshRoadEditorCtrl;
- friend class GuiMeshRoadEditorUndoAction;
- friend class MeshRoadConvex;
- friend class MeshRoadProfile;
- typedef SceneObject Parent;
- enum
- {
- MeshRoadMask = Parent::NextFreeMask,
- NodeMask = Parent::NextFreeMask << 1,
- RegenMask = Parent::NextFreeMask << 2,
- InitialUpdateMask = Parent::NextFreeMask << 3,
- SelectedMask = Parent::NextFreeMask << 4,
- MaterialMask = Parent::NextFreeMask << 5,
- ProfileMask = Parent::NextFreeMask << 6,
- NextFreeMask = Parent::NextFreeMask << 7,
- };
- public:
- MeshRoad();
- ~MeshRoad();
- DECLARE_CONOBJECT(MeshRoad);
- // ConObject.
- static void initPersistFields();
- static void consoleInit();
- // SimObject
- bool onAdd();
- void onRemove();
- void onEditorEnable();
- void onEditorDisable();
- void inspectPostApply();
- void onStaticModified(const char* slotName, const char*newValue = NULL);
- void writeFields(Stream &stream, U32 tabStop);
- bool writeField( StringTableEntry fieldname, const char *value );
- // NetObject
- U32 packUpdate(NetConnection *, U32, BitStream *);
- void unpackUpdate(NetConnection *, BitStream *);
- // SceneObject
- virtual void prepRenderImage( SceneRenderState* sceneState );
- virtual void setTransform( const MatrixF &mat );
- virtual void setScale( const VectorF &scale );
- // SceneObject - Collision
- virtual void buildConvex(const Box3F& box,Convex* convex);
- virtual bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF &sphere);
- virtual bool castRay(const Point3F &start, const Point3F &end, RayInfo* info);
- virtual bool collideBox(const Point3F &start, const Point3F &end, RayInfo* info);
- // MeshRoad
- void regenerate();
- void setBatchSize( U32 level );
- void setTextureFile( StringTableEntry file );
- void setTextureRepeat( F32 meters );
- bool collideRay( const Point3F &origin, const Point3F &direction, U32 *nodeIdx = NULL, Point3F *collisionPnt = NULL );
- bool buildSegmentPolyList( AbstractPolyList* polyList, U32 startSegIdx, U32 endSegIdx, bool capFront, bool capEnd );
- void buildNodesFromList( MeshRoadNodeList* list );
- U32 insertNode( const Point3F &pos, const F32 &width, const F32 &depth, const Point3F &normal, const U32 &idx );
- U32 addNode( const Point3F &pos, const F32 &width, const F32 &depth, const Point3F &normal );
- void deleteNode( U32 idx );
- void setNode( const Point3F &pos, const F32 &width, const F32 &depth, const Point3F &normal, const U32 &idx );
- const MeshRoadNode& getNode( U32 idx );
- VectorF getNodeNormal( U32 idx );
- void setNodeNormal( U32 idx, const VectorF &normal );
- Point3F getNodePosition( U32 idx );
- void setNodePosition( U32 idx, const Point3F &pos );
- F32 getNodeWidth( U32 idx );
- void setNodeWidth( U32 idx, F32 width );
- F32 getNodeDepth( U32 idx );
- void setNodeDepth( U32 idx, F32 depth );
- MatrixF getNodeTransform( U32 idx );
- void calcSliceTransform( U32 idx, MatrixF &mat );
- bool isEndNode( U32 idx ) { return ( mNodes.size() > 0 && ( idx == 0 || idx == mNodes.size() - 1 ) ); }
- U32 getSegmentCount() { return mSegments.size(); }
- const MeshRoadSegment& getSegment( U32 idx ) { return mSegments[idx]; }
- F32 getRoadLength() const;
- static SimSet* getServerSet();
- /// Protected 'Component' Field setter that will add a component to the list.
- static bool addNodeFromField( void *object, const char *index, const char *data );
- static bool addProfileNodeFromField(void *obj, const char *index, const char* data);
- static bool smEditorOpen;
- static bool smWireframe;
- static bool smShowBatches;
- static bool smShowSpline;
- static bool smShowRoad;
- static bool smShowRoadProfile;
- static SimObjectPtr<SimSet> smServerMeshRoadSet;
- protected:
- void _initMaterial();
- void _debugRender( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance* );
- U32 _insertNode( const Point3F &pos, const F32 &width, const F32 &depth, const Point3F &normal, const U32 &idx );
- U32 _addNode( const Point3F &pos, const F32 &width, const F32 &depth, const Point3F &normal );
- void _regenerate();
- void _generateSlices();
- void _generateSegments();
- void _generateVerts();
- protected:
- MeshRoadSliceVector mSlices;
- MeshRoadNodeVector mNodes;
- MeshRoadSegmentVector mSegments;
- MeshRoadBatchVector mBatches;
-
- static GFXStateBlockRef smWireframeSB;
- enum {
- Top = 0,
- Bottom = 1,
- Side = 2,
- SurfaceCount = 3
- };
- GFXVertexBufferHandle<GFXVertexPNTT> mVB[SurfaceCount];
- GFXPrimitiveBufferHandle mPB[SurfaceCount];
- DECLARE_MATERIALASSET(MeshRoad, TopMaterial);
- DECLARE_ASSET_NET_SETGET(MeshRoad, TopMaterial, MeshRoadMask);
- DECLARE_MATERIALASSET(MeshRoad, BottomMaterial);
- DECLARE_ASSET_NET_SETGET(MeshRoad, BottomMaterial, MeshRoadMask);
- DECLARE_MATERIALASSET(MeshRoad, SideMaterial);
- DECLARE_ASSET_NET_SETGET(MeshRoad, SideMaterial, MeshRoadMask);
- //String mMaterialName[SurfaceCount];
- SimObjectPtr<Material> mMaterial[SurfaceCount];
- BaseMatInstance *mMatInst[SurfaceCount];
- U32 mVertCount[SurfaceCount];
- U32 mTriangleCount[SurfaceCount];
- MeshRoadProfile mSideProfile;
-
- // Fields.
- F32 mTextureLength;
- F32 mBreakAngle;
- S32 mWidthSubdivisions;
-
- // Collision and Physics.
- Convex* mConvexList;
- Vector<MeshRoadConvex*> mDebugConvex;
- PhysicsBody *mPhysicsRep;
- private:
- static bool buildPolyList_TopSurfaceOnly;
- public:
- bool buildTopPolyList(PolyListContext, AbstractPolyList*);
- };
- #endif // _MESHROAD_H_
|