mirror of
https://github.com/Garux/netradiant-custom.git
synced 2026-09-28 00:00:03 +02:00
add MeshQuadIterator
This commit is contained in:
+51
-103
@@ -63,7 +63,7 @@ static Vector3 entityOrigin;
|
||||
returns false if a texture matrix cannot be created
|
||||
*/
|
||||
|
||||
static bool MakeTextureMatrix( decalProjector_t *dp, const Plane3f& projection, const bspDrawVert_t *a, const bspDrawVert_t *b, const bspDrawVert_t *c ){
|
||||
static bool MakeTextureMatrix( decalProjector_t& dp, const Plane3f& projection, const bspDrawVert_t *a, const bspDrawVert_t *b, const bspDrawVert_t *c ){
|
||||
int i, j;
|
||||
double bb, s, t;
|
||||
DoubleVector3 pa, pb, pc;
|
||||
@@ -138,13 +138,13 @@ static bool MakeTextureMatrix( decalProjector_t *dp, const Plane3f& projection,
|
||||
}
|
||||
for ( i = 0; i < 2; ++i )
|
||||
for ( j = 0; j < 3; ++j )
|
||||
dp->texMat[ i ][ j ] = lengths[ i ] != 0 ? ( axis[ i ][ j ] / lengths[ i ] ) : 0.0;
|
||||
//% dp->texMat[ i ][ j ] = std::fabs( vecs[ i ][ j ] ) > 0 ? ( 1.0 / vecs[ i ][ j ] ) : 0.0;
|
||||
//% dp->texMat[ i ][ j ] = axis[ i ][ j ] > 0 ? ( 1.0 / axis[ i ][ j ] ) : 0.0;
|
||||
dp.texMat[ i ][ j ] = lengths[ i ] != 0 ? ( axis[ i ][ j ] / lengths[ i ] ) : 0.0;
|
||||
//% dp.texMat[ i ][ j ] = std::fabs( vecs[ i ][ j ] ) > 0 ? ( 1.0 / vecs[ i ][ j ] ) : 0.0;
|
||||
//% dp.texMat[ i ][ j ] = axis[ i ][ j ] > 0 ? ( 1.0 / axis[ i ][ j ] ) : 0.0;
|
||||
|
||||
/* calculalate translation component */
|
||||
dp->texMat[ 0 ][ 3 ] = a->st[ 0 ] - vector3_dot( a->xyz, dp->texMat[ 0 ].vec3() );
|
||||
dp->texMat[ 1 ][ 3 ] = a->st[ 1 ] - vector3_dot( a->xyz, dp->texMat[ 1 ].vec3() );
|
||||
dp.texMat[ 0 ][ 3 ] = a->st[ 0 ] - vector3_dot( a->xyz, dp.texMat[ 0 ].vec3() );
|
||||
dp.texMat[ 1 ][ 3 ] = a->st[ 1 ] - vector3_dot( a->xyz, dp.texMat[ 1 ].vec3() );
|
||||
}
|
||||
#else
|
||||
{
|
||||
@@ -186,15 +186,15 @@ static bool MakeTextureMatrix( decalProjector_t *dp, const Plane3f& projection,
|
||||
|
||||
/* set texture matrix component */
|
||||
if ( std::fabs( delta ) > 0 ) {
|
||||
dp->texMat[ i ][ j ] = texDelta / delta;
|
||||
dp.texMat[ i ][ j ] = texDelta / delta;
|
||||
}
|
||||
else{
|
||||
dp->texMat[ i ][ j ] = 0;
|
||||
dp.texMat[ i ][ j ] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* set translation component */
|
||||
dp->texMat[ i ][ 3 ] = a->st[ i ] - vector3_dot( pa, dp->texMat[ i ].vec3() );
|
||||
dp.texMat[ i ][ 3 ] = a->st[ i ] - vector3_dot( pa, dp.texMat[ i ].vec3() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -202,34 +202,34 @@ static bool MakeTextureMatrix( decalProjector_t *dp, const Plane3f& projection,
|
||||
/* debug code */
|
||||
#if 1
|
||||
Sys_Printf( "Mat: [ %f %f %f %f ] [ %f %f %f %f ] Theta: %lf (%lf)\n",
|
||||
dp->texMat[ 0 ][ 0 ], dp->texMat[ 0 ][ 1 ], dp->texMat[ 0 ][ 2 ], dp->texMat[ 0 ][ 3 ],
|
||||
dp->texMat[ 1 ][ 0 ], dp->texMat[ 1 ][ 1 ], dp->texMat[ 1 ][ 2 ], dp->texMat[ 1 ][ 3 ],
|
||||
radians_to_degrees( acos( vector3_dot( dp->texMat[ 0 ].vec3(), dp->texMat[ 1 ].vec3() ) ) ),
|
||||
dp.texMat[ 0 ][ 0 ], dp.texMat[ 0 ][ 1 ], dp.texMat[ 0 ][ 2 ], dp.texMat[ 0 ][ 3 ],
|
||||
dp.texMat[ 1 ][ 0 ], dp.texMat[ 1 ][ 1 ], dp.texMat[ 1 ][ 2 ], dp.texMat[ 1 ][ 3 ],
|
||||
radians_to_degrees( acos( vector3_dot( dp.texMat[ 0 ].vec3(), dp.texMat[ 1 ].vec3() ) ) ),
|
||||
radians_to_degrees( acos( vector3_dot( axis[ 0 ], axis[ 1 ] ) ) ) );
|
||||
|
||||
Sys_Printf( "XYZ: %f %f %f ST: %f %f ST(t): %lf %lf\n",
|
||||
a->xyz[ 0 ], a->xyz[ 1 ], a->xyz[ 2 ],
|
||||
a->st[ 0 ], a->st[ 1 ],
|
||||
vector3_dot( a->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ], vector3_dot( a->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ] );
|
||||
vector3_dot( a->xyz, dp.texMat[ 0 ].vec3() ) + dp.texMat[ 0 ][ 3 ], vector3_dot( a->xyz, dp.texMat[ 1 ].vec3() ) + dp.texMat[ 1 ][ 3 ] );
|
||||
#endif
|
||||
|
||||
/* test texture matrix */
|
||||
s = vector3_dot( a->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ];
|
||||
t = vector3_dot( a->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ];
|
||||
s = vector3_dot( a->xyz, dp.texMat[ 0 ].vec3() ) + dp.texMat[ 0 ][ 3 ];
|
||||
t = vector3_dot( a->xyz, dp.texMat[ 1 ].vec3() ) + dp.texMat[ 1 ][ 3 ];
|
||||
if ( !float_equal_epsilon( s, a->st[ 0 ], 0.01 ) || !float_equal_epsilon( t, a->st[ 1 ], 0.01 ) ) {
|
||||
Sys_Printf( "Bad texture matrix! (A) (%f, %f) != (%f, %f)\n",
|
||||
s, t, a->st[ 0 ], a->st[ 1 ] );
|
||||
//% return false;
|
||||
}
|
||||
s = vector3_dot( b->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ];
|
||||
t = vector3_dot( b->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ];
|
||||
s = vector3_dot( b->xyz, dp.texMat[ 0 ].vec3() ) + dp.texMat[ 0 ][ 3 ];
|
||||
t = vector3_dot( b->xyz, dp.texMat[ 1 ].vec3() ) + dp.texMat[ 1 ][ 3 ];
|
||||
if ( !float_equal_epsilon( s, b->st[ 0 ], 0.01 ) || !float_equal_epsilon( t, b->st[ 1 ], 0.01 ) ) {
|
||||
Sys_Printf( "Bad texture matrix! (B) (%f, %f) != (%f, %f)\n",
|
||||
s, t, b->st[ 0 ], b->st[ 1 ] );
|
||||
//% return false;
|
||||
}
|
||||
s = vector3_dot( c->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ];
|
||||
t = vector3_dot( c->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ];
|
||||
s = vector3_dot( c->xyz, dp.texMat[ 0 ].vec3() ) + dp.texMat[ 0 ][ 3 ];
|
||||
t = vector3_dot( c->xyz, dp.texMat[ 1 ].vec3() ) + dp.texMat[ 1 ][ 3 ];
|
||||
if ( !float_equal_epsilon( s, c->st[ 0 ], 0.01 ) || !float_equal_epsilon( t, c->st[ 1 ], 0.01 ) ) {
|
||||
Sys_Printf( "Bad texture matrix! (C) (%f, %f) != (%f, %f)\n",
|
||||
s, t, c->st[ 0 ], c->st[ 1 ] );
|
||||
@@ -286,16 +286,7 @@ static void TransformDecalProjector( decalProjector_t *in, const Vector3 (&axis)
|
||||
creates a new decal projector from a triangle
|
||||
*/
|
||||
|
||||
static int MakeDecalProjector( shaderInfo_t *si, const Plane3f& projection, float distance, int numVerts, const bspDrawVert_t **dv ){
|
||||
int i, j;
|
||||
decalProjector_t *dp;
|
||||
|
||||
|
||||
/* dummy check */
|
||||
if ( numVerts != 3 && numVerts != 4 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int MakeDecalProjector( shaderInfo_t *si, const Plane3f& projection, float distance, const TriRef& tri ){
|
||||
/* limit check */
|
||||
if ( numProjectors >= MAX_PROJECTORS ) {
|
||||
Sys_Warning( "MAX_PROJECTORS (%d) exceeded, no more decal projectors available.\n", MAX_PROJECTORS );
|
||||
@@ -303,45 +294,47 @@ static int MakeDecalProjector( shaderInfo_t *si, const Plane3f& projection, floa
|
||||
}
|
||||
|
||||
/* create a new projector */
|
||||
dp = &projectors[ numProjectors ];
|
||||
memset( dp, 0, sizeof( *dp ) );
|
||||
decalProjector_t& dp = projectors[ numProjectors ];
|
||||
memset( &dp, 0, sizeof( dp ) );
|
||||
|
||||
/* basic setup */
|
||||
dp->si = si;
|
||||
dp->numPlanes = numVerts + 2;
|
||||
dp.si = si;
|
||||
dp.numPlanes = tri.size() + 2;
|
||||
|
||||
/* make texture matrix */
|
||||
if ( !MakeTextureMatrix( dp, projection, dv[ 0 ], dv[ 1 ], dv[ 2 ] ) ) {
|
||||
if ( !MakeTextureMatrix( dp, projection, tri[ 0 ], tri[ 1 ], tri[ 2 ] ) ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* bound the projector */
|
||||
dp->minmax.clear();
|
||||
for ( i = 0; i < numVerts; ++i )
|
||||
dp.minmax.clear();
|
||||
for ( size_t i = 0; i < tri.size(); ++i )
|
||||
{
|
||||
dp->minmax.extend( dv[ i ]->xyz );
|
||||
dp->minmax.extend( dv[ i ]->xyz + projection.normal() * distance );
|
||||
dp.minmax.extend( tri[ i ]->xyz );
|
||||
dp.minmax.extend( tri[ i ]->xyz + projection.normal() * distance );
|
||||
}
|
||||
|
||||
/* make bouding sphere */
|
||||
dp->center = dp->minmax.origin();
|
||||
dp->radius = vector3_length( dp->minmax.maxs - dp->center );
|
||||
dp->radius2 = dp->radius * dp->radius;
|
||||
dp.center = dp.minmax.origin();
|
||||
dp.radius = vector3_length( dp.minmax.maxs - dp.center );
|
||||
dp.radius2 = dp.radius * dp.radius;
|
||||
|
||||
/* make the front plane */
|
||||
if ( !PlaneFromPoints( dp->planes[ 0 ], dv[ 0 ]->xyz, dv[ 1 ]->xyz, dv[ 2 ]->xyz ) ) {
|
||||
if ( !PlaneFromPoints( dp.planes[ 0 ], tri[ 0 ]->xyz, tri[ 1 ]->xyz, tri[ 2 ]->xyz ) ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* make the back plane */
|
||||
dp->planes[ 1 ].normal() = -dp->planes[ 0 ].normal();
|
||||
dp->planes[ 1 ].dist() = vector3_dot( dv[ 0 ]->xyz + projection.normal() * distance, dp->planes[ 1 ].normal() );
|
||||
dp.planes[ 1 ].normal() = -dp.planes[ 0 ].normal();
|
||||
dp.planes[ 1 ].dist() = vector3_dot( tri[ 0 ]->xyz + projection.normal() * distance, dp.planes[ 1 ].normal() );
|
||||
|
||||
/* make the side planes */
|
||||
for ( i = 0; i < numVerts; ++i )
|
||||
for ( size_t i = 0; i < tri.size(); ++i )
|
||||
{
|
||||
j = ( i + 1 ) % numVerts;
|
||||
if ( !PlaneFromPoints( dp->planes[ i + 2 ], dv[ j ]->xyz, dv[ i ]->xyz, dv[ i ]->xyz + projection.normal() * distance ) ) {
|
||||
if ( !PlaneFromPoints( dp.planes[ i + 2 ],
|
||||
tri[ ( i + 1 ) % tri.size() ]->xyz,
|
||||
tri[ i ]->xyz,
|
||||
tri[ i ]->xyz + projection.normal() * distance ) ) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -417,28 +410,8 @@ void ProcessDecals(){
|
||||
vert.xyz += e.origin;
|
||||
|
||||
/* iterate through the mesh quads */
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* get drawverts */
|
||||
const bspDrawVert_t *dv[ 4 ] = {
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ]
|
||||
};
|
||||
for( MeshQuadIterator it( mesh ); it; ++it ){
|
||||
#if 0
|
||||
/* planar? (nuking this optimization as it doesn't work on non-rectangular quads) */
|
||||
if ( 0 && PlaneFromPoints( plane, dv[ 0 ]->xyz, dv[ 1 ]->xyz, dv[ 2 ]->xyz ) &&
|
||||
std::fabs( plane3_distance_to_point( plane, dv[ 1 ]->xyz ) ) <= PLANAR_EPSILON ) {
|
||||
@@ -446,15 +419,10 @@ void ProcessDecals(){
|
||||
MakeDecalProjector( p.shaderInfo, projection, distance, 4, dv );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* make first triangle */
|
||||
MakeDecalProjector( p.shaderInfo, projection, distance, 3, dv );
|
||||
|
||||
/* make second triangle */
|
||||
dv[ 1 ] = dv[ 2 ];
|
||||
dv[ 2 ] = dv[ 3 ];
|
||||
MakeDecalProjector( p.shaderInfo, projection, distance, 3, dv );
|
||||
}
|
||||
for( const TriRef& tri : it.tris() )
|
||||
MakeDecalProjector( p.shaderInfo, projection, distance, tri );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,34 +576,14 @@ static void ProjectDecalOntoPatch( decalProjector_t& dp, mapDrawSurface_t& ds ){
|
||||
mesh_t mesh = TessellatedMesh( mesh_t( ds.patchWidth, ds.patchHeight, ds.verts.data() ), IterationsForCurve( ds.longestCurve, patchSubdivisions ) );
|
||||
|
||||
/* iterate through the mesh quads */
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* generate decal for first triangle */
|
||||
for( MeshQuadIterator it( mesh ); it; ++it ){
|
||||
for( const TriRef& tri : it.tris() ){
|
||||
/* generate decal for triangle */
|
||||
winding_t w{
|
||||
mesh.verts[ pw[ r + 0 ] ].xyz,
|
||||
mesh.verts[ pw[ r + 1 ] ].xyz,
|
||||
mesh.verts[ pw[ r + 2 ] ].xyz };
|
||||
tri[ 0 ]->xyz,
|
||||
tri[ 1 ]->xyz,
|
||||
tri[ 2 ]->xyz };
|
||||
ProjectDecalOntoWinding( dp, ds, w );
|
||||
|
||||
/* generate decal for second triangle */
|
||||
winding_t w2{
|
||||
mesh.verts[ pw[ r + 0 ] ].xyz,
|
||||
mesh.verts[ pw[ r + 2 ] ].xyz,
|
||||
mesh.verts[ pw[ r + 3 ] ].xyz };
|
||||
ProjectDecalOntoWinding( dp, ds, w2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -662,37 +662,13 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, const shader
|
||||
}
|
||||
|
||||
/* iterate through the mesh quads */
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
for( MeshQuadIterator it( mesh ); it; ++it )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* get drawverts */
|
||||
const bspDrawVert_t *dv[ 4 ] = {
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ]
|
||||
};
|
||||
const QuadRef quad( it.quad() );
|
||||
/* planar? */
|
||||
Plane3f plane;
|
||||
bool planar = PlaneFromPoints( plane, dv[ 0 ]->xyz, dv[ 1 ]->xyz, dv[ 2 ]->xyz );
|
||||
if ( planar ) {
|
||||
if ( std::fabs( plane3_distance_to_point( plane, dv[ 1 ]->xyz ) ) > PLANAR_EPSILON ) {
|
||||
planar = false;
|
||||
}
|
||||
}
|
||||
|
||||
const bool planar = PlaneFromPoints( plane, quad[ 0 ]->xyz, quad[ 1 ]->xyz, quad[ 2 ]->xyz )
|
||||
&& std::fabs( plane3_distance_to_point( plane, quad[ 1 ]->xyz ) ) < PLANAR_EPSILON;
|
||||
/* generate a quad */
|
||||
if ( planar ) {
|
||||
radWinding_t rw;
|
||||
@@ -700,13 +676,13 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, const shader
|
||||
for ( int v = 0; v < 4; ++v )
|
||||
{
|
||||
/* get most everything */
|
||||
memcpy( &rw.verts[ v ], dv[ v ], sizeof( bspDrawVert_t ) );
|
||||
memcpy( &rw.verts[ v ], quad[ v ], sizeof( bspDrawVert_t ) );
|
||||
|
||||
/* fix colors */
|
||||
for ( int i = 0; i < MAX_LIGHTMAPS; ++i )
|
||||
{
|
||||
rw.verts[ v ].color[ i ].rgb() = getRadVertexLuxel( i, ds.firstVert + dv[ v ]->color[ 0 ][ 0 ] );
|
||||
rw.verts[ v ].color[ i ].alpha() = dv[ v ]->color[ i ].alpha();
|
||||
rw.verts[ v ].color[ i ].rgb() = getRadVertexLuxel( i, ds.firstVert + quad[ v ]->color[ 0 ][ 0 ] );
|
||||
rw.verts[ v ].color[ i ].alpha() = quad[ v ]->color[ i ].alpha();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -719,23 +695,18 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, const shader
|
||||
{
|
||||
radWinding_t rw;
|
||||
rw.numVerts = 3;
|
||||
for ( int t = 0; t < 2; ++t )
|
||||
for ( const TriRef& tri : it.tris() )
|
||||
{
|
||||
for ( int v = 0; v < 3 + t; ++v )
|
||||
for ( int v = 0; v < 3; ++v )
|
||||
{
|
||||
/* get "other" triangle (stupid hacky logic, but whatevah) */
|
||||
if ( v == 1 && t == 1 ) {
|
||||
v++;
|
||||
}
|
||||
|
||||
/* get most everything */
|
||||
memcpy( &rw.verts[ v ], dv[ v ], sizeof( bspDrawVert_t ) );
|
||||
memcpy( &rw.verts[ v ], tri[ v ], sizeof( bspDrawVert_t ) );
|
||||
|
||||
/* fix colors */
|
||||
for ( int i = 0; i < MAX_LIGHTMAPS; ++i )
|
||||
{
|
||||
rw.verts[ v ].color[ i ].rgb() = getRadVertexLuxel( i, ds.firstVert + dv[ v ]->color[ 0 ][ 0 ] );
|
||||
rw.verts[ v ].color[ i ].alpha() = dv[ v ]->color[ i ].alpha();
|
||||
rw.verts[ v ].color[ i ].rgb() = getRadVertexLuxel( i, ds.firstVert + tri[ v ]->color[ 0 ][ 0 ] );
|
||||
rw.verts[ v ].color[ i ].alpha() = tri[ v ]->color[ i ].alpha();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -744,7 +715,6 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, const shader
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* free the mesh */
|
||||
mesh.freeVerts();
|
||||
|
||||
@@ -177,7 +177,7 @@ static int AllocTraceNode(){
|
||||
adds a winding to the raytracing pool
|
||||
*/
|
||||
|
||||
static int AddTraceWinding( traceWinding_t *tw ){
|
||||
static int AddTraceWinding( const traceWinding_t& tw ){
|
||||
int num;
|
||||
|
||||
/* check for a dead winding */
|
||||
@@ -194,7 +194,7 @@ static int AddTraceWinding( traceWinding_t *tw ){
|
||||
}
|
||||
|
||||
/* add the winding */
|
||||
memcpy( &traceWindings[ num ], tw, sizeof( *traceWindings ) );
|
||||
memcpy( &traceWindings[ num ], &tw, sizeof( *traceWindings ) );
|
||||
if ( num == numTraceWindings ) {
|
||||
numTraceWindings++;
|
||||
}
|
||||
@@ -354,23 +354,23 @@ static int SetupTraceNodes_r( int bspNodeNum ){
|
||||
|
||||
#define TW_ON_EPSILON 0.25f
|
||||
|
||||
void ClipTraceWinding( traceWinding_t *tw, const Plane3f& plane, traceWinding_t *front, traceWinding_t *back ){
|
||||
void ClipTraceWinding( const traceWinding_t& tw, const Plane3f& plane, traceWinding_t& front, traceWinding_t& back ){
|
||||
int i, j, k;
|
||||
EPlaneSide sides[ MAX_TW_VERTS ];
|
||||
int counts[ 3 ] = { 0, 0, 0 };
|
||||
float dists[ MAX_TW_VERTS ];
|
||||
float frac;
|
||||
traceVert_t *a, *b, mid;
|
||||
traceVert_t mid;
|
||||
|
||||
|
||||
/* clear front and back */
|
||||
front->numVerts = 0;
|
||||
back->numVerts = 0;
|
||||
front.numVerts = 0;
|
||||
back.numVerts = 0;
|
||||
|
||||
/* classify points */
|
||||
for ( i = 0; i < tw->numVerts; ++i )
|
||||
for ( i = 0; i < tw.numVerts; ++i )
|
||||
{
|
||||
dists[ i ] = plane3_distance_to_point( plane, tw->v[ i ].xyz );
|
||||
dists[ i ] = plane3_distance_to_point( plane, tw.v[ i ].xyz );
|
||||
if ( dists[ i ] < -TW_ON_EPSILON ) {
|
||||
sides[ i ] = eSideBack;
|
||||
}
|
||||
@@ -385,56 +385,56 @@ void ClipTraceWinding( traceWinding_t *tw, const Plane3f& plane, traceWinding_t
|
||||
|
||||
/* entirely on front? */
|
||||
if ( counts[ eSideBack ] == 0 ) {
|
||||
memcpy( front, tw, sizeof( *front ) );
|
||||
memcpy( &front, &tw, sizeof( front ) );
|
||||
}
|
||||
|
||||
/* entirely on back? */
|
||||
else if ( counts[ eSideFront ] == 0 ) {
|
||||
memcpy( back, tw, sizeof( *back ) );
|
||||
memcpy( &back, &tw, sizeof( back ) );
|
||||
}
|
||||
|
||||
/* straddles the plane */
|
||||
else
|
||||
{
|
||||
/* setup front and back */
|
||||
memcpy( front, tw, sizeof( *front ) );
|
||||
front->numVerts = 0;
|
||||
memcpy( back, tw, sizeof( *back ) );
|
||||
back->numVerts = 0;
|
||||
memcpy( &front, &tw, sizeof( front ) );
|
||||
front.numVerts = 0;
|
||||
memcpy( &back, &tw, sizeof( back ) );
|
||||
back.numVerts = 0;
|
||||
|
||||
/* split the winding */
|
||||
for ( i = 0; i < tw->numVerts; ++i )
|
||||
for ( i = 0; i < tw.numVerts; ++i )
|
||||
{
|
||||
/* radix */
|
||||
j = ( i + 1 ) % tw->numVerts;
|
||||
j = ( i + 1 ) % tw.numVerts;
|
||||
|
||||
/* get verts */
|
||||
a = &tw->v[ i ];
|
||||
b = &tw->v[ j ];
|
||||
const traceVert_t& a = tw.v[ i ];
|
||||
const traceVert_t& b = tw.v[ j ];
|
||||
|
||||
/* handle points on the splitting plane */
|
||||
switch ( sides[ i ] )
|
||||
{
|
||||
case eSideFront:
|
||||
if ( front->numVerts >= MAX_TW_VERTS ) {
|
||||
if ( front.numVerts >= MAX_TW_VERTS ) {
|
||||
Error( "MAX_TW_VERTS (%d) exceeded", MAX_TW_VERTS );
|
||||
}
|
||||
front->v[ front->numVerts++ ] = *a;
|
||||
front.v[ front.numVerts++ ] = a;
|
||||
break;
|
||||
|
||||
case eSideBack:
|
||||
if ( back->numVerts >= MAX_TW_VERTS ) {
|
||||
if ( back.numVerts >= MAX_TW_VERTS ) {
|
||||
Error( "MAX_TW_VERTS (%d) exceeded", MAX_TW_VERTS );
|
||||
}
|
||||
back->v[ back->numVerts++ ] = *a;
|
||||
back.v[ back.numVerts++ ] = a;
|
||||
break;
|
||||
|
||||
case eSideOn:
|
||||
if ( front->numVerts >= MAX_TW_VERTS || back->numVerts >= MAX_TW_VERTS ) {
|
||||
if ( front.numVerts >= MAX_TW_VERTS || back.numVerts >= MAX_TW_VERTS ) {
|
||||
Error( "MAX_TW_VERTS (%d) exceeded", MAX_TW_VERTS );
|
||||
}
|
||||
front->v[ front->numVerts++ ] = *a;
|
||||
back->v[ back->numVerts++ ] = *a;
|
||||
front.v[ front.numVerts++ ] = a;
|
||||
back.v[ back.numVerts++ ] = a;
|
||||
continue;
|
||||
case eSideCross: // unused here, suppress warning
|
||||
break;
|
||||
@@ -446,7 +446,7 @@ void ClipTraceWinding( traceWinding_t *tw, const Plane3f& plane, traceWinding_t
|
||||
}
|
||||
|
||||
/* check limit */
|
||||
if ( front->numVerts >= MAX_TW_VERTS || back->numVerts >= MAX_TW_VERTS ) {
|
||||
if ( front.numVerts >= MAX_TW_VERTS || back.numVerts >= MAX_TW_VERTS ) {
|
||||
Error( "MAX_TW_VERTS (%d) exceeded", MAX_TW_VERTS );
|
||||
}
|
||||
|
||||
@@ -462,15 +462,15 @@ void ClipTraceWinding( traceWinding_t *tw, const Plane3f& plane, traceWinding_t
|
||||
mid.xyz[ k ] = -plane.dist();
|
||||
}
|
||||
else{
|
||||
mid.xyz[ k ] = a->xyz[ k ] + frac * ( b->xyz[ k ] - a->xyz[ k ] );
|
||||
mid.xyz[ k ] = a.xyz[ k ] + frac * ( b.xyz[ k ] - a.xyz[ k ] );
|
||||
}
|
||||
}
|
||||
/* set texture coordinates */
|
||||
mid.st = a->st + ( b->st - a->st ) * frac;
|
||||
mid.st = a.st + ( b.st - a.st ) * frac;
|
||||
|
||||
/* copy midpoint to front and back polygons */
|
||||
front->v[ front->numVerts++ ] = mid;
|
||||
back->v[ back->numVerts++ ] = mid;
|
||||
front.v[ front.numVerts++ ] = mid;
|
||||
back.v[ back.numVerts++ ] = mid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -482,7 +482,7 @@ void ClipTraceWinding( traceWinding_t *tw, const Plane3f& plane, traceWinding_t
|
||||
filters a trace winding into the raytracing tree
|
||||
*/
|
||||
|
||||
static void FilterTraceWindingIntoNodes_r( traceWinding_t *tw, int nodeNum ){
|
||||
static void FilterTraceWindingIntoNodes_r( traceWinding_t& tw, int nodeNum ){
|
||||
int num;
|
||||
Plane3f plane1, plane2, reverse;
|
||||
traceNode_t *node;
|
||||
@@ -501,7 +501,7 @@ static void FilterTraceWindingIntoNodes_r( traceWinding_t *tw, int nodeNum ){
|
||||
if ( node->type >= 0 ) {
|
||||
/* create winding plane if necessary, filtering out bogus windings as well */
|
||||
if ( nodeNum == headNodeNum ) {
|
||||
if ( !PlaneFromPoints( tw->plane, tw->v[ 0 ].xyz, tw->v[ 1 ].xyz, tw->v[ 2 ].xyz ) ) {
|
||||
if ( !PlaneFromPoints( tw.plane, tw.v[ 0 ].xyz, tw.v[ 1 ].xyz, tw.v[ 2 ].xyz ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -515,7 +515,7 @@ static void FilterTraceWindingIntoNodes_r( traceWinding_t *tw, int nodeNum ){
|
||||
plane1 = node->plane;
|
||||
|
||||
/* get winding plane */
|
||||
plane2 = tw->plane;
|
||||
plane2 = tw.plane;
|
||||
|
||||
/* invert surface plane */
|
||||
reverse = plane3_flipped( plane2 );
|
||||
@@ -533,14 +533,14 @@ static void FilterTraceWindingIntoNodes_r( traceWinding_t *tw, int nodeNum ){
|
||||
}
|
||||
|
||||
/* clip the winding by node plane */
|
||||
ClipTraceWinding( tw, plane1, &front, &back );
|
||||
ClipTraceWinding( tw, plane1, front, back );
|
||||
|
||||
/* filter by node plane */
|
||||
if ( front.numVerts >= 3 ) {
|
||||
FilterTraceWindingIntoNodes_r( &front, node->children[ 0 ] );
|
||||
FilterTraceWindingIntoNodes_r( front, node->children[ 0 ] );
|
||||
}
|
||||
if ( back.numVerts >= 3 ) {
|
||||
FilterTraceWindingIntoNodes_r( &back, node->children[ 1 ] );
|
||||
FilterTraceWindingIntoNodes_r( back, node->children[ 1 ] );
|
||||
}
|
||||
|
||||
/* return to caller */
|
||||
@@ -563,7 +563,7 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){
|
||||
int i, j, count, num, frontNum, backNum, type;
|
||||
float dist;
|
||||
traceNode_t *node, *frontNode, *backNode;
|
||||
traceWinding_t *tw, front, back;
|
||||
traceWinding_t front, back;
|
||||
|
||||
|
||||
/* dummy check */
|
||||
@@ -599,13 +599,13 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){
|
||||
for ( i = 0; i < node->numItems; ++i )
|
||||
{
|
||||
/* get winding */
|
||||
tw = &traceWindings[ node->items[ i ] ];
|
||||
const traceWinding_t& tw = traceWindings[ node->items[ i ] ];
|
||||
|
||||
/* walk its verts */
|
||||
for ( j = 0; j < tw->numVerts; ++j )
|
||||
for ( j = 0; j < tw.numVerts; ++j )
|
||||
{
|
||||
node->minmax.extend( tw->v[ j ].xyz );
|
||||
average += tw->v[ j ].xyz;
|
||||
node->minmax.extend( tw.v[ j ].xyz );
|
||||
average += tw.v[ j ].xyz;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -676,10 +676,10 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){
|
||||
for ( i = 0; i < node->numItems; ++i )
|
||||
{
|
||||
/* get winding */
|
||||
tw = &traceWindings[ node->items[ i ] ];
|
||||
const traceWinding_t& tw = traceWindings[ node->items[ i ] ];
|
||||
|
||||
/* clip the winding by the new split plane */
|
||||
ClipTraceWinding( tw, node->plane, &front, &back );
|
||||
ClipTraceWinding( tw, node->plane, front, back );
|
||||
|
||||
/* kill the existing winding */
|
||||
if ( front.numVerts >= 3 || back.numVerts >= 3 ) {
|
||||
@@ -688,13 +688,13 @@ static void SubdivideTraceNode_r( int nodeNum, int depth ){
|
||||
|
||||
/* add front winding */
|
||||
if ( front.numVerts >= 3 ) {
|
||||
num = AddTraceWinding( &front );
|
||||
num = AddTraceWinding( front );
|
||||
AddItemToTraceNode( frontNode, num );
|
||||
}
|
||||
|
||||
/* add back winding */
|
||||
if ( back.numVerts >= 3 ) {
|
||||
num = AddTraceWinding( &back );
|
||||
num = AddTraceWinding( back );
|
||||
AddItemToTraceNode( backNode, num );
|
||||
}
|
||||
}
|
||||
@@ -894,44 +894,14 @@ static void PopulateWithBSPModel( const bspModel_t& model, const Matrix4& transf
|
||||
mesh_t mesh = TessellatedMesh( mesh_t( ds.patchWidth, ds.patchHeight, &bspDrawVerts[ ds.firstVert ] ), info.patchIterations );
|
||||
|
||||
/* subdivide each quad to place the models */
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
for( MeshQuadIterator it( mesh ); it; ++it ){
|
||||
for( const TriRef& tri : it.tris() ){
|
||||
for( int i = 0; i < 3; ++i )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* make first triangle */
|
||||
tw.v[ 0 ].xyz = mesh.verts[ pw[ r + 0 ] ].xyz;
|
||||
tw.v[ 0 ].st = mesh.verts[ pw[ r + 0 ] ].st;
|
||||
tw.v[ 1 ].xyz = mesh.verts[ pw[ r + 1 ] ].xyz;
|
||||
tw.v[ 1 ].st = mesh.verts[ pw[ r + 1 ] ].st;
|
||||
tw.v[ 2 ].xyz = mesh.verts[ pw[ r + 2 ] ].xyz;
|
||||
tw.v[ 2 ].st = mesh.verts[ pw[ r + 2 ] ].st;
|
||||
matrix4_transform_point( transform, tw.v[ 0 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 1 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 2 ].xyz );
|
||||
FilterTraceWindingIntoNodes_r( &tw, nodeNum );
|
||||
|
||||
/* make second triangle */
|
||||
tw.v[ 0 ].xyz = mesh.verts[ pw[ r + 0 ] ].xyz;
|
||||
tw.v[ 0 ].st = mesh.verts[ pw[ r + 0 ] ].st;
|
||||
tw.v[ 1 ].xyz = mesh.verts[ pw[ r + 2 ] ].xyz;
|
||||
tw.v[ 1 ].st = mesh.verts[ pw[ r + 2 ] ].st;
|
||||
tw.v[ 2 ].xyz = mesh.verts[ pw[ r + 3 ] ].xyz;
|
||||
tw.v[ 2 ].st = mesh.verts[ pw[ r + 3 ] ].st;
|
||||
matrix4_transform_point( transform, tw.v[ 0 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 1 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 2 ].xyz );
|
||||
FilterTraceWindingIntoNodes_r( &tw, nodeNum );
|
||||
tw.v[ i ].xyz = matrix4_transformed_point( transform, tri[ i ]->xyz );
|
||||
tw.v[ i ].st = tri[ i ]->st;
|
||||
}
|
||||
FilterTraceWindingIntoNodes_r( tw, nodeNum );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -950,16 +920,13 @@ static void PopulateWithBSPModel( const bspModel_t& model, const Matrix4& transf
|
||||
/* walk the triangle list */
|
||||
for ( int j = 0; j < ds.numIndexes; j += 3 )
|
||||
{
|
||||
tw.v[ 0 ].xyz = verts[ indexes[ j + 0 ] ].xyz;
|
||||
tw.v[ 0 ].st = verts[ indexes[ j + 0 ] ].st;
|
||||
tw.v[ 1 ].xyz = verts[ indexes[ j + 1 ] ].xyz;
|
||||
tw.v[ 1 ].st = verts[ indexes[ j + 1 ] ].st;
|
||||
tw.v[ 2 ].xyz = verts[ indexes[ j + 2 ] ].xyz;
|
||||
tw.v[ 2 ].st = verts[ indexes[ j + 2 ] ].st;
|
||||
matrix4_transform_point( transform, tw.v[ 0 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 1 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 2 ].xyz );
|
||||
FilterTraceWindingIntoNodes_r( &tw, nodeNum );
|
||||
for( int i = 0; i < 3; ++i )
|
||||
{
|
||||
const bspDrawVert_t& v = verts[ indexes[ j + i ] ];
|
||||
tw.v[ i ].xyz = matrix4_transformed_point( transform, v.xyz );
|
||||
tw.v[ i ].st = v.st;
|
||||
}
|
||||
FilterTraceWindingIntoNodes_r( tw, nodeNum );
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1018,11 +985,11 @@ static void PopulateWithPicoModel( int castShadows, const std::vector<const AssM
|
||||
|
||||
/* walk the triangle list */
|
||||
mesh->forEachFace( [&tw, &transform]( const Vector3 ( &xyz )[3], const Vector2 ( &st )[3] ){
|
||||
for( size_t i = 0; i < 3; ++i ){
|
||||
for( int i = 0; i < 3; ++i ){
|
||||
tw.v[ i ].xyz = matrix4_transformed_point( transform, xyz[ i ] );
|
||||
tw.v[ i ].st = st[ i ];
|
||||
}
|
||||
FilterTraceWindingIntoNodes_r( &tw, headNodeNum );
|
||||
FilterTraceWindingIntoNodes_r( tw, headNodeNum );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1151,7 +1151,7 @@ static bool MapQuad( rawLightmap_t *lm, const surfaceInfo_t *info, const QuadRef
|
||||
*/
|
||||
|
||||
void MapRawLightmap( int rawLightmapNum ){
|
||||
int n, i, x, y, sx, sy, mapNonAxial;
|
||||
int n, i, x, y, sx, sy;
|
||||
float samples, radius, pass;
|
||||
rawLightmap_t *lm;
|
||||
bspDrawVert_t fake;
|
||||
@@ -1207,7 +1207,7 @@ void MapRawLightmap( int rawLightmapNum ){
|
||||
const bspDrawVert_t *verts = &yDrawVerts[ ds.firstVert ];
|
||||
|
||||
/* map the triangles */
|
||||
for ( mapNonAxial = 0; mapNonAxial < 2; ++mapNonAxial )
|
||||
for ( int mapNonAxial = 0; mapNonAxial < 2; ++mapNonAxial )
|
||||
for ( i = 0; i < ds.numIndexes; i += 3 )
|
||||
MapTriangle( lm, info, TriRef{
|
||||
&verts[ bspDrawIndexes[ ds.firstIndex + i ] ],
|
||||
@@ -1232,82 +1232,24 @@ void MapRawLightmap( int rawLightmapNum ){
|
||||
|
||||
/* map the mesh quads */
|
||||
#if 0
|
||||
|
||||
for ( mapNonAxial = 0; mapNonAxial < 2; ++mapNonAxial )
|
||||
for ( int mapNonAxial = 0; mapNonAxial < 2; ++mapNonAxial )
|
||||
{
|
||||
for ( y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* get drawverts and map first triangle */
|
||||
MapTriangle( lm, info, TriRef{
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ] }, mapNonAxial );
|
||||
|
||||
/* get drawverts and map second triangle */
|
||||
MapTriangle( lm, info, TriRef{
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ] }, mapNonAxial );
|
||||
for( MeshQuadIterator it( mesh ); it; ++it ){
|
||||
for( const TriRef& tri : it.tris() )
|
||||
MapTriangle( lm, info, tri, mapNonAxial );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
for ( y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
for( MeshQuadIterator it( mesh ); it; ++it ){
|
||||
/* attempt to map quad first */
|
||||
if ( MapQuad( lm, info, QuadRef{
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ] } ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( mapNonAxial = 0; mapNonAxial < 2; ++mapNonAxial )
|
||||
if ( !MapQuad( lm, info, it.quad() ) ) {
|
||||
for ( int mapNonAxial = 0; mapNonAxial < 2; ++mapNonAxial )
|
||||
{
|
||||
/* get drawverts and map first triangle */
|
||||
MapTriangle( lm, info, TriRef{
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ] }, mapNonAxial );
|
||||
|
||||
/* get drawverts and map second triangle */
|
||||
MapTriangle( lm, info, TriRef{
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ] }, mapNonAxial );
|
||||
for( const TriRef& tri : it.tris() )
|
||||
MapTriangle( lm, info, tri, mapNonAxial );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* free the mesh */
|
||||
|
||||
@@ -1667,33 +1667,11 @@ static bool ApproximateLightmap( rawLightmap_t *lm ){
|
||||
|
||||
/* map the mesh quads */
|
||||
info.approximated = true;
|
||||
for ( int y = 0; y < ( mesh.height - 1 ) && info.approximated; ++y )
|
||||
for( MeshQuadIterator it( mesh ); it && info.approximated; ++it ){
|
||||
for( const TriRef& tri : it.tris() )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh.width - 1 ) && info.approximated; ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* get drawverts and map first triangle */
|
||||
info.approximated = ApproximateTriangle_r( lm, TriRef{
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ] } );
|
||||
|
||||
/* get drawverts and map second triangle */
|
||||
if ( info.approximated ) {
|
||||
info.approximated = ApproximateTriangle_r( lm, TriRef{
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ] } );
|
||||
info.approximated = ApproximateTriangle_r( lm, tri );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1534,6 +1534,64 @@ mesh_t TessellatedMesh( const mesh_t in, int iterations );
|
||||
void MakeMeshNormals( mesh_t& in );
|
||||
void PutMeshOnCurve( mesh_t& in );
|
||||
|
||||
class MeshQuadIterator
|
||||
{
|
||||
const mesh_t m;
|
||||
int y, x;
|
||||
std::array<int, 4> _idx;
|
||||
void update_idx(){
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * m.width ),
|
||||
x + ( ( y + 1 ) * m.width ),
|
||||
x + 1 + ( ( y + 1 ) * m.width ),
|
||||
x + 1 + ( y * m.width ),
|
||||
x + ( y * m.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
_idx = { pw[ r + 0 ],
|
||||
pw[ r + 1 ],
|
||||
pw[ r + 2 ],
|
||||
pw[ r + 3 ] };
|
||||
}
|
||||
public:
|
||||
MeshQuadIterator( const mesh_t m ) : m( m ), y( 0 ), x( 0 ) {
|
||||
update_idx();
|
||||
}
|
||||
void operator++(){
|
||||
/* iterate through the mesh quads */
|
||||
// for ( int y = 0; y < ( m.height - 1 ); ++y )
|
||||
// for ( int x = 0; x < ( m.width - 1 ); ++x )
|
||||
if( ++x >= ( m.width - 1 ) ){
|
||||
x = 0;
|
||||
++y;
|
||||
}
|
||||
update_idx();
|
||||
}
|
||||
operator bool() const {
|
||||
return y < ( m.height - 1 );
|
||||
}
|
||||
const std::array<int, 4>& idx() const {
|
||||
return _idx;
|
||||
}
|
||||
QuadRef quad() const {
|
||||
return { m.verts + _idx[0],
|
||||
m.verts + _idx[1],
|
||||
m.verts + _idx[2],
|
||||
m.verts + _idx[3] };
|
||||
}
|
||||
std::array<TriRef, 2> tris() const {
|
||||
return { TriRef{ m.verts + _idx[0],
|
||||
m.verts + _idx[1],
|
||||
m.verts + _idx[2] },
|
||||
TriRef{ m.verts + _idx[0],
|
||||
m.verts + _idx[2],
|
||||
m.verts + _idx[3] } };
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* map.c */
|
||||
void LoadMapFile( const char *filename, bool onlyLights, bool noCollapseGroups );
|
||||
|
||||
@@ -2846,40 +2846,15 @@ static int AddSurfaceModels( mapDrawSurface_t& ds, entity_t& entity ){
|
||||
mesh_t mesh = TessellatedMesh( mesh_t( ds.patchWidth, ds.patchHeight, ds.verts.data() ), IterationsForCurve( ds.longestCurve, patchSubdivisions ) );
|
||||
|
||||
/* subdivide each quad to place the models */
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
for( MeshQuadIterator it( mesh ); it; ++it ){
|
||||
for( const TriRef& tri : it.tris() )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ), /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* triangle 1 */
|
||||
const int n = AddSurfaceModelsToTriangle_r( ds, model, TriRef{
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ] }, entity );
|
||||
const int n = AddSurfaceModelsToTriangle_r( ds, model, tri, entity );
|
||||
if ( n < 0 ) {
|
||||
mesh.freeVerts();
|
||||
return n;
|
||||
}
|
||||
localNumSurfaceModels += n;
|
||||
|
||||
/* triangle 2 */
|
||||
const int n2 = AddSurfaceModelsToTriangle_r( ds, model, TriRef{
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ] }, entity );
|
||||
if ( n2 < 0 ) {
|
||||
return n2;
|
||||
}
|
||||
localNumSurfaceModels += n2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -195,35 +195,9 @@ void Foliage( mapDrawSurface_t& src, entity_t& entity ){
|
||||
subdivided.freeVerts();
|
||||
|
||||
/* map the mesh quads */
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* get drawverts and map first triangle */
|
||||
SubdivideFoliageTriangle_r( foliage, TriRef{
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ]
|
||||
} );
|
||||
/* get drawverts and map second triangle */
|
||||
SubdivideFoliageTriangle_r( foliage, TriRef{
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ]
|
||||
} );
|
||||
}
|
||||
}
|
||||
for( MeshQuadIterator it( mesh ); it; ++it )
|
||||
for( const TriRef& tri : it.tris() )
|
||||
SubdivideFoliageTriangle_r( foliage, tri );
|
||||
|
||||
/* free the mesh */
|
||||
mesh.freeVerts();
|
||||
|
||||
@@ -391,31 +391,16 @@ static void TriangulatePatchSurface( const entity_t& e, mapDrawSurface_t& ds ){
|
||||
dsNew.verts.assign( mesh.verts, mesh.verts + mesh.numVerts() );
|
||||
|
||||
/* iterate through the mesh quads */
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
for( MeshQuadIterator it( mesh ); it; ++it ){
|
||||
/* make first triangle */
|
||||
dsNew.indexes.push_back( pw[ r + 0 ] );
|
||||
dsNew.indexes.push_back( pw[ r + 1 ] );
|
||||
dsNew.indexes.push_back( pw[ r + 2 ] );
|
||||
dsNew.indexes.push_back( it.idx()[0] );
|
||||
dsNew.indexes.push_back( it.idx()[1] );
|
||||
dsNew.indexes.push_back( it.idx()[2] );
|
||||
|
||||
/* make second triangle */
|
||||
dsNew.indexes.push_back( pw[ r + 0 ] );
|
||||
dsNew.indexes.push_back( pw[ r + 2 ] );
|
||||
dsNew.indexes.push_back( pw[ r + 3 ] );
|
||||
}
|
||||
dsNew.indexes.push_back( it.idx()[0] );
|
||||
dsNew.indexes.push_back( it.idx()[2] );
|
||||
dsNew.indexes.push_back( it.idx()[3] );
|
||||
}
|
||||
|
||||
mesh.freeVerts();
|
||||
|
||||
Reference in New Issue
Block a user