#ifndef NV_TRISTRIP_OBJECTS_H #define NV_TRISTRIP_OBJECTS_H #include #include #include #include #include "VertexCache.h" ///////////////////////////////////////////////////////////////////////////////// // // Types defined for stripification // ///////////////////////////////////////////////////////////////////////////////// struct MyVertex { float x, y, z; float nx, ny, nz; }; typedef MyVertex MyVector; struct MyFace { int v1, v2, v3; float nx, ny, nz; }; class NvFaceInfo { public: // vertex indices NvFaceInfo(int v0, int v1, int v2){ m_v0 = v0; m_v1 = v1; m_v2 = v2; m_stripId = -1; m_testStripId = -1; m_experimentId = -1; } // data members are left public int m_v0, m_v1, m_v2; int m_stripId; // real strip Id int m_testStripId; // strip Id in an experiment int m_experimentId; // in what experiment was it given an experiment Id? }; // nice and dumb edge class that points knows its // indices, the two faces, and the next edge using // the lesser of the indices class NvEdgeInfo { public: // constructor puts 1 ref on us NvEdgeInfo (int v0, int v1){ m_v0 = v0; m_v1 = v1; m_face0 = NULL; m_face1 = NULL; m_nextV0 = NULL; m_nextV1 = NULL; // we will appear in 2 lists. this is a good // way to make sure we delete it the second time // we hit it in the edge infos m_refCount = 2; } // ref and unref void Unref () { if (--m_refCount == 0) delete this; } // data members are left public UINT m_refCount; NvFaceInfo *m_face0, *m_face1; int m_v0, m_v1; NvEdgeInfo *m_nextV0, *m_nextV1; }; // This class is a quick summary of parameters used // to begin a triangle strip. Some operations may // want to create lists of such items, so they were // pulled out into a class class NvStripStartInfo { public: NvStripStartInfo(NvFaceInfo *startFace, NvEdgeInfo *startEdge, bool toV1){ m_startFace = startFace; m_startEdge = startEdge; m_toV1 = toV1; } NvFaceInfo *m_startFace; NvEdgeInfo *m_startEdge; bool m_toV1; }; typedef std::vector NvFaceInfoVec; typedef std::list NvFaceInfoList; typedef std::list NvStripList; typedef std::vector NvEdgeInfoVec; typedef std::vector WordVec; typedef std::vector IntVec; typedef std::vector MyVertexVec; typedef std::vector MyFaceVec; template inline void SWAP(T& first, T& second) { T temp = first; first = second; second = temp; } // This is a summary of a strip that has been built class NvStripInfo { public: // A little information about the creation of the triangle strips NvStripInfo(const NvStripStartInfo &startInfo, int stripId, int experimentId = -1) : m_startInfo(startInfo) { m_stripId = stripId; m_experimentId = experimentId; visited = false; m_numDegenerates = 0; } // This is an experiment if the experiment id is >= 0 inline bool IsExperiment () const { return m_experimentId >= 0; } inline bool IsInStrip (const NvFaceInfo *faceInfo) const { if(faceInfo == NULL) return false; return (m_experimentId >= 0 ? faceInfo->m_testStripId == m_stripId : faceInfo->m_stripId == m_stripId); } bool SharesEdge(const NvFaceInfo* faceInfo, NvEdgeInfoVec &edgeInfos); // take the given forward and backward strips and combine them together void Combine(const NvFaceInfoVec &forward, const NvFaceInfoVec &backward); //returns true if the face is "unique", i.e. has a vertex which doesn't exist in the faceVec bool Unique(NvFaceInfoVec& faceVec, NvFaceInfo* face); // mark the triangle as taken by this strip bool IsMarked (NvFaceInfo *faceInfo); void MarkTriangle(NvFaceInfo *faceInfo); // build the strip void Build(NvEdgeInfoVec &edgeInfos, NvFaceInfoVec &faceInfos); // public data members NvStripStartInfo m_startInfo; NvFaceInfoVec m_faces; int m_stripId; int m_experimentId; bool visited; int m_numDegenerates; }; typedef std::vector NvStripInfoVec; //The actual stripifier class NvStripifier { public: // Constructor NvStripifier(); ~NvStripifier(); //the target vertex cache size, the structure to place the strips in, and the input indices void Stripify(const WordVec &in_indices, const int in_cacheSize, const int in_minStripLength, const unsigned short maxIndex, NvStripInfoVec &allStrips, NvFaceInfoVec &allFaces); void CreateStrips(const NvStripInfoVec& allStrips, IntVec& stripIndices, const bool bStitchStrips, unsigned int& numSeparateStrips); static int GetUniqueVertexInB(NvFaceInfo *faceA, NvFaceInfo *faceB); //static int GetSharedVertex(NvFaceInfo *faceA, NvFaceInfo *faceB); static void GetSharedVertices(NvFaceInfo *faceA, NvFaceInfo *faceB, int* vertex0, int* vertex1); static bool IsDegenerate(const NvFaceInfo* face); protected: WordVec indices; int cacheSize; int minStripLength; float meshJump; bool bFirstTimeResetPoint; ///////////////////////////////////////////////////////////////////////////////// // // Big mess of functions called during stripification // ///////////////////////////////////////////////////////////////////////////////// //******************** bool IsMoneyFace(const NvFaceInfo& face); bool FaceContainsIndex(const NvFaceInfo& face, const unsigned int index); bool IsCW(NvFaceInfo *faceInfo, int v0, int v1); bool NextIsCW(const int numIndices); bool IsDegenerate(const unsigned short v0, const unsigned short v1, const unsigned short v2); static int GetNextIndex(const WordVec &indices, NvFaceInfo *face); static NvEdgeInfo *FindEdgeInfo(NvEdgeInfoVec &edgeInfos, int v0, int v1); static NvFaceInfo *FindOtherFace(NvEdgeInfoVec &edgeInfos, int v0, int v1, NvFaceInfo *faceInfo); NvFaceInfo *FindGoodResetPoint(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos); void FindAllStrips(NvStripInfoVec &allStrips, NvFaceInfoVec &allFaceInfos, NvEdgeInfoVec &allEdgeInfos, int numSamples); void SplitUpStripsAndOptimize(NvStripInfoVec &allStrips, NvStripInfoVec &outStrips, NvEdgeInfoVec& edgeInfos, NvFaceInfoVec& outFaceList); void RemoveSmallStrips(NvStripInfoVec& allStrips, NvStripInfoVec& allBigStrips, NvFaceInfoVec& faceList); bool FindTraversal(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos, NvStripInfo *strip, NvStripStartInfo &startInfo); int CountRemainingTris(std::list::iterator iter, std::list::iterator end); void CommitStrips(NvStripInfoVec &allStrips, const NvStripInfoVec &strips); float AvgStripSize(const NvStripInfoVec &strips); int FindStartPoint(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos); void UpdateCacheStrip(VertexCache* vcache, NvStripInfo* strip); void UpdateCacheFace(VertexCache* vcache, NvFaceInfo* face); float CalcNumHitsStrip(VertexCache* vcache, NvStripInfo* strip); int CalcNumHitsFace(VertexCache* vcache, NvFaceInfo* face); int NumNeighbors(NvFaceInfo* face, NvEdgeInfoVec& edgeInfoVec); void BuildStripifyInfo(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos, const unsigned short maxIndex); bool AlreadyExists(NvFaceInfo* faceInfo, NvFaceInfoVec& faceInfos); // let our strip info classes and the other classes get // to these protected stripificaton methods if they want friend NvStripInfo; }; #endif