Skip to content

Commit

Permalink
Optimize UE1 vertex normal computation.
Browse files Browse the repository at this point in the history
  • Loading branch information
Marisa Kirisame authored and Doom2fan committed Jul 11, 2020
1 parent c8fe5bc commit 6e79209
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 14 deletions.
6 changes: 4 additions & 2 deletions src/common/models/model_ue1.h
Expand Up @@ -13,7 +13,7 @@ class FUE1Model : public FModel
PT_TwoSided = 1, // like normal, but don't cull backfaces
PT_Translucent = 2, // additive blending
PT_Masked = 3, // draw with alpha testing
PT_Modulated = 4, // overlay-like blending (rgb values below 128 darken, 128 is unchanged, and above 128 lighten)
PT_Modulated = 4, // modulated blending (src*dest*2)
// types mask
PT_Type = 7,
// flags
Expand Down Expand Up @@ -86,6 +86,8 @@ class FUE1Model : public FModel
struct UE1Vertex
{
FVector3 Pos, Normal;
TArray<int> P; // polys that reference this vertex, used in normal computation to save time
int nP; // count of those polys
};
struct UE1Poly
{
Expand All @@ -103,7 +105,7 @@ class FUE1Model : public FModel
int numFrames;
int numPolys;
int numGroups;
int weaponPoly; // for future model attachment support, unused for now
TArray<int> specialPolys; // for future model attachment support, unused for now

TArray<UE1Vertex> verts;
TArray<UE1Poly> polys;
Expand Down
30 changes: 18 additions & 12 deletions src/common/models/models_ue1.cpp
Expand Up @@ -85,7 +85,6 @@ void FUE1Model::LoadGeometry()
averts = (uint32_t*)(buffer2+sizeof(a3dhead));
dxverts = NULL;
}
weaponPoly = -1;
// set counters
numVerts = dhead->numverts;
numFrames = ahead->numframes;
Expand All @@ -111,6 +110,9 @@ void FUE1Model::LoadGeometry()
unpackuvert(averts[j+i*numVerts],2),
-unpackuvert(averts[j+i*numVerts],1));
}
// refs will be set later
Vert.P.Reset();
Vert.nP = 0;
// push vertex (without normals, will be calculated later)
verts.Push(Vert);
}
Expand All @@ -132,23 +134,26 @@ void FUE1Model::LoadGeometry()
dir[0] = verts[Poly.V[1]+numVerts*j].Pos-verts[Poly.V[0]+numVerts*j].Pos;
dir[1] = verts[Poly.V[2]+numVerts*j].Pos-verts[Poly.V[0]+numVerts*j].Pos;
Poly.Normals.Push((dir[0]^dir[1]).Unit());
// since we're iterating frames, also set references for later
for ( int k=0; k<3; k++ )
{
verts[Poly.V[k]+numVerts*j].P.Push(i);
verts[Poly.V[k]+numVerts*j].nP++;
}
}
// push
polys.Push(Poly);
}
// compute normals for vertex arrays
// iterates through all polys and compute the average of all facet normals
// from those who use this vertex. not pretty, but does the job
// compute normals for vertex arrays (average of all referenced poly normals)
// since we have references listed from before, this saves a lot of time
// without having to loop through the entire model each vertex (especially true for very complex models)
for ( int i=0; i<numFrames; i++ )
{
for ( int j=0; j<numVerts; j++ )
{
FVector3 nsum = FVector3(0,0,0);
for ( int k=0; k<numPolys; k++ )
{
if ( (polys[k].V[0] != j) && (polys[k].V[1] != j) && (polys[k].V[2] != j) ) continue;
nsum += polys[k].Normals[i];
}
for ( int k=0; k<verts[j+numVerts*i].nP; k++ )
nsum += polys[verts[j+numVerts*i].P[k]].Normals[i];
verts[j+numVerts*i].Normal = nsum.Unit();
}
}
Expand All @@ -159,8 +164,9 @@ void FUE1Model::LoadGeometry()
UE1Group Group;
for ( int i=0; i<numPolys; i++ )
{
// while we're at it, look for the weapon triangle
if ( dpolys[i].type&PT_WeaponTriangle ) weaponPoly = i;
// while we're at it, look for attachment triangles
// technically only one should exist, but we ain't following the specs 100% here
if ( dpolys[i].type&PT_WeaponTriangle ) specialPolys.Push(i);
if ( curgroup == -1 )
{
// no group, create it
Expand Down Expand Up @@ -197,7 +203,7 @@ void FUE1Model::LoadGeometry()
void FUE1Model::UnloadGeometry()
{
mDataLoaded = false;
weaponPoly = -1;
specialPolys.Reset();
numVerts = 0;
numFrames = 0;
numPolys = 0;
Expand Down

0 comments on commit 6e79209

Please sign in to comment.