mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-04 09:52:01 +00:00
Optimize UE1 vertex normal computation.
This commit is contained in:
parent
c8fe5bcb2e
commit
6e79209931
2 changed files with 22 additions and 14 deletions
|
@ -13,7 +13,7 @@ public:
|
||||||
PT_TwoSided = 1, // like normal, but don't cull backfaces
|
PT_TwoSided = 1, // like normal, but don't cull backfaces
|
||||||
PT_Translucent = 2, // additive blending
|
PT_Translucent = 2, // additive blending
|
||||||
PT_Masked = 3, // draw with alpha testing
|
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
|
// types mask
|
||||||
PT_Type = 7,
|
PT_Type = 7,
|
||||||
// flags
|
// flags
|
||||||
|
@ -86,6 +86,8 @@ private:
|
||||||
struct UE1Vertex
|
struct UE1Vertex
|
||||||
{
|
{
|
||||||
FVector3 Pos, Normal;
|
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
|
struct UE1Poly
|
||||||
{
|
{
|
||||||
|
@ -103,7 +105,7 @@ private:
|
||||||
int numFrames;
|
int numFrames;
|
||||||
int numPolys;
|
int numPolys;
|
||||||
int numGroups;
|
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<UE1Vertex> verts;
|
||||||
TArray<UE1Poly> polys;
|
TArray<UE1Poly> polys;
|
||||||
|
|
|
@ -85,7 +85,6 @@ void FUE1Model::LoadGeometry()
|
||||||
averts = (uint32_t*)(buffer2+sizeof(a3dhead));
|
averts = (uint32_t*)(buffer2+sizeof(a3dhead));
|
||||||
dxverts = NULL;
|
dxverts = NULL;
|
||||||
}
|
}
|
||||||
weaponPoly = -1;
|
|
||||||
// set counters
|
// set counters
|
||||||
numVerts = dhead->numverts;
|
numVerts = dhead->numverts;
|
||||||
numFrames = ahead->numframes;
|
numFrames = ahead->numframes;
|
||||||
|
@ -111,6 +110,9 @@ void FUE1Model::LoadGeometry()
|
||||||
unpackuvert(averts[j+i*numVerts],2),
|
unpackuvert(averts[j+i*numVerts],2),
|
||||||
-unpackuvert(averts[j+i*numVerts],1));
|
-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)
|
// push vertex (without normals, will be calculated later)
|
||||||
verts.Push(Vert);
|
verts.Push(Vert);
|
||||||
}
|
}
|
||||||
|
@ -132,23 +134,26 @@ void FUE1Model::LoadGeometry()
|
||||||
dir[0] = verts[Poly.V[1]+numVerts*j].Pos-verts[Poly.V[0]+numVerts*j].Pos;
|
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;
|
dir[1] = verts[Poly.V[2]+numVerts*j].Pos-verts[Poly.V[0]+numVerts*j].Pos;
|
||||||
Poly.Normals.Push((dir[0]^dir[1]).Unit());
|
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
|
// push
|
||||||
polys.Push(Poly);
|
polys.Push(Poly);
|
||||||
}
|
}
|
||||||
// compute normals for vertex arrays
|
// compute normals for vertex arrays (average of all referenced poly normals)
|
||||||
// iterates through all polys and compute the average of all facet normals
|
// since we have references listed from before, this saves a lot of time
|
||||||
// from those who use this vertex. not pretty, but does the job
|
// 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 i=0; i<numFrames; i++ )
|
||||||
{
|
{
|
||||||
for ( int j=0; j<numVerts; j++ )
|
for ( int j=0; j<numVerts; j++ )
|
||||||
{
|
{
|
||||||
FVector3 nsum = FVector3(0,0,0);
|
FVector3 nsum = FVector3(0,0,0);
|
||||||
for ( int k=0; k<numPolys; k++ )
|
for ( int k=0; k<verts[j+numVerts*i].nP; k++ )
|
||||||
{
|
nsum += polys[verts[j+numVerts*i].P[k]].Normals[i];
|
||||||
if ( (polys[k].V[0] != j) && (polys[k].V[1] != j) && (polys[k].V[2] != j) ) continue;
|
|
||||||
nsum += polys[k].Normals[i];
|
|
||||||
}
|
|
||||||
verts[j+numVerts*i].Normal = nsum.Unit();
|
verts[j+numVerts*i].Normal = nsum.Unit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,8 +164,9 @@ void FUE1Model::LoadGeometry()
|
||||||
UE1Group Group;
|
UE1Group Group;
|
||||||
for ( int i=0; i<numPolys; i++ )
|
for ( int i=0; i<numPolys; i++ )
|
||||||
{
|
{
|
||||||
// while we're at it, look for the weapon triangle
|
// while we're at it, look for attachment triangles
|
||||||
if ( dpolys[i].type&PT_WeaponTriangle ) weaponPoly = i;
|
// 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 )
|
if ( curgroup == -1 )
|
||||||
{
|
{
|
||||||
// no group, create it
|
// no group, create it
|
||||||
|
@ -197,7 +203,7 @@ void FUE1Model::LoadGeometry()
|
||||||
void FUE1Model::UnloadGeometry()
|
void FUE1Model::UnloadGeometry()
|
||||||
{
|
{
|
||||||
mDataLoaded = false;
|
mDataLoaded = false;
|
||||||
weaponPoly = -1;
|
specialPolys.Reset();
|
||||||
numVerts = 0;
|
numVerts = 0;
|
||||||
numFrames = 0;
|
numFrames = 0;
|
||||||
numPolys = 0;
|
numPolys = 0;
|
||||||
|
|
Loading…
Reference in a new issue