forked from graphitemaster/neothyne
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mesh.h
142 lines (116 loc) · 3.01 KB
/
mesh.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#ifndef MESH_HDR
#define MESH_HDR
#include "u_vector.h"
#include "m_bbox.h"
#include "m_half.h"
namespace u {
struct string;
}
struct model;
struct obj;
namespace mesh {
struct basicVertex {
float position[3];
float normal[3];
float coordinate[2];
float tangent[4]; // w = sign of bitangent
};
struct animVertex : basicVertex {
unsigned char blendIndex[4];
unsigned char blendWeight[4];
};
struct basicHalfVertex {
m::half position[3];
m::half normal[3];
m::half coordinate[2];
m::half tangent[4]; // w = sign of bitangent
};
struct animHalfVertex : basicHalfVertex {
unsigned char blendIndex[4];
unsigned char blendWeight[4];
};
}
struct vertexCacheData {
u::vector<size_t> indices;
size_t cachePosition;
float currentScore;
size_t totalValence;
size_t remainingValence;
bool calculated;
vertexCacheData();
size_t findTriangle(size_t tri);
void moveTriangle(size_t tri);
};
struct triangleCacheData {
bool rendered;
float currentScore;
size_t vertices[3];
bool calculated;
triangleCacheData();
};
struct vertexCache {
void addVertex(size_t vertex);
void clear();
size_t getCacheMissCount() const;
size_t getCacheMissCount(const u::vector<size_t> &indices);
size_t getCachedVertex(size_t index) const;
vertexCache();
private:
size_t findVertex(size_t vertex);
void removeVertex(size_t stackIndex);
size_t m_cache[40];
size_t m_misses;
};
struct vertexCacheOptimizer {
vertexCacheOptimizer();
enum result {
kSuccess,
kErrorInvalidIndex,
kErrorNoVertices
};
result optimize(u::vector<size_t> &indices);
size_t getCacheMissCount() const;
private:
u::vector<vertexCacheData> m_vertices;
u::vector<triangleCacheData> m_triangles;
u::vector<size_t> m_indices;
u::vector<size_t> m_drawList;
vertexCache m_vertexCache;
size_t m_bestTriangle;
float calcVertexScore(size_t vertex);
size_t fullScoreRecalculation();
result initialPass();
result init(u::vector<size_t> &indices, size_t vertexCount);
void addTriangle(size_t triangle);
bool cleanFlags();
void triangleScoreRecalculation(size_t triangle);
size_t partialScoreRecalculation();
bool process();
};
struct face {
face();
size_t vertex;
size_t normal;
size_t coordinate;
};
inline face::face()
: vertex((size_t)-1)
, normal((size_t)-1)
, coordinate((size_t)-1)
{
}
inline bool operator==(const face &lhs, const face &rhs) {
return lhs.vertex == rhs.vertex
&& lhs.normal == rhs.normal
&& lhs.coordinate == rhs.coordinate;
}
// Hash a face
namespace u {
inline size_t hash(const ::face &f) {
static constexpr size_t prime1 = 73856093u;
static constexpr size_t prime2 = 19349663u;
static constexpr size_t prime3 = 83492791u;
return (f.vertex * prime1) ^ (f.normal * prime2) ^ (f.coordinate * prime3);
}
}
#endif