-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
brfMesh.h
343 lines (254 loc) · 9.63 KB
/
brfMesh.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
/* OpenBRF -- by marco tarini. Provided under GNU General Public License */
#ifndef BRF_MESH
#define BRF_MESH
// a BRF mesh....
#include "brfToken.h"
namespace vcg {
template <class T> class Matrix44;
}
class CarryPosition;
class BrfSkeleton;
class BrfAnimation;
class BrfBodyPart;
class BrfVert{
public:
BrfVert();
int index;
unsigned int col;
Point3f __norm; // use normal inside frame instead
Point3f tang; // tangent dir...
unsigned char tangi; // 0: frame TBN right-handed 1: left-handed
Point2f ta,tb; // texture
BrfVert operator + (const int i) const {BrfVert res = *this; res.index += i; return res;}
bool Load(FILE*f);
void Save(FILE*f) const;
static unsigned int SizeOnDisk();
};
class BrfFace{
public:
int index[3];
BrfFace(){}
BrfFace(int i, int j, int k) {index[0]=i; index[1]=j; index[2]=k; }
BrfFace operator + (const int i) const {BrfFace res = *this;
res.index[0] += i; res.index[1] += i; res.index[2] += i; return res;}
void Flip() { int tmp=index[1]; index[1]=index[2]; index[2]=tmp;}
bool Load(FILE*f);
void Save(FILE*f) const;
static unsigned int SizeOnDisk();
};
class BrfSkinning{
public:
BrfSkinning();
// skinning
int boneIndex[4];
float boneWeight[4];
void SetColorGl() const;
bool operator < (const BrfSkinning &b) const;
bool operator == (const BrfSkinning &b) const;
int FirstEmpty() const;
int LeastIndex() const; // index with the smallest weight
float WeightOf(int i) const;
void Normalize();
void Add(int index, float w);
bool MaybeAdd(int index, float w);
bool MaybeAdd(BrfSkinning &b);
void Stiffen(float howmuch);
};
class BrfFrame{
public:
int time;
vector<Point3f> pos; // size = pos.size() !!!
vector<Point3f> norm; // size = vert.size() !!!
bool Load(FILE*f);
void Save(FILE*f) const;
static bool Skip(FILE*f);
BrfFrame Blend(const BrfFrame& b, float t) const ;
BrfFrame Blend(const BrfFrame& b, float t, const vector<bool> &sel) const;
Point3f MinPos();
Point3f MaxPos();
void Apply(Matrix44<float> m);
int FindClosestPoint(Point3f to, float* maxdist)const;
void MakeSlim(float ratioX, float ratioZ, const BrfSkeleton* s);
};
class BrfMesh;
// used to morph a skinned mesh frame, e.g. feminine armour from masculine
class MeshMorpher{
public:
enum{MAX_BONES = 40, POSZ_BONES = 20};
void LearnFrom(BrfMesh& a, int framei, int framej); // learn from an example
void ResetLearning();
void FinishLearning();
bool Save(const char* filename) const;
bool Load(const char* text);
void Emphatize(float k);
Point3f s[MAX_BONES], t[MAX_BONES];
float extraBreast;
private:
// quadric coefficients
Point3f css[MAX_BONES],ctt[MAX_BONES],cst[MAX_BONES],cs[MAX_BONES],ct[MAX_BONES],cc[MAX_BONES];
// breast multiplier
};
class BrfMesh{
private:
public:
void Apply(Matrix44<float> m);
bool Apply( const CarryPosition& cp , const BrfSkeleton &s, float weapLen, bool atOrigin);
static bool LoadCarryPosition(CarryPosition& cp, const char* line);
int GetFirstSelected(int after=-1) const;
// adds a rope from avg selected pos to To.AvgSelPos
void AddRope(const BrfMesh &to, int nseg, float width);
vector<BrfSkinning> skinning; // one per pos
void DiminishAni(float t);
void DiminishAniSelected(float t);
bool UniformizeWith(const BrfMesh& target); // crates/removes vertex ani, tangent space, etc to uniformize with target mesh
void Unskeletonize(const BrfSkeleton& from);
void Reskeletonize(const BrfSkeleton& from, const BrfSkeleton& to);
void ReskeletonizeHuman(const BrfSkeleton& from, const BrfSkeleton& to, float bonusArm = 0);
void TransferRigging(const std::vector<BrfMesh>& from, int nf, int nfb);
void ShrinkAroundBones(const BrfSkeleton& s, int nframe);
void NormalizeRigging();
void DiscardRigging();
void DiscardTangentField();
int IsNamedAsLOD() const; // does it follow the M&B convention for LOD meshes?
bool IsNamedAsBody(const char* bodyName) const; // is it the M&B conventional rule for Collision body? ("bo_"+name)
bool CopyModification(const BrfMesh& mod);
bool CopyTextcoords(const BrfMesh& b);
bool CopyVertColors(const BrfMesh& b, bool overwrite=true);
bool CopyVertAni(const BrfMesh& b);
void SetDefault();
void MakeSingleQuad(float x, float y, float dx, float dy);
void AddToBody(BrfBodyPart &dest);
void SmoothRigging();
void StiffenRigging(float howmuch);
void TuneColors(int contast, int hue, int sat, int brigh);
void MorphFrame(int framei, int framej, const MeshMorpher& m);
void AddALittleOfBreast(int framei, float howMuch);
unsigned int GetAverageColor() const;
void FreezeFrame(const BrfSkeleton& s, const BrfAnimation& a, int frameInput, int frameOutput=0);
bool SkinnedToVertexAni(const BrfSkeleton& s, const BrfAnimation& a);
void Unmount(const BrfSkeleton& s);
void MountOnBone(const BrfSkeleton& s, int boneIndex);
const char* GetLikelyCollisonBodyName() const;
void ResizeTextCoords(Point2f min, Point2f max );
void paintAlphaAsZ(float min, float max);
int DivideIntoSeparateChunks(std::vector<int> &map);
void FixRigidObjectsInRigging();
void SubdivideIntoConnectedComponents(std::vector<BrfMesh> &res);
BrfMesh(){}
BrfMesh(FILE *f){ Load(f);}
unsigned int flags;
char name[255];
char material[255];
static int tokenIndex(){return MESH;}
void KeepOnlyFrame(int i);
vector<bool> selected;
vector<BrfFrame> frame;
vector<BrfVert> vert;
vector<BrfFace> face;
Box3f bbox;
int maxBone; // if skinned, what is the max bone index
bool SaveSMD(FILE *f) const;
bool LoadSMD(FILE *f) const;
bool SaveOBJ(char* f, int frame) const;
bool LoadOBJ(char* f);
bool SaveVertexAniAsOBJ(char* f) const;
/* data extracted from name... */
char baseName[255];
int lodLevel;
int pieceIndex;
void AnalyzeName();
bool IsSkinned() const; // for convenience
void UpdateBBox();
void SetUniformRig(int nbone);
void SplitFaces(const std::vector<int> &matIndex);
bool RemoveUnreferenced();
void ColorAll(unsigned int newcol);
void MultColorAll(unsigned int newcol);
void AdjustNormDuplicates(); // copys normals
// sanity check
bool CheckAssert() const;
bool Load(FILE*f);
void Save(FILE*f) const;
bool Skip(FILE* f);
bool SaveAsPly(int nframe=0, const char* path="") const;
void Flip();
void Bend(int frame, float range); // bends as if on a cylinder
bool IsAnimable() const;
void ComputeNormals();
void ComputeTangents();
void ComputeTangentsMaybeSplit();
void ZeroTangents();
void ComputeNormals(int framei);
void ComputeAndStoreTangents();
bool UnifyPos();
bool UnifyVert(bool careForNormals, float crease=0);
void DivideVert();
void RemoveSeamsFromNormals(double crease);
void AfterLoad();
bool hasVertexColor;
bool StoresTangentField() const; // on disk
bool HasTangentField() const; // for previewing
bool HasVertexAni() const;
bool reverseVertexAni();
bool Merge(const BrfMesh &brf);
bool AddAllFrames(const BrfMesh &brf);
bool AddFrameDirect(const BrfMesh &brf);
bool AddFrameMatchVert(const BrfMesh &brf, int k);
bool AddFrameMatchTc(const BrfMesh &brf, int k);
bool AddFrameMatchPosOrDie(const BrfMesh &brf, int k);
void EnsureTwoFrames();
void Scale(float f);
void Scale(float xNeg, float xPos, float yPos, float yNeg, float zPos, float zNeg);
void TowardZero(float x,float y, float z);
void TransformUv(float su, float sv, float tu, float tv);
void Transform(float * m, int frameN = -1);
void Translate(Point3f p);
void RemoveBackfacingFaces();
void AddBackfacingFaces();
void GetTimings(std::vector<int> &v);
void SetTimings(const std::vector<int> &v);
static unsigned int multCol( unsigned int col, float a);
static unsigned int multCol( unsigned int col, unsigned int colb);
void SetName(const char* st);
private:
void CopyTimesFrom(const BrfMesh &brf);
void Blend(const BrfMesh &brf);
void MergeMirror(const BrfMesh &brf);
void UpdateMaxBone();
void CollapseBetweenFrames(int fi, int fj);
void DuplicateFrames(const BrfMesh &brf);
void DuplicateFrames(int i);
void CopySelectedFrom(const BrfMesh &brf);
void FollowSelected(const BrfMesh &brf, int baseframe=0);
void FollowSelectedSmart(const BrfMesh &brf, int baseframe=0);
void KeepSelctedFixed(int asInFrame, float howmuch);
void CopyTextcoord(const BrfMesh &origbrf, const BrfMesh &newbrf, int nframe=0);
void CopyPos(int x, const BrfMesh &origbrf, const BrfMesh &newbrf);
void PropagateDeformations(int nframe, const BrfMesh &brf);
void SelectRed(const BrfMesh &brf);
void SelectRand();
float GetTopPos(int frame, int axis=1) const;
//void Scale(float f);
void TranslateSelected(Point3f p);
void CycleFrame(int i);
void Hasten(float timemult);
void FixTextcoord(const BrfMesh &newbrf, BrfMesh &refbrf, int nframe=0);
void FixPosOrder(const BrfMesh &refbrf);
void InvertPosOrder();
Point3f GetASelectedPos(int frame=0) const;
Point3f GetAvgSelectedPos(int framei) const;
void FindRefPoints();
vector<int> refpoint;
void FindSymmetry(vector<int> &output);
void ApplySymmetry(const vector<int> &output);
void SelectAbsent(const BrfMesh& ref, int nframe=0);
void DeleteSelected();
void ClearSelection();
void CopySelection(const BrfMesh& ref);
void AdaptToRes(const BrfMesh& ref);
//BrfMesh& operator = (const BrfMesh &brf);
static void AlignToTop(BrfMesh& a, BrfMesh& b);
BrfMesh SingleFrame(int i) const; // returns a BrfMesh consisting only of frame i
static bool FindVertVertMapping(std::vector<int> &map, const BrfMesh& a, const BrfMesh& b, int ai, int bi, float uv, float xyz);
};
#endif