You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
7.3 KiB
243 lines
7.3 KiB
|
|
#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
|
|
|