Calculate normals for OBJ models with smooth groups
Add smoothGroup member to OBJFace struct, and assign the current smooth group number to it
Move face normal calculation code to CalculateNormalFlat
Add AddVertFaces method, which initializes and populates the vertFaces array of arrays, which holds references to triangle references per vertex
Only initialize and populate vertFaces if the model has missing normals and smooth groups
Assign smooth groups to triangle data
Add CalculateNormalSmooth method, which calculates the normals for each face the vertex is attached to, depending on whether or not the faces are part of the given smooth group, and averages them out
Add OBJTriRef struct, which holds references to triangles on OBJ surfaces
Make {agg,cur}SurfFaceCount unsigned ints
Change nvec to a value instead of a pointer
This commit is contained in:
parent
38c8f0d585
commit
7d4895d9df
2 changed files with 150 additions and 24 deletions
|
|
@ -30,6 +30,8 @@ class FOBJModel : public FModel
|
|||
{
|
||||
private:
|
||||
const char *newSideSep = "$"; // OBJ side separator is /, which is parsed as a line comment by FScanner if two of them are next to each other.
|
||||
bool hasMissingNormals;
|
||||
bool hasSmoothGroups;
|
||||
|
||||
enum class FaceElement
|
||||
{
|
||||
|
|
@ -38,6 +40,14 @@ private:
|
|||
VNormalIndex
|
||||
};
|
||||
|
||||
struct OBJTriRef
|
||||
{
|
||||
unsigned int surf;
|
||||
unsigned int tri;
|
||||
OBJTriRef(): surf(0), tri(0) {}
|
||||
OBJTriRef(unsigned int surf, unsigned int tri): surf(surf), tri(tri) {}
|
||||
bool operator== (OBJTriRef other) { return surf == other.surf && tri == other.tri; }
|
||||
};
|
||||
struct OBJFaceSide
|
||||
{
|
||||
int vertref;
|
||||
|
|
@ -47,7 +57,9 @@ private:
|
|||
struct OBJFace
|
||||
{
|
||||
unsigned int sideCount;
|
||||
unsigned int smoothGroup;
|
||||
OBJFaceSide sides[4];
|
||||
OBJFace(): sideCount(0), smoothGroup(0) {}
|
||||
};
|
||||
struct OBJSurface // 1 surface per 'usemtl'
|
||||
{
|
||||
|
|
@ -66,16 +78,21 @@ private:
|
|||
TArray<OBJFace> faces;
|
||||
TArray<OBJSurface> surfaces;
|
||||
FScanner sc;
|
||||
TArray<OBJTriRef>* vertFaces;
|
||||
|
||||
int ResolveIndex(int origIndex, FaceElement el);
|
||||
template<typename T, size_t L> void ParseVector(TArray<T> &array);
|
||||
bool ParseFaceSide(const FString &side, OBJFace &face, int sidx);
|
||||
void ConstructSurfaceTris(OBJSurface &surf);
|
||||
int ResolveIndex(int origIndex, FaceElement el);
|
||||
void AddVertFaces();
|
||||
void TriangulateQuad(const OBJFace &quad, OBJFace *tris);
|
||||
FVector3 RealignVector(FVector3 vecToRealign);
|
||||
FVector2 FixUV(FVector2 vecToRealign);
|
||||
FVector3 CalculateNormalFlat(unsigned int surfIdx, unsigned int triIdx);
|
||||
FVector3 CalculateNormalFlat(OBJTriRef otr);
|
||||
FVector3 CalculateNormalSmooth(unsigned int vidx, unsigned int smoothGroup);
|
||||
public:
|
||||
FOBJModel() {}
|
||||
FOBJModel(): hasMissingNormals(false), hasSmoothGroups(false), vertFaces(nullptr) {}
|
||||
~FOBJModel();
|
||||
bool Load(const char* fn, int lumpnum, const char* buffer, int length) override;
|
||||
int FindFrame(const char* name) override;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue