diff options
Diffstat (limited to 'utils/nvtristriplib/nvtristripobjects.h')
| -rw-r--r-- | utils/nvtristriplib/nvtristripobjects.h | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/utils/nvtristriplib/nvtristripobjects.h b/utils/nvtristriplib/nvtristripobjects.h new file mode 100644 index 0000000..930929c --- /dev/null +++ b/utils/nvtristriplib/nvtristripobjects.h @@ -0,0 +1,243 @@ + +#ifndef NV_TRISTRIP_OBJECTS_H +#define NV_TRISTRIP_OBJECTS_H + +#include <assert.h> +#include <windows.h> +#include <vector> +#include <list> +#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<NvFaceInfo*> NvFaceInfoVec; +typedef std::list <NvFaceInfo*> NvFaceInfoList; +typedef std::list <NvFaceInfoVec*> NvStripList; +typedef std::vector<NvEdgeInfo*> NvEdgeInfoVec; + +typedef std::vector<WORD> WordVec; +typedef std::vector<int> IntVec; +typedef std::vector<MyVertex> MyVertexVec; +typedef std::vector<MyFace> MyFaceVec; + +template<class T> +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<NvStripInfo*> 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<NvStripInfo*>::iterator iter, std::list<NvStripInfo*>::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 |