using winding_t = std::vector<Vector3>

This commit is contained in:
Garux 2021-07-31 18:28:38 +03:00
parent dbfb22e273
commit c3041cc2f8
18 changed files with 344 additions and 457 deletions

View File

@ -29,10 +29,9 @@
#define BOGUS_RANGE WORLD_SIZE #define BOGUS_RANGE WORLD_SIZE
void pw( winding_t *w ){ void pw( const winding_t& w ){
int i; for ( const Vector3& p : w )
for ( i = 0 ; i < w->numpoints ; i++ ) Sys_Printf( "(%5.1f, %5.1f, %5.1f)\n", p[0], p[1], p[2] );
Sys_Printf( "(%5.1f, %5.1f, %5.1f)\n",w->p[i][0], w->p[i][1],w->p[i][2] );
} }
@ -45,7 +44,9 @@ winding_t *AllocWinding( int points ){
if ( points >= MAX_POINTS_ON_WINDING ) { if ( points >= MAX_POINTS_ON_WINDING ) {
Error( "AllocWinding failed: MAX_POINTS_ON_WINDING exceeded" ); Error( "AllocWinding failed: MAX_POINTS_ON_WINDING exceeded" );
} }
return safe_calloc( offsetof_array( winding_t, p, points ) ); winding_t *w = new winding_t;
w->reserve( points );
return w;
} }
/* /*
@ -57,13 +58,7 @@ void FreeWinding( winding_t *w ){
if ( !w ) { if ( !w ) {
Error( "FreeWinding: winding is NULL" ); Error( "FreeWinding: winding is NULL" );
} }
delete w;
if ( *(unsigned *)w == 0xdeaddead ) {
Error( "FreeWinding: freed a freed winding" );
}
*(unsigned *)w = 0xdeaddead;
free( w );
} }
/* /*
@ -71,28 +66,22 @@ void FreeWinding( winding_t *w ){
RemoveColinearPoints RemoveColinearPoints
============ ============
*/ */
void RemoveColinearPoints( winding_t *w ){ void RemoveColinearPoints( winding_t& w ){
int i, j, k; winding_t p;
int nump; p.reserve( w.size() );
Vector3 p[MAX_POINTS_ON_WINDING];
nump = 0; for ( size_t i = 0 ; i < w.size() ; i++ )
for ( i = 0 ; i < w->numpoints ; i++ )
{ {
j = ( i + 1 ) % w->numpoints; const size_t j = ( i + 1 ) % w.size();
k = ( i + w->numpoints - 1 ) % w->numpoints; const size_t k = ( i + w.size() - 1 ) % w.size();
if ( vector3_dot( VectorNormalized( w->p[j] - w->p[i] ), VectorNormalized( w->p[j] - w->p[k] ) ) < 0.999 ) { if ( vector3_dot( VectorNormalized( w[j] - w[i] ), VectorNormalized( w[j] - w[k] ) ) < 0.999 ) {
p[nump] = w->p[i]; p.push_back( w[i] );
nump++;
} }
} }
if ( nump == w->numpoints ) { if ( p.size() != w.size() ) {
return; w.swap( p );
} }
w->numpoints = nump;
memcpy( w->p, p, nump * sizeof( p[0] ) );
} }
/* /*
@ -100,9 +89,9 @@ void RemoveColinearPoints( winding_t *w ){
WindingPlane WindingPlane
============ ============
*/ */
Plane3f WindingPlane( const winding_t *w ){ Plane3f WindingPlane( const winding_t& w ){
Plane3f plane; Plane3f plane;
PlaneFromPoints( plane, w->p[0], w->p[1], w->p[2] ); PlaneFromPoints( plane, w.data() );
return plane; return plane;
} }
@ -111,20 +100,20 @@ Plane3f WindingPlane( const winding_t *w ){
WindingArea WindingArea
============= =============
*/ */
float WindingArea( const winding_t *w ){ float WindingArea( const winding_t& w ){
float total = 0; float total = 0;
for ( int i = 2 ; i < w->numpoints ; i++ ) for ( size_t i = 2; i < w.size(); i++ )
{ {
total += 0.5 * vector3_length( vector3_cross( w->p[i - 1] - w->p[0], w->p[i] - w->p[0] ) ); total += 0.5 * vector3_length( vector3_cross( w[i - 1] - w[0], w[i] - w[0] ) );
} }
return total; return total;
} }
void WindingExtendBounds( const winding_t *w, MinMax& minmax ){ void WindingExtendBounds( const winding_t& w, MinMax& minmax ){
for ( int i = 0 ; i < w->numpoints ; ++i ) for ( const Vector3& p : w )
{ {
minmax.extend( w->p[i] ); minmax.extend( p );
} }
} }
@ -133,13 +122,13 @@ void WindingExtendBounds( const winding_t *w, MinMax& minmax ){
WindingCenter WindingCenter
============= =============
*/ */
Vector3 WindingCenter( const winding_t *w ){ Vector3 WindingCenter( const winding_t& w ){
Vector3 center( 0 ); Vector3 center( 0 );
for ( int i = 0 ; i < w->numpoints ; i++ ) for ( const Vector3& p : w )
center += w->p[i]; center += p;
return center / w->numpoints; return center / w.size();
} }
/* /*
@ -261,7 +250,6 @@ winding_t *BaseWindingForPlane( const Plane3f& plane ){
int i, x; int i, x;
float max, v; float max, v;
Vector3 org, vright, vup; Vector3 org, vright, vup;
winding_t *w;
// find the major axis // find the major axis
@ -305,16 +293,12 @@ winding_t *BaseWindingForPlane( const Plane3f& plane ){
vright *= MAX_WORLD_COORD * 2; vright *= MAX_WORLD_COORD * 2;
// project a really big axis aligned box onto the plane // project a really big axis aligned box onto the plane
w = AllocWinding( 4 ); return new winding_t{
org - vright + vup,
w->p[0] = org - vright + vup; org + vright + vup,
w->p[1] = org + vright + vup; org + vright - vup,
w->p[2] = org + vright - vup; org - vright - vup
w->p[3] = org - vright - vup; };
w->numpoints = 4;
return w;
} }
/* /*
@ -326,7 +310,7 @@ winding_t *CopyWinding( const winding_t *w ){
if ( !w ) { if ( !w ) {
Error( "CopyWinding: winding is NULL" ); Error( "CopyWinding: winding is NULL" );
} }
return void_ptr( memcpy( AllocWinding( w->numpoints ), w, offsetof_array( winding_t, p, w->numpoints ) ) ); return new winding_t( *w );
} }
/* /*
@ -335,13 +319,7 @@ winding_t *CopyWinding( const winding_t *w ){
================== ==================
*/ */
winding_t *CopyWindingAccuToRegular( const winding_accu_t& w ){ winding_t *CopyWindingAccuToRegular( const winding_accu_t& w ){
winding_t *c = AllocWinding( w.size() ); return new winding_t( w.begin(), w.end() );
c->numpoints = w.size();
for ( int i = 0; i < c->numpoints; i++ )
{
c->p[i] = w[i];
}
return c;
} }
/* /*
@ -349,17 +327,8 @@ winding_t *CopyWindingAccuToRegular( const winding_accu_t& w ){
ReverseWinding ReverseWinding
================== ==================
*/ */
winding_t *ReverseWinding( const winding_t *w ){ winding_t *ReverseWinding( const winding_t& w ){
int i; return new winding_t( w.crbegin(), w.crend() );
winding_t *c;
c = AllocWinding( w->numpoints );
for ( i = 0 ; i < w->numpoints ; i++ )
{
c->p[i] = w->p[w->numpoints - 1 - i];
}
c->numpoints = w->numpoints;
return c;
} }
@ -368,22 +337,18 @@ winding_t *ReverseWinding( const winding_t *w ){
ClipWindingEpsilon ClipWindingEpsilon
============= =============
*/ */
void ClipWindingEpsilonStrict( winding_t *in, const Plane3f& plane, void ClipWindingEpsilonStrict( const winding_t& in, const Plane3f& plane,
float epsilon, winding_t **front, winding_t **back ){ float epsilon, winding_t *&front, winding_t *&back ){
float dists[MAX_POINTS_ON_WINDING + 4]; float dists[MAX_POINTS_ON_WINDING + 4];
EPlaneSide sides[MAX_POINTS_ON_WINDING + 4]; EPlaneSide sides[MAX_POINTS_ON_WINDING + 4];
int counts[3]; int counts[3] = { 0 };
int i, j; size_t i, j;
winding_t *f, *b;
int maxpts;
counts[0] = counts[1] = counts[2] = 0;
// determine sides for each point // determine sides for each point
for ( i = 0 ; i < in->numpoints ; i++ ) for ( i = 0; i < in.size(); i++ )
{ {
dists[i] = plane3_distance_to_point( plane, in->p[i] ); dists[i] = plane3_distance_to_point( plane, in[i] );
if ( dists[i] > epsilon ) { if ( dists[i] > epsilon ) {
sides[i] = eSideFront; sides[i] = eSideFront;
} }
@ -399,45 +364,41 @@ void ClipWindingEpsilonStrict( winding_t *in, const Plane3f& plane,
sides[i] = sides[0]; sides[i] = sides[0];
dists[i] = dists[0]; dists[i] = dists[0];
*front = *back = NULL; front = back = NULL;
if ( !counts[0] && !counts[1] ) { if ( !counts[eSideFront] && !counts[eSideBack] ) {
return; return;
} }
if ( !counts[0] ) { if ( !counts[eSideFront] ) {
*back = CopyWinding( in ); back = CopyWinding( &in );
return; return;
} }
if ( !counts[1] ) { if ( !counts[eSideBack] ) {
*front = CopyWinding( in ); front = CopyWinding( &in );
return; return;
} }
maxpts = in->numpoints + 4; // cant use counts[0]+2 because const size_t maxpts = in.size() + 4; // cant use counts[0]+2 because
// of fp grouping errors // of fp grouping errors
*front = f = AllocWinding( maxpts ); front = AllocWinding( maxpts );
*back = b = AllocWinding( maxpts ); back = AllocWinding( maxpts );
for ( i = 0 ; i < in->numpoints ; i++ ) for ( i = 0 ; i < in.size() ; i++ )
{ {
const Vector3& p1 = in->p[i]; const Vector3& p1 = in[i];
if ( sides[i] == eSideOn ) { if ( sides[i] == eSideOn ) {
f->p[f->numpoints] = p1; front->push_back( p1 );
f->numpoints++; back->push_back( p1 );
b->p[b->numpoints] = p1;
b->numpoints++;
continue; continue;
} }
if ( sides[i] == eSideFront ) { if ( sides[i] == eSideFront ) {
f->p[f->numpoints] = p1; front->push_back( p1 );
f->numpoints++;
} }
if ( sides[i] == eSideBack ) { if ( sides[i] == eSideBack ) {
b->p[b->numpoints] = p1; back->push_back( p1 );
b->numpoints++;
} }
if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) { if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) {
@ -445,10 +406,10 @@ void ClipWindingEpsilonStrict( winding_t *in, const Plane3f& plane,
} }
// generate a split point // generate a split point
const Vector3& p2 = in->p[( i + 1 ) % in->numpoints]; const Vector3& p2 = in[( i + 1 ) % in.size()];
const double dot = dists[i] / ( dists[i] - dists[i + 1] ); const double dot = dists[i] / ( dists[i] - dists[i + 1] );
Vector3 mid; Vector3 mid;
for ( j = 0 ; j < 3 ; j++ ) for ( j = 0; j < 3; j++ )
{ // avoid round off error when possible { // avoid round off error when possible
if ( plane.normal()[j] == 1 ) { if ( plane.normal()[j] == 1 ) {
mid[j] = plane.dist(); mid[j] = plane.dist();
@ -461,26 +422,21 @@ void ClipWindingEpsilonStrict( winding_t *in, const Plane3f& plane,
} }
} }
f->p[f->numpoints] = mid; front->push_back( mid );
f->numpoints++; back->push_back( mid );
b->p[b->numpoints] = mid;
b->numpoints++;
} }
if ( f->numpoints > maxpts || b->numpoints > maxpts ) { if ( front->size() > MAX_POINTS_ON_WINDING || back->size() > MAX_POINTS_ON_WINDING ) {
Error( "ClipWinding: points exceeded estimate" );
}
if ( f->numpoints > MAX_POINTS_ON_WINDING || b->numpoints > MAX_POINTS_ON_WINDING ) {
Error( "ClipWinding: MAX_POINTS_ON_WINDING" ); Error( "ClipWinding: MAX_POINTS_ON_WINDING" );
} }
} }
void ClipWindingEpsilon( winding_t *in, const Plane3f& plane, void ClipWindingEpsilon( const winding_t& in, const Plane3f& plane,
float epsilon, winding_t **front, winding_t **back ){ float epsilon, winding_t *&front, winding_t *&back ){
ClipWindingEpsilonStrict( in, plane, epsilon, front, back ); ClipWindingEpsilonStrict( in, plane, epsilon, front, back );
/* apparently most code expects that in the winding-on-plane case, the back winding is the original winding */ /* apparently most code expects that in the winding-on-plane case, the back winding is the original winding */
if ( !*front && !*back ) { if ( !front && !back ) {
*back = CopyWinding( in ); back = CopyWinding( &in );
} }
} }
@ -622,22 +578,17 @@ void ChopWindingInPlaceAccu( winding_accu_t& inout, const Plane3& plane, float c
ChopWindingInPlace ChopWindingInPlace
============= =============
*/ */
void ChopWindingInPlace( winding_t **inout, const Plane3f& plane, float epsilon ){ void ChopWindingInPlace( winding_t *&inout, const Plane3f& plane, float epsilon ){
winding_t *in; winding_t& in = *inout;
float dists[MAX_POINTS_ON_WINDING + 4]; float dists[MAX_POINTS_ON_WINDING + 4];
EPlaneSide sides[MAX_POINTS_ON_WINDING + 4]; EPlaneSide sides[MAX_POINTS_ON_WINDING + 4];
int counts[3]; int counts[3] = { 0 };
int i, j; size_t i, j;
winding_t *f;
int maxpts;
in = *inout;
counts[0] = counts[1] = counts[2] = 0;
// determine sides for each point // determine sides for each point
for ( i = 0 ; i < in->numpoints ; i++ ) for ( i = 0; i < in.size(); i++ )
{ {
dists[i] = plane3_distance_to_point( plane, in->p[i] ); dists[i] = plane3_distance_to_point( plane, in[i] );
if ( dists[i] > epsilon ) { if ( dists[i] > epsilon ) {
sides[i] = eSideFront; sides[i] = eSideFront;
} }
@ -653,33 +604,30 @@ void ChopWindingInPlace( winding_t **inout, const Plane3f& plane, float epsilon
sides[i] = sides[0]; sides[i] = sides[0];
dists[i] = dists[0]; dists[i] = dists[0];
if ( !counts[0] ) { if ( !counts[eSideFront] ) {
FreeWinding( in ); FreeWinding( inout );
*inout = NULL; inout = NULL;
return; return;
} }
if ( !counts[1] ) { if ( !counts[eSideBack] ) {
return; // inout stays the same return; // inout stays the same
} }
maxpts = in->numpoints + 4; // cant use counts[0]+2 because
// of fp grouping errors
f = AllocWinding( maxpts ); winding_t f;
f.reserve( in.size() + 4 ); // cant use counts[0]+2 because of fp grouping errors
for ( i = 0 ; i < in->numpoints ; i++ ) for ( i = 0; i < in.size(); i++ )
{ {
const Vector3& p1 = in->p[i]; const Vector3& p1 = in[i];
if ( sides[i] == eSideOn ) { if ( sides[i] == eSideOn ) {
f->p[f->numpoints] = p1; f.push_back( p1 );
f->numpoints++;
continue; continue;
} }
if ( sides[i] == eSideFront ) { if ( sides[i] == eSideFront ) {
f->p[f->numpoints] = p1; f.push_back( p1 );
f->numpoints++;
} }
if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) { if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) {
@ -687,11 +635,11 @@ void ChopWindingInPlace( winding_t **inout, const Plane3f& plane, float epsilon
} }
// generate a split point // generate a split point
const Vector3& p2 = in->p[( i + 1 ) % in->numpoints]; const Vector3& p2 = in[( i + 1 ) % in.size()];
const double dot = dists[i] / ( dists[i] - dists[i + 1] ); const double dot = dists[i] / ( dists[i] - dists[i + 1] );
Vector3 mid; Vector3 mid;
for ( j = 0 ; j < 3 ; j++ ) for ( j = 0; j < 3; j++ )
{ // avoid round off error when possible { // avoid round off error when possible
if ( plane.normal()[j] == 1 ) { if ( plane.normal()[j] == 1 ) {
mid[j] = plane.dist(); mid[j] = plane.dist();
@ -704,19 +652,14 @@ void ChopWindingInPlace( winding_t **inout, const Plane3f& plane, float epsilon
} }
} }
f->p[f->numpoints] = mid; f.push_back( mid );
f->numpoints++;
} }
if ( f->numpoints > maxpts ) { if ( f.size() > MAX_POINTS_ON_WINDING ) {
Error( "ClipWinding: points exceeded estimate" );
}
if ( f->numpoints > MAX_POINTS_ON_WINDING ) {
Error( "ClipWinding: MAX_POINTS_ON_WINDING" ); Error( "ClipWinding: MAX_POINTS_ON_WINDING" );
} }
FreeWinding( in ); inout->swap( f );
*inout = f;
} }
@ -731,7 +674,7 @@ void ChopWindingInPlace( winding_t **inout, const Plane3f& plane, float epsilon
winding_t *ChopWinding( winding_t *in, const Plane3f& plane ){ winding_t *ChopWinding( winding_t *in, const Plane3f& plane ){
winding_t *f, *b; winding_t *f, *b;
ClipWindingEpsilon( in, plane, ON_EPSILON, &f, &b ); ClipWindingEpsilon( *in, plane, ON_EPSILON, f, b );
FreeWinding( in ); FreeWinding( in );
if ( b ) { if ( b ) {
FreeWinding( b ); FreeWinding( b );
@ -747,56 +690,49 @@ inline const MinMax c_worldMinmax( Vector3( MIN_WORLD_COORD ), Vector3( MAX_WORL
================= =================
*/ */
void CheckWinding( winding_t *w ){ void CheckWinding( const winding_t& w ){
int i, j; if ( w.size() < 3 ) {
float edgedist; Error( "CheckWinding: %zu points",w.size() );
Vector3 dir, edgenormal;
float area;
if ( w->numpoints < 3 ) {
Error( "CheckWinding: %i points",w->numpoints );
} }
area = WindingArea( w ); const float area = WindingArea( w );
if ( area < 1 ) { if ( area < 1 ) {
Error( "CheckWinding: %f area", area ); Error( "CheckWinding: %f area", area );
} }
const Plane3f faceplane = WindingPlane( w ); const Plane3f faceplane = WindingPlane( w );
for ( i = 0 ; i < w->numpoints ; i++ ) for ( size_t i = 0 ; i < w.size() ; i++ )
{ {
const Vector3& p1 = w->p[i]; const Vector3& p1 = w[i];
if ( !c_worldMinmax.test( p1 ) ) { if ( !c_worldMinmax.test( p1 ) ) {
Error( "CheckFace: MAX_WORLD_COORD exceeded: ( %f %f %f )", p1[0], p1[1], p1[2] ); Error( "CheckFace: MAX_WORLD_COORD exceeded: ( %f %f %f )", p1[0], p1[1], p1[2] );
} }
j = ( i + 1 == w->numpoints )? 0 : i + 1;
// check the point is on the face plane // check the point is on the face plane
if ( fabs( plane3_distance_to_point( faceplane, p1 ) ) > ON_EPSILON ) { if ( fabs( plane3_distance_to_point( faceplane, p1 ) ) > ON_EPSILON ) {
Error( "CheckWinding: point off plane" ); Error( "CheckWinding: point off plane" );
} }
// check the edge isnt degenerate // check the edge isnt degenerate
const Vector3& p2 = w->p[j]; const Vector3& p2 = w[( i + 1 == w.size() )? 0 : i + 1];
dir = p2 - p1; const Vector3 dir = p2 - p1;
if ( vector3_length( dir ) < ON_EPSILON ) { if ( vector3_length( dir ) < ON_EPSILON ) {
Error( "CheckWinding: degenerate edge" ); Error( "CheckWinding: degenerate edge" );
} }
edgenormal = VectorNormalized( vector3_cross( faceplane.normal(), dir ) ); const Vector3 edgenormal = VectorNormalized( vector3_cross( faceplane.normal(), dir ) );
edgedist = vector3_dot( p1, edgenormal ) + ON_EPSILON; const float edgedist = vector3_dot( p1, edgenormal ) + ON_EPSILON;
// all other points must be on front side // all other points must be on front side
for ( j = 0 ; j < w->numpoints ; j++ ) for ( size_t j = 0 ; j < w.size() ; j++ )
{ {
if ( j == i ) { if ( j == i ) {
continue; continue;
} }
if ( vector3_dot( w->p[j], edgenormal ) > edgedist ) { if ( vector3_dot( w[j], edgenormal ) > edgedist ) {
Error( "CheckWinding: non-convex" ); Error( "CheckWinding: non-convex" );
} }
} }
@ -809,12 +745,12 @@ void CheckWinding( winding_t *w ){
WindingOnPlaneSide WindingOnPlaneSide
============ ============
*/ */
EPlaneSide WindingOnPlaneSide( const winding_t *w, const Plane3f& plane ){ EPlaneSide WindingOnPlaneSide( const winding_t& w, const Plane3f& plane ){
bool front = false; bool front = false;
bool back = false; bool back = false;
for ( int i = 0 ; i < w->numpoints ; i++ ) for ( const Vector3& p : w )
{ {
const double d = plane3_distance_to_point( plane, w->p[i] ); const double d = plane3_distance_to_point( plane, p );
if ( d < -ON_EPSILON ) { if ( d < -ON_EPSILON ) {
if ( front ) { if ( front ) {
return eSideCross; return eSideCross;
@ -849,8 +785,8 @@ EPlaneSide WindingOnPlaneSide( const winding_t *w, const Plane3f& plane ){
================= =================
*/ */
#define MAX_HULL_POINTS 128 #define MAX_HULL_POINTS 128
void AddWindingToConvexHull( winding_t *w, winding_t **hull, const Vector3& normal ) { void AddWindingToConvexHull( const winding_t& w, winding_t *&hull, const Vector3& normal ) {
int i, j, k; int j, k;
int numHullPoints, numNew; int numHullPoints, numNew;
Vector3 hullPoints[MAX_HULL_POINTS]; Vector3 hullPoints[MAX_HULL_POINTS];
Vector3 newHullPoints[MAX_HULL_POINTS]; Vector3 newHullPoints[MAX_HULL_POINTS];
@ -858,26 +794,24 @@ void AddWindingToConvexHull( winding_t *w, winding_t **hull, const Vector3& n
bool hullSide[MAX_HULL_POINTS]; bool hullSide[MAX_HULL_POINTS];
bool outside; bool outside;
if ( *hull == nullptr ) { if ( hull == nullptr ) {
*hull = CopyWinding( w ); hull = CopyWinding( &w );
return; return;
} }
numHullPoints = ( *hull )->numpoints; numHullPoints = hull->size();
memcpy( hullPoints, ( *hull )->p, numHullPoints * sizeof( Vector3 ) ); memcpy( hullPoints, hull->data(), numHullPoints * sizeof( Vector3 ) );
for ( i = 0 ; i < w->numpoints ; i++ ) {
const Vector3 &p = w->p[i];
for ( const Vector3 &p : w ) {
// calculate hull side vectors // calculate hull side vectors
for ( j = 0 ; j < numHullPoints ; j++ ) { for ( j = 0; j < numHullPoints; j++ ) {
k = ( j + 1 ) % numHullPoints; k = ( j + 1 ) % numHullPoints;
hullDirs[j] = vector3_cross( normal, VectorNormalized( hullPoints[k] - hullPoints[j] ) ); hullDirs[j] = vector3_cross( normal, VectorNormalized( hullPoints[k] - hullPoints[j] ) );
} }
outside = false; outside = false;
for ( j = 0 ; j < numHullPoints ; j++ ) { for ( j = 0; j < numHullPoints; j++ ) {
const double d = vector3_dot( p - hullPoints[j], hullDirs[j] ); const double d = vector3_dot( p - hullPoints[j], hullDirs[j] );
if ( d >= ON_EPSILON ) { if ( d >= ON_EPSILON ) {
outside = true; outside = true;
@ -891,7 +825,7 @@ void AddWindingToConvexHull( winding_t *w, winding_t **hull, const Vector3& n
} }
// find the back side to front side transition // find the back side to front side transition
for ( j = 0 ; j < numHullPoints ; j++ ) { for ( j = 0; j < numHullPoints; j++ ) {
if ( !hullSide[ j % numHullPoints ] && hullSide[ ( j + 1 ) % numHullPoints ] ) { if ( !hullSide[ j % numHullPoints ] && hullSide[ ( j + 1 ) % numHullPoints ] ) {
break; break;
} }
@ -906,7 +840,7 @@ void AddWindingToConvexHull( winding_t *w, winding_t **hull, const Vector3& n
// copy over all points that aren't double fronts // copy over all points that aren't double fronts
j = ( j + 1 ) % numHullPoints; j = ( j + 1 ) % numHullPoints;
for ( k = 0 ; k < numHullPoints ; k++ ) { for ( k = 0; k < numHullPoints; k++ ) {
if ( hullSide[ ( j + k ) % numHullPoints ] && hullSide[ ( j + k + 1 ) % numHullPoints ] ) { if ( hullSide[ ( j + k ) % numHullPoints ] && hullSide[ ( j + k + 1 ) % numHullPoints ] ) {
continue; continue;
} }
@ -918,9 +852,5 @@ void AddWindingToConvexHull( winding_t *w, winding_t **hull, const Vector3& n
memcpy( hullPoints, newHullPoints, numHullPoints * sizeof( Vector3 ) ); memcpy( hullPoints, newHullPoints, numHullPoints * sizeof( Vector3 ) );
} }
FreeWinding( *hull ); *hull = winding_t( hullPoints, hullPoints + numHullPoints );
w = AllocWinding( numHullPoints );
w->numpoints = numHullPoints;
*hull = w;
memcpy( w->p, hullPoints, numHullPoints * sizeof( Vector3 ) );
} }

View File

@ -23,11 +23,7 @@
#include "qmath.h" #include "qmath.h"
struct winding_t using winding_t = std::vector<Vector3>;
{
int numpoints;
Vector3 p[];
};
#define MAX_POINTS_ON_WINDING 512 #define MAX_POINTS_ON_WINDING 512
@ -45,29 +41,29 @@ enum EPlaneSide
}; };
winding_t *AllocWinding( int points ); winding_t *AllocWinding( int points );
float WindingArea( const winding_t *w ); float WindingArea( const winding_t& w );
Vector3 WindingCenter( const winding_t *w ); Vector3 WindingCenter( const winding_t& w );
void ClipWindingEpsilon( winding_t *in, const Plane3f& plane, void ClipWindingEpsilon( const winding_t& in, const Plane3f& plane,
float epsilon, winding_t **front, winding_t **back ); float epsilon, winding_t *&front, winding_t *&back );
void ClipWindingEpsilonStrict( winding_t *in, const Plane3f& plane, void ClipWindingEpsilonStrict( const winding_t& in, const Plane3f& plane,
float epsilon, winding_t **front, winding_t **back ); float epsilon, winding_t *&front, winding_t *&back );
winding_t *ChopWinding( winding_t *in, const Plane3f& plane ); winding_t *ChopWinding( winding_t *in, const Plane3f& plane );
winding_t *CopyWinding( const winding_t *w ); winding_t *CopyWinding( const winding_t *w );
winding_t *ReverseWinding( const winding_t *w ); winding_t *ReverseWinding( const winding_t& w );
winding_t *BaseWindingForPlane( const Plane3f& plane ); winding_t *BaseWindingForPlane( const Plane3f& plane );
void CheckWinding( winding_t *w ); void CheckWinding( const winding_t& w );
Plane3f WindingPlane( const winding_t *w ); Plane3f WindingPlane( const winding_t& w );
void RemoveColinearPoints( winding_t *w ); void RemoveColinearPoints( winding_t& w );
EPlaneSide WindingOnPlaneSide( const winding_t *w, const Plane3f& plane ); EPlaneSide WindingOnPlaneSide( const winding_t& w, const Plane3f& plane );
void FreeWinding( winding_t *w ); void FreeWinding( winding_t *w );
void WindingExtendBounds( const winding_t *w, MinMax& minmax ); void WindingExtendBounds( const winding_t& w, MinMax& minmax );
void AddWindingToConvexHull( winding_t *w, winding_t **hull, const Vector3& normal ); void AddWindingToConvexHull( const winding_t& w, winding_t *&hull, const Vector3& normal );
void ChopWindingInPlace( winding_t **w, const Plane3f& plane, float epsilon ); void ChopWindingInPlace( winding_t *&w, const Plane3f& plane, float epsilon );
// frees the original if clipped // frees the original if clipped
void pw( winding_t *w ); void pw( const winding_t& w );
/////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////

View File

@ -180,7 +180,7 @@ bool BoundBrush( brush_t *brush ){
{ {
const winding_t *w = brush->sides[ i ].winding; const winding_t *w = brush->sides[ i ].winding;
if ( w != NULL ) { if ( w != NULL ) {
WindingExtendBounds( w, brush->minmax ); WindingExtendBounds( *w, brush->minmax );
} }
} }
@ -198,17 +198,15 @@ bool BoundBrush( brush_t *brush ){
#define SNAP_EPSILON 0.01 #define SNAP_EPSILON 0.01
void SnapWeldVector( const Vector3& a, const Vector3& b, Vector3& out ){ Vector3 SnapWeldVector( const Vector3& a, const Vector3& b ){
int i; Vector3 out;
float ai, bi, outi;
/* do each element */ /* do each element */
for ( i = 0; i < 3; i++ ) for ( int i = 0; i < 3; i++ )
{ {
/* round to integer */ /* round to integer */
ai = std::rint( a[ i ] ); const float ai = std::rint( a[ i ] );
bi = std::rint( b[ i ] ); const float bi = std::rint( b[ i ] );
/* prefer exact integer */ /* prefer exact integer */
if ( ai == a[ i ] ) { if ( ai == a[ i ] ) {
@ -227,11 +225,13 @@ void SnapWeldVector( const Vector3& a, const Vector3& b, Vector3& out ){
} }
/* snap */ /* snap */
outi = std::rint( out[ i ] ); const float outi = std::rint( out[ i ] );
if ( fabs( outi - out[ i ] ) <= SNAP_EPSILON ) { if ( fabs( outi - out[ i ] ) <= SNAP_EPSILON ) {
out[ i ] = outi; out[ i ] = outi;
} }
} }
return out;
} }
/* /*
@ -292,9 +292,6 @@ DoubleVector3 SnapWeldVectorAccu( const DoubleVector3& a, const DoubleVector3& b
bool FixWinding( winding_t *w ){ bool FixWinding( winding_t *w ){
bool valid = true; bool valid = true;
int i, j, k;
Vector3 vec;
/* dummy check */ /* dummy check */
if ( !w ) { if ( !w ) {
@ -302,38 +299,30 @@ bool FixWinding( winding_t *w ){
} }
/* check all verts */ /* check all verts */
for ( i = 0; i < w->numpoints; i++ ) for ( winding_t::iterator i = w->end() - 1, j = w->begin(); j != w->end(); i = j, ++j )
{ {
/* don't remove points if winding is a triangle */ /* don't remove points if winding is a triangle */
if ( w->numpoints == 3 ) { if ( w->size() == 3 ) {
return valid; return valid;
} }
/* get second point index */
j = ( i + 1 ) % w->numpoints;
/* degenerate edge? */ /* degenerate edge? */
if ( vector3_length( w->p[ i ] - w->p[ j ] ) < DEGENERATE_EPSILON ) { if ( vector3_length( *i - *j ) < DEGENERATE_EPSILON ) {
valid = false; valid = false;
//Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: Degenerate winding edge found, fixing...\n" ); //Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: Degenerate winding edge found, fixing...\n" );
/* create an average point (ydnar 2002-01-26: using nearest-integer weld preference) */ /* create an average point (ydnar 2002-01-26: using nearest-integer weld preference) */
SnapWeldVector( w->p[ i ], w->p[ j ], vec ); *i = SnapWeldVector( *i, *j );
w->p[ i ] = vec;
//VectorAdd( w->p[ i ], w->p[ j ], vec ); //VectorAdd( w->p[ i ], w->p[ j ], vec );
//VectorScale( vec, 0.5, w->p[ i ] ); //VectorScale( vec, 0.5, w->p[ i ] );
/* move the remaining verts */ /* move the remaining verts */
for ( k = i + 2; k < w->numpoints; k++ ) w->erase( j );
{
w->p[ k - 1 ] = w->p[ k ];
}
w->numpoints--;
} }
} }
/* one last check and return */ /* one last check and return */
if ( w->numpoints < 3 ) { if ( w->size() < 3 ) {
valid = false; valid = false;
} }
return valid; return valid;
@ -426,7 +415,7 @@ bool CreateBrushWindings( brush_t *brush ){
#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES #if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES
ChopWindingInPlaceAccu( w, ( cside.plane.normal() != g_vector3_identity )? plane3_flipped( cside.plane ) : Plane3( cplane.plane ), 0 ); ChopWindingInPlaceAccu( w, ( cside.plane.normal() != g_vector3_identity )? plane3_flipped( cside.plane ) : Plane3( cplane.plane ), 0 );
#else #else
ChopWindingInPlace( &w, cplane.plane, 0 ); // CLIP_EPSILON ); ChopWindingInPlace( w, cplane.plane, 0 ); // CLIP_EPSILON );
#endif #endif
/* ydnar: fix broken windings that would generate trifans */ /* ydnar: fix broken windings that would generate trifans */
@ -513,7 +502,7 @@ float BrushVolume( brush_t *brush ){
if ( !w ) { if ( !w ) {
return 0; return 0;
} }
corner = w->p[0]; corner = ( *w )[0];
// make tetrahedrons to all other faces // make tetrahedrons to all other faces
@ -524,7 +513,7 @@ float BrushVolume( brush_t *brush ){
if ( !w ) { if ( !w ) {
continue; continue;
} }
volume += -plane3_distance_to_point( mapplanes[brush->sides[i].planenum].plane, corner ) * WindingArea( w ); volume += -plane3_distance_to_point( mapplanes[brush->sides[i].planenum].plane, corner ) * WindingArea( *w );
} }
volume /= 3; volume /= 3;
@ -541,8 +530,6 @@ float BrushVolume( brush_t *brush ){
void WriteBSPBrushMap( const char *name, brush_t *list ){ void WriteBSPBrushMap( const char *name, brush_t *list ){
side_t *s; side_t *s;
int i; int i;
winding_t *w;
/* note it */ /* note it */
Sys_Printf( "Writing %s\n", name ); Sys_Printf( "Writing %s\n", name );
@ -552,18 +539,19 @@ void WriteBSPBrushMap( const char *name, brush_t *list ){
fprintf( f, "{\n\"classname\" \"worldspawn\"\n" ); fprintf( f, "{\n\"classname\" \"worldspawn\"\n" );
for ( ; list ; list = list->next ) for ( ; list; list = list->next )
{ {
fprintf( f, "{\n" ); fprintf( f, "{\n" );
for ( i = 0,s = list->sides ; i < list->numsides ; i++,s++ ) for ( i = 0, s = list->sides; i < list->numsides; i++, s++ )
{ {
// TODO: See if we can use a smaller winding to prevent resolution loss. // TODO: See if we can use a smaller winding to prevent resolution loss.
// Is WriteBSPBrushMap() used only to decompile maps? // Is WriteBSPBrushMap() used only to decompile maps?
w = BaseWindingForPlane( mapplanes[s->planenum].plane ); winding_t *w = BaseWindingForPlane( mapplanes[s->planenum].plane );
const winding_t& wr = *w;
fprintf( f, "( %i %i %i ) ", (int)w->p[0][0], (int)w->p[0][1], (int)w->p[0][2] ); fprintf( f, "( %i %i %i ) ", (int)wr[0][0], (int)wr[0][1], (int)wr[0][2] );
fprintf( f, "( %i %i %i ) ", (int)w->p[1][0], (int)w->p[1][1], (int)w->p[1][2] ); fprintf( f, "( %i %i %i ) ", (int)wr[1][0], (int)wr[1][1], (int)wr[1][2] );
fprintf( f, "( %i %i %i ) ", (int)w->p[2][0], (int)w->p[2][1], (int)w->p[2][2] ); fprintf( f, "( %i %i %i ) ", (int)wr[2][0], (int)wr[2][1], (int)wr[2][2] );
fprintf( f, "notexture 0 0 0 1 1\n" ); fprintf( f, "notexture 0 0 0 1 1\n" );
FreeWinding( w ); FreeWinding( w );
@ -746,19 +734,17 @@ node_t *AllocNode( void ){
================ ================
*/ */
#define EDGE_LENGTH 0.2 #define EDGE_LENGTH 0.2
bool WindingIsTiny( winding_t *w ){ bool WindingIsTiny( const winding_t& w ){
/* /*
if (WindingArea (w) < 1) if (WindingArea (w) < 1)
return true; return true;
return false; return false;
*/ */
int i, j;
int edges = 0; int edges = 0;
for ( i = 0 ; i < w->numpoints ; i++ ) for ( size_t i = w.size() - 1, j = 0; j < w.size(); i = j, ++j )
{ {
j = ( i == w->numpoints - 1 )? 0 : i + 1; if ( vector3_length( w[j] - w[i] ) > EDGE_LENGTH ) {
if ( vector3_length( w->p[j] - w->p[i] ) > EDGE_LENGTH ) {
if ( ++edges == 3 ) { if ( ++edges == 3 ) {
return false; return false;
} }
@ -775,9 +761,9 @@ bool WindingIsTiny( winding_t *w ){
from basewinding for plane from basewinding for plane
================ ================
*/ */
bool WindingIsHuge( winding_t *w ){ bool WindingIsHuge( const winding_t& w ){
for ( int i = 0; i < w->numpoints; i++ ) for ( const Vector3& p : w )
if ( !c_worldMinmax.test( w->p[i] ) ) if ( !c_worldMinmax.test( p ) )
return true; return true;
return false; return false;
} }
@ -791,29 +777,23 @@ bool WindingIsHuge( winding_t *w ){
================== ==================
*/ */
int BrushMostlyOnSide( brush_t *brush, plane_t *plane ){ int BrushMostlyOnSide( brush_t *brush, plane_t *plane ){
int i, j; float max = 0;
winding_t *w; int side = PSIDE_FRONT;
float max; for ( int i = 0 ; i < brush->numsides ; i++ )
int side;
max = 0;
side = PSIDE_FRONT;
for ( i = 0 ; i < brush->numsides ; i++ )
{ {
w = brush->sides[i].winding; winding_t *w = brush->sides[i].winding;
if ( !w ) { if ( w ) {
continue; for ( const Vector3& p : *w )
} {
for ( j = 0 ; j < w->numpoints ; j++ ) const double d = plane3_distance_to_point( plane->plane, p );
{ if ( d > max ) {
const double d = plane3_distance_to_point( plane->plane, w->p[j] ); max = d;
if ( d > max ) { side = PSIDE_FRONT;
max = d; }
side = PSIDE_FRONT; if ( -d > max ) {
} max = -d;
if ( -d > max ) { side = PSIDE_BACK;
max = -d; }
side = PSIDE_BACK;
} }
} }
} }
@ -848,9 +828,9 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back )
if ( !w ) { if ( !w ) {
continue; continue;
} }
for ( j = 0 ; j < w->numpoints ; j++ ) for ( const Vector3& p : *w )
{ {
const float d = plane3_distance_to_point( plane->plane, w->p[j] ); const float d = plane3_distance_to_point( plane->plane, p );
if ( d > 0 ) { if ( d > 0 ) {
value_maximize( d_front, d ); value_maximize( d_front, d );
} }
@ -877,10 +857,10 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back )
for ( i = 0 ; i < brush->numsides && w ; i++ ) for ( i = 0 ; i < brush->numsides && w ; i++ )
{ {
plane2 = &mapplanes[brush->sides[i].planenum ^ 1]; plane2 = &mapplanes[brush->sides[i].planenum ^ 1];
ChopWindingInPlace( &w, plane2->plane, 0 ); // PLANESIDE_EPSILON); ChopWindingInPlace( w, plane2->plane, 0 ); // PLANESIDE_EPSILON);
} }
if ( !w || WindingIsTiny( w ) ) { // the brush isn't really split if ( !w || WindingIsTiny( *w ) ) { // the brush isn't really split
int side; int side;
side = BrushMostlyOnSide( brush, plane ); side = BrushMostlyOnSide( brush, plane );
@ -893,7 +873,7 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back )
return; return;
} }
if ( WindingIsHuge( w ) ) { if ( WindingIsHuge( *w ) ) {
Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: huge winding\n" ); Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: huge winding\n" );
} }
@ -919,8 +899,8 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back )
if ( !w ) { if ( !w ) {
continue; continue;
} }
ClipWindingEpsilonStrict( w, plane->plane, ClipWindingEpsilonStrict( *w, plane->plane,
0 /*PLANESIDE_EPSILON*/, &cw[0], &cw[1] ); /* strict, in parallel case we get the face back because it also is the midwinding */ 0 /*PLANESIDE_EPSILON*/, cw[0], cw[1] ); /* strict, in parallel case we get the face back because it also is the midwinding */
for ( j = 0 ; j < 2 ; j++ ) for ( j = 0 ; j < 2 ; j++ )
{ {
if ( !cw[j] ) { if ( !cw[j] ) {

View File

@ -788,7 +788,7 @@ void PseudoCompileBSP( bool need_tree ){
continue; continue;
} }
/* save this winding as a visible surface */ /* save this winding as a visible surface */
DrawSurfaceForSide( entity, brush, side, side->winding ); DrawSurfaceForSide( entity, brush, side, *side->winding );
} }
} }

View File

@ -54,7 +54,6 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t *
float best = 0; float best = 0;
float thisarea; float thisarea;
bspDrawVert_t *vert[3]; bspDrawVert_t *vert[3];
winding_t *polygon;
const plane_t& buildPlane = mapplanes[buildSide->planenum]; const plane_t& buildPlane = mapplanes[buildSide->planenum];
int matches = 0; int matches = 0;
@ -99,7 +98,7 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t *
continue; continue;
} }
// Okay. Correct surface type, correct shader, correct plane. Let's start with the business... // Okay. Correct surface type, correct shader, correct plane. Let's start with the business...
polygon = CopyWinding( buildSide->winding ); winding_t *polygon = CopyWinding( buildSide->winding );
for ( i = 0; i < 3; ++i ) for ( i = 0; i < 3; ++i )
{ {
// 0: 1, 2 // 0: 1, 2
@ -110,12 +109,12 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t *
// we now need to generate the plane spanned by normal and (v2 - v1). // we now need to generate the plane spanned by normal and (v2 - v1).
Plane3f plane( vector3_cross( v2 - v1, buildPlane.normal() ), 0 ); Plane3f plane( vector3_cross( v2 - v1, buildPlane.normal() ), 0 );
plane.dist() = vector3_dot( v1, plane.normal() ); plane.dist() = vector3_dot( v1, plane.normal() );
ChopWindingInPlace( &polygon, plane, distanceEpsilon ); ChopWindingInPlace( polygon, plane, distanceEpsilon );
if ( !polygon ) { if ( !polygon ) {
goto exwinding; goto exwinding;
} }
} }
thisarea = WindingArea( polygon ); thisarea = WindingArea( *polygon );
if ( thisarea > 0 ) { if ( thisarea > 0 ) {
++matches; ++matches;
} }
@ -465,12 +464,9 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, const Vector3& or
/* recheck and fix winding points, fails occur somehow */ /* recheck and fix winding points, fails occur somehow */
int match = 0; int match = 0;
for ( j = 0; j < buildSide->winding->numpoints; j++ ){ for ( const Vector3& p : ( *buildSide->winding ) ){
if ( fabs( plane3_distance_to_point( buildPlane.plane, buildSide->winding->p[ j ] ) ) >= distanceEpsilon ) { if ( fabs( plane3_distance_to_point( buildPlane.plane, p ) ) < distanceEpsilon ) {
continue; pts[ match ] = p;
}
else{
pts[ match ] = buildSide->winding->p[ j ];
match++; match++;
/* got 3 fine points? */ /* got 3 fine points? */
if( match > 2 ) if( match > 2 )

View File

@ -502,17 +502,17 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
/* dummy check */ /* dummy check */
if ( w->numpoints < 3 ) { if ( w->size() < 3 ) {
FreeWinding( w ); FreeWinding( w );
return; return;
} }
/* offset by entity origin */ /* offset by entity origin */
for ( i = 0; i < w->numpoints; i++ ) for ( Vector3& p : *w )
w->p[ i ] += entityOrigin; p += entityOrigin;
/* make a plane from the winding */ /* make a plane from the winding */
if ( !PlaneFromPoints( plane, w->p[ 0 ], w->p[ 1 ], w->p[ 2 ] ) ) { if ( !PlaneFromPoints( plane, w->data() ) ) {
FreeWinding( w ); FreeWinding( w );
return; return;
} }
@ -527,7 +527,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
for ( i = 0; i < dp->numPlanes; i++ ) for ( i = 0; i < dp->numPlanes; i++ )
{ {
/* chop winding by the plane */ /* chop winding by the plane */
ClipWindingEpsilonStrict( w, dp->planes[ i ], 0.0625f, &front, &back ); /* strict, if identical plane we don't want to keep it */ ClipWindingEpsilonStrict( *w, dp->planes[ i ], 0.0625f, front, back ); /* strict, if identical plane we don't want to keep it */
FreeWinding( w ); FreeWinding( w );
/* lose the front fragment */ /* lose the front fragment */
@ -545,7 +545,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
} }
/* nothing left? */ /* nothing left? */
if ( w == NULL || w->numpoints < 3 ) { if ( w == NULL || w->size() < 3 ) {
return; return;
} }
@ -563,7 +563,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
ds2->fogNum = ds->fogNum; /* why was this -1? */ ds2->fogNum = ds->fogNum; /* why was this -1? */
ds2->lightmapScale = ds->lightmapScale; ds2->lightmapScale = ds->lightmapScale;
ds2->shadeAngleDegrees = ds->shadeAngleDegrees; ds2->shadeAngleDegrees = ds->shadeAngleDegrees;
ds2->numVerts = w->numpoints; ds2->numVerts = w->size();
ds2->verts = safe_calloc( ds2->numVerts * sizeof( *ds2->verts ) ); ds2->verts = safe_calloc( ds2->numVerts * sizeof( *ds2->verts ) );
/* set vertexes */ /* set vertexes */
@ -573,12 +573,12 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
dv = &ds2->verts[ i ]; dv = &ds2->verts[ i ];
/* set alpha */ /* set alpha */
const float d = plane3_distance_to_point( dp->planes[ 0 ], w->p[ i ] ); const float d = plane3_distance_to_point( dp->planes[ 0 ], ( *w )[ i ] );
const float d2 = plane3_distance_to_point( dp->planes[ 1 ], w->p[ i ] ); const float d2 = plane3_distance_to_point( dp->planes[ 1 ], ( *w )[ i ] );
const float alpha = 255.0f * d2 / ( d + d2 ); const float alpha = 255.0f * d2 / ( d + d2 );
/* set misc */ /* set misc */
dv->xyz = w->p[ i ] - entityOrigin; dv->xyz = ( *w )[ i ] - entityOrigin;
dv->normal = plane.normal(); dv->normal = plane.normal();
dv->st[ 0 ] = vector3_dot( dv->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ]; dv->st[ 0 ] = vector3_dot( dv->xyz, dp->texMat[ 0 ].vec3() ) + dp->texMat[ 0 ][ 3 ];
dv->st[ 1 ] = vector3_dot( dv->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ]; dv->st[ 1 ] = vector3_dot( dv->xyz, dp->texMat[ 1 ].vec3() ) + dp->texMat[ 1 ][ 3 ];
@ -669,18 +669,16 @@ static void ProjectDecalOntoPatch( decalProjector_t *dp, mapDrawSurface_t *ds ){
/* generate decal for first triangle */ /* generate decal for first triangle */
w = AllocWinding( 3 ); w = AllocWinding( 3 );
w->numpoints = 3; w->push_back( mesh->verts[ pw[ r + 0 ] ].xyz );
w->p[ 0 ] = mesh->verts[ pw[ r + 0 ] ].xyz; w->push_back( mesh->verts[ pw[ r + 1 ] ].xyz );
w->p[ 1 ] = mesh->verts[ pw[ r + 1 ] ].xyz; w->push_back( mesh->verts[ pw[ r + 2 ] ].xyz );
w->p[ 2 ] = mesh->verts[ pw[ r + 2 ] ].xyz;
ProjectDecalOntoWinding( dp, ds, w ); ProjectDecalOntoWinding( dp, ds, w );
/* generate decal for second triangle */ /* generate decal for second triangle */
w = AllocWinding( 3 ); w = AllocWinding( 3 );
w->numpoints = 3; w->push_back( mesh->verts[ pw[ r + 0 ] ].xyz );
w->p[ 0 ] = mesh->verts[ pw[ r + 0 ] ].xyz; w->push_back( mesh->verts[ pw[ r + 2 ] ].xyz );
w->p[ 1 ] = mesh->verts[ pw[ r + 2 ] ].xyz; w->push_back( mesh->verts[ pw[ r + 3 ] ].xyz );
w->p[ 2 ] = mesh->verts[ pw[ r + 3 ] ].xyz;
ProjectDecalOntoWinding( dp, ds, w ); ProjectDecalOntoWinding( dp, ds, w );
} }
} }
@ -717,10 +715,9 @@ static void ProjectDecalOntoTriangles( decalProjector_t *dp, mapDrawSurface_t *d
{ {
/* generate decal */ /* generate decal */
winding_t *w = AllocWinding( 3 ); winding_t *w = AllocWinding( 3 );
w->numpoints = 3; w->push_back( ds->verts[ ds->indexes[ i ] ].xyz );
w->p[ 0 ] = ds->verts[ ds->indexes[ i ] ].xyz; w->push_back( ds->verts[ ds->indexes[ i + 1 ] ].xyz );
w->p[ 1 ] = ds->verts[ ds->indexes[ i + 1 ] ].xyz; w->push_back( ds->verts[ ds->indexes[ i + 2 ] ].xyz );
w->p[ 2 ] = ds->verts[ ds->indexes[ i + 2 ] ].xyz;
ProjectDecalOntoWinding( dp, ds, w ); ProjectDecalOntoWinding( dp, ds, w );
} }
} }

View File

@ -126,7 +126,7 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum,
//check->checked = true; // won't need to test this plane again //check->checked = true; // won't need to test this plane again
continue; continue;
} }
const EPlaneSide side = WindingOnPlaneSide( check->w, plane.plane ); const EPlaneSide side = WindingOnPlaneSide( *check->w, plane.plane );
if ( side == eSideCross ) { if ( side == eSideCross ) {
splits++; splits++;
} }
@ -142,7 +142,7 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum,
// from 27 // from 27
//Bigger is better //Bigger is better
sizeBias = WindingArea( split->w ); sizeBias = WindingArea( *split->w );
//Base score = 20000 perfectly balanced //Base score = 20000 perfectly balanced
value = 20000 - ( abs( front - back ) ); value = 20000 - ( abs( front - back ) );
@ -276,12 +276,12 @@ void BuildFaceTree_r( node_t *node, face_t *list ){
#endif #endif
/* determine which side the face falls on */ /* determine which side the face falls on */
const EPlaneSide side = WindingOnPlaneSide( split->w, plane.plane ); const EPlaneSide side = WindingOnPlaneSide( *split->w, plane.plane );
/* switch on side */ /* switch on side */
if ( side == eSideCross ) { if ( side == eSideCross ) {
ClipWindingEpsilonStrict( split->w, plane.plane, CLIP_EPSILON * 2, ClipWindingEpsilonStrict( *split->w, plane.plane, CLIP_EPSILON * 2,
&frontWinding, &backWinding ); /* strict; if no winding is left, we have a "virtually identical" plane and don't want to split by it */ frontWinding, backWinding ); /* strict; if no winding is left, we have a "virtually identical" plane and don't want to split by it */
if ( frontWinding ) { if ( frontWinding ) {
newFace = AllocBspFace(); newFace = AllocBspFace();
newFace->w = frontWinding; newFace->w = frontWinding;
@ -370,7 +370,7 @@ tree_t *FaceBSP( face_t *list ) {
int count = 0; int count = 0;
for ( const face_t *face = list; face != NULL; face = face->next ) for ( const face_t *face = list; face != NULL; face = face->next )
{ {
WindingExtendBounds( face->w, tree->minmax ); WindingExtendBounds( *face->w, tree->minmax );
count++; count++;
} }
Sys_FPrintf( SYS_VRB, "%9d faces\n", count ); Sys_FPrintf( SYS_VRB, "%9d faces\n", count );

View File

@ -349,9 +349,8 @@ winding_t *WindingFromDrawSurf( mapDrawSurface_t *ds ){
} }
w = AllocWinding( ds->numVerts ); w = AllocWinding( ds->numVerts );
w->numpoints = ds->numVerts; for ( i = 0; i < ds->numVerts; i++ ) {
for ( i = 0 ; i < ds->numVerts ; i++ ) { w->push_back( ds->verts[i].xyz );
w->p[i] = ds->verts[i].xyz;
} }
return w; return w;
} }
@ -400,7 +399,7 @@ bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
} }
/* general case */ /* general case */
ClipWindingEpsilonStrict( w, plane.plane, ON_EPSILON, &front, &back ); /* strict; if plane is "almost identical" to face, both ways to continue can be wrong, so we better not fog it */ ClipWindingEpsilonStrict( *w, plane.plane, ON_EPSILON, front, back ); /* strict; if plane is "almost identical" to face, both ways to continue can be wrong, so we better not fog it */
FreeWinding( w ); FreeWinding( w );
if ( back == NULL ) { if ( back == NULL ) {
@ -428,7 +427,7 @@ bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
s = ds->sideRef->side; s = ds->sideRef->side;
for ( i = 0; i < numOutside; i++ ) for ( i = 0; i < numOutside; i++ )
{ {
newds = DrawSurfaceForSide( e, ds->mapBrush, s, outside[ i ] ); newds = DrawSurfaceForSide( e, ds->mapBrush, s, *outside[ i ] );
newds->fogNum = ds->fogNum; newds->fogNum = ds->fogNum;
FreeWinding( outside[ i ] ); FreeWinding( outside[ i ] );
} }
@ -438,7 +437,7 @@ bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
the right thing and uses the original surface's brush side */ the right thing and uses the original surface's brush side */
/* build a drawsurf for it */ /* build a drawsurf for it */
newds = DrawSurfaceForSide( e, ds->mapBrush, s, w ); newds = DrawSurfaceForSide( e, ds->mapBrush, s, *w );
if ( newds == NULL ) { if ( newds == NULL ) {
return false; return false;
} }

View File

@ -97,7 +97,7 @@ xmlNodePtr LeakFile( tree_t *tree ){
} }
} }
node = nextnode; node = nextnode;
mid = WindingCenter( nextportal->winding ); mid = WindingCenter( *nextportal->winding );
fprintf( linefile, "%f %f %f\n", mid[0], mid[1], mid[2] ); fprintf( linefile, "%f %f %f\n", mid[0], mid[1], mid[2] );
point = xml_NodeForVec( mid ); point = xml_NodeForVec( mid );
xmlAddChild( xml_node, point ); xmlAddChild( xml_node, point );

View File

@ -637,17 +637,17 @@ void SetEntityOrigins( void ){
#define ONE_OVER_2PI 0.159154942f //% (1.0f / (2.0f * 3.141592657f)) #define ONE_OVER_2PI 0.159154942f //% (1.0f / (2.0f * 3.141592657f))
float PointToPolygonFormFactor( const Vector3& point, const Vector3& normal, const winding_t *w ){ float PointToPolygonFormFactor( const Vector3& point, const Vector3& normal, const winding_t& w ){
int i, j;
Vector3 dirs[ MAX_POINTS_ON_WINDING ]; Vector3 dirs[ MAX_POINTS_ON_WINDING ];
float total; float total;
float angle, facing; float angle, facing;
/* this is expensive */ /* this is expensive */
for ( i = 0; i < w->numpoints; i++ ) size_t i;
for ( i = 0; i < w.size(); i++ )
{ {
dirs[ i ] = w->p[ i ] - point; dirs[ i ] = w[ i ] - point;
VectorFastNormalize( dirs[ i ] ); VectorFastNormalize( dirs[ i ] );
} }
@ -656,10 +656,10 @@ float PointToPolygonFormFactor( const Vector3& point, const Vector3& normal, con
/* calculcate relative area */ /* calculcate relative area */
total = 0.0f; total = 0.0f;
for ( i = 0; i < w->numpoints; i++ ) for ( i = 0; i < w.size(); i++ )
{ {
/* get a triangle */ /* get a triangle */
j = i + 1; const size_t j = i + 1;
/* get the angle */ /* get the angle */
/* roundoff can cause slight creep, which gives an IND from acos, thus clamp */ /* roundoff can cause slight creep, which gives an IND from acos, thus clamp */
@ -811,7 +811,7 @@ int LightContributionToSample( trace_t *trace ){
else else
{ {
/* calculate the contribution */ /* calculate the contribution */
factor = PointToPolygonFormFactor( pushedOrigin, trace->normal, light->w ); factor = PointToPolygonFormFactor( pushedOrigin, trace->normal, *light->w );
if ( factor == 0.0f ) { if ( factor == 0.0f ) {
return 0; return 0;
} }
@ -1258,7 +1258,7 @@ bool LightContributionToPoint( trace_t *trace ){
} }
/* calculate the contribution (ydnar 2002-10-21: [bug 642] bad normal calc) */ /* calculate the contribution (ydnar 2002-10-21: [bug 642] bad normal calc) */
factor = PointToPolygonFormFactor( pushedOrigin, trace->direction, light->w ); factor = PointToPolygonFormFactor( pushedOrigin, trace->direction, *light->w );
if ( factor == 0.0f ) { if ( factor == 0.0f ) {
return false; return false;
} }

View File

@ -389,7 +389,7 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
float dist, area, value; float dist, area, value;
Vector3 normal, color, gradient; Vector3 normal, color, gradient;
light_t *light, *splash; light_t *light, *splash;
winding_t *w, *splash_w; winding_t *w;
/* dummy check */ /* dummy check */
@ -447,11 +447,10 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
/* create a regular winding and an average normal */ /* create a regular winding and an average normal */
w = AllocWinding( rw->numVerts ); w = AllocWinding( rw->numVerts );
w->numpoints = rw->numVerts;
normal.set( 0 ); normal.set( 0 );
for ( i = 0; i < rw->numVerts; i++ ) for ( i = 0; i < rw->numVerts; i++ )
{ {
w->p[ i ] = rw->verts[ i ].xyz; w->push_back( rw->verts[ i ].xyz );
normal += rw->verts[ i ].normal; normal += rw->verts[ i ].normal;
} }
normal /= rw->numVerts; normal /= rw->numVerts;
@ -582,11 +581,9 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
} }
/* create a regular winding */ /* create a regular winding */
splash_w = AllocWinding( rw->numVerts ); splash->w = AllocWinding( rw->numVerts );
splash_w->numpoints = rw->numVerts;
for ( i = 0; i < rw->numVerts; i++ ) for ( i = 0; i < rw->numVerts; i++ )
splash_w->p[ i ] = rw->verts[rw->numVerts - 1 - i].xyz + normal * si->backsplashDistance; splash->w->push_back( rw->verts[rw->numVerts - 1 - i].xyz + normal * si->backsplashDistance );
splash->w = splash_w;
splash->origin = normal * si->backsplashDistance + light->origin; splash->origin = normal * si->backsplashDistance + light->origin;
splash->normal = -normal; splash->normal = -normal;
@ -610,7 +607,7 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
} }
/* set origin */ /* set origin */
light->origin = WindingCenter( w ); light->origin = WindingCenter( *w );
/* nudge it off the plane a bit */ /* nudge it off the plane a bit */
light->normal = normal; light->normal = normal;

View File

@ -3433,7 +3433,7 @@ void SetupEnvelopes( bool forGrid, bool fastFlag ){
for ( radius = 100.0f; radius < MAX_WORLD_COORD * 8.0f; radius += 10.0f ) for ( radius = 100.0f; radius < MAX_WORLD_COORD * 8.0f; radius += 10.0f )
{ {
const Vector3 origin = light->origin + light->normal * radius; const Vector3 origin = light->origin + light->normal * radius;
const float factor = std::abs( PointToPolygonFormFactor( origin, dir, light->w ) ); const float factor = std::abs( PointToPolygonFormFactor( origin, dir, *light->w ) );
if ( ( factor * light->add ) <= light->falloffTolerance ) { if ( ( factor * light->add ) <= light->falloffTolerance ) {
light->envelope = radius; light->envelope = radius;
break; break;

View File

@ -651,8 +651,8 @@ void AddBrushBevels( void ){
if ( !w ) { if ( !w ) {
continue; continue;
} }
for ( k = 0; k < w->numpoints; k++ ) { for ( const Vector3& po : *w ) {
if ( fabs( plane.dist() - w->p[k][axis] ) < .1f ) { if ( fabs( plane.dist() - po[axis] ) < .1f ) {
s->surfaceFlags |= ( s2->surfaceFlags & surfaceFlagsMask ); s->surfaceFlags |= ( s2->surfaceFlags & surfaceFlagsMask );
break; break;
} }
@ -686,9 +686,9 @@ void AddBrushBevels( void ){
if ( !w ) { if ( !w ) {
continue; continue;
} }
for ( j = 0; j < w->numpoints; j++ ) { for ( j = 0; j < w->size(); j++ ) {
k = ( j + 1 ) % w->numpoints; k = ( j + 1 ) % w->size();
vec = w->p[j] - w->p[k]; vec = ( *w )[j] - ( *w )[k];
if ( VectorNormalize( vec ) < 0.5f ) { if ( VectorNormalize( vec ) < 0.5f ) {
continue; continue;
} }
@ -715,7 +715,7 @@ void AddBrushBevels( void ){
if ( VectorNormalize( plane.normal() ) < 0.5f ) { if ( VectorNormalize( plane.normal() ) < 0.5f ) {
continue; continue;
} }
plane.dist() = vector3_dot( w->p[j], plane.normal() ); plane.dist() = vector3_dot( ( *w )[j], plane.normal() );
// if all the points on all the sides are // if all the points on all the sides are
// behind this plane, it is a proper edge bevel // behind this plane, it is a proper edge bevel
@ -734,15 +734,15 @@ void AddBrushBevels( void ){
continue; continue;
} }
minBack = 0.0f; minBack = 0.0f;
for ( l = 0; l < w2->numpoints; l++ ) { for ( l = 0; l < w2->size(); l++ ) {
d = plane3_distance_to_point( plane, w2->p[l] ); d = plane3_distance_to_point( plane, ( *w2 )[l] );
if ( d > 0.1f ) { if ( d > 0.1f ) {
break; // point in front break; // point in front
} }
value_minimize( minBack, d ); value_minimize( minBack, d );
} }
// if some point was at the front // if some point was at the front
if ( l != w2->numpoints ) { if ( l != w2->size() ) {
break; break;
} }
@ -768,7 +768,7 @@ void AddBrushBevels( void ){
buildBrush->numsides++; buildBrush->numsides++;
memset( s2, 0, sizeof( *s2 ) ); memset( s2, 0, sizeof( *s2 ) );
s2->planenum = FindFloatPlane( plane, 1, &w->p[ j ] ); s2->planenum = FindFloatPlane( plane, 1, &( *w )[ j ] );
s2->contentFlags = buildBrush->sides[0].contentFlags; s2->contentFlags = buildBrush->sides[0].contentFlags;
s2->surfaceFlags = ( s->surfaceFlags & surfaceFlagsMask ); /* handle bevel surfaceflags */ s2->surfaceFlags = ( s->surfaceFlags & surfaceFlagsMask ); /* handle bevel surfaceflags */
s2->bevel = true; s2->bevel = true;

View File

@ -156,14 +156,9 @@ void RemovePortalFromNode( portal_t *portal, node_t *l ){
//============================================================================ //============================================================================
void PrintPortal( portal_t *p ){ void PrintPortal( const portal_t *p ){
int i; for ( const Vector3& point : ( *p->winding ) )
winding_t *w; Sys_Printf( "(%5.0f,%5.0f,%5.0f)\n", point[0], point[1], point[2] );
w = p->winding;
for ( i = 0 ; i < w->numpoints ; i++ )
Sys_Printf( "(%5.0f,%5.0f,%5.0f)\n", w->p[i][0]
, w->p[i][1], w->p[i][2] );
} }
/* /*
@ -226,7 +221,7 @@ void MakeHeadnodePortals( tree_t *tree ){
if ( j == i ) { if ( j == i ) {
continue; continue;
} }
ChopWindingInPlace( &portals[i]->winding, bplanes[j].plane, ON_EPSILON ); ChopWindingInPlace( portals[i]->winding, bplanes[j].plane, ON_EPSILON );
} }
} }
} }
@ -254,11 +249,11 @@ winding_t *BaseWindingForNode( node_t *node ){
const plane_t& plane = mapplanes[n->planenum]; const plane_t& plane = mapplanes[n->planenum];
if ( n->children[0] == node ) { // take front if ( n->children[0] == node ) { // take front
ChopWindingInPlace( &w, plane.plane, BASE_WINDING_EPSILON ); ChopWindingInPlace( w, plane.plane, BASE_WINDING_EPSILON );
} }
else else
{ // take back { // take back
ChopWindingInPlace( &w, plane3_flipped( plane.plane ), BASE_WINDING_EPSILON ); ChopWindingInPlace( w, plane3_flipped( plane.plane ), BASE_WINDING_EPSILON );
} }
node = n; node = n;
n = n->parent; n = n->parent;
@ -289,11 +284,11 @@ void MakeNodePortal( node_t *node ){
{ {
if ( p->nodes[0] == node ) { if ( p->nodes[0] == node ) {
side = 0; side = 0;
ChopWindingInPlace( &w, p->plane.plane, CLIP_EPSILON ); ChopWindingInPlace( w, p->plane.plane, CLIP_EPSILON );
} }
else if ( p->nodes[1] == node ) { else if ( p->nodes[1] == node ) {
side = 1; side = 1;
ChopWindingInPlace( &w, plane3_flipped( p->plane.plane ), CLIP_EPSILON ); ChopWindingInPlace( w, plane3_flipped( p->plane.plane ), CLIP_EPSILON );
} }
else{ else{
Error( "CutNodePortals_r: mislinked portal" ); Error( "CutNodePortals_r: mislinked portal" );
@ -315,7 +310,7 @@ void MakeNodePortal( node_t *node ){
} }
#endif #endif
if ( WindingIsTiny( w ) ) { if ( WindingIsTiny( *w ) ) {
c_tinyportals++; c_tinyportals++;
FreeWinding( w ); FreeWinding( w );
return; return;
@ -368,16 +363,16 @@ void SplitNodePortals( node_t *node ){
// //
// cut the portal into two portals, one on each side of the cut plane // cut the portal into two portals, one on each side of the cut plane
// //
ClipWindingEpsilon( p->winding, plane.plane, ClipWindingEpsilon( *p->winding, plane.plane,
SPLIT_WINDING_EPSILON, &frontwinding, &backwinding ); /* not strict, we want to always keep one of them even if coplanar */ SPLIT_WINDING_EPSILON, frontwinding, backwinding ); /* not strict, we want to always keep one of them even if coplanar */
if ( frontwinding && WindingIsTiny( frontwinding ) ) { if ( frontwinding && WindingIsTiny( *frontwinding ) ) {
if ( !f->tinyportals ) { if ( !f->tinyportals ) {
f->referencepoint = frontwinding->p[0]; f->referencepoint = ( *frontwinding )[0];
} }
f->tinyportals++; f->tinyportals++;
if ( !other_node->tinyportals ) { if ( !other_node->tinyportals ) {
other_node->referencepoint = frontwinding->p[0]; other_node->referencepoint = ( *frontwinding )[0];
} }
other_node->tinyportals++; other_node->tinyportals++;
@ -386,13 +381,13 @@ void SplitNodePortals( node_t *node ){
c_tinyportals++; c_tinyportals++;
} }
if ( backwinding && WindingIsTiny( backwinding ) ) { if ( backwinding && WindingIsTiny( *backwinding ) ) {
if ( !b->tinyportals ) { if ( !b->tinyportals ) {
b->referencepoint = backwinding->p[0]; b->referencepoint = ( *backwinding )[0];
} }
b->tinyportals++; b->tinyportals++;
if ( !other_node->tinyportals ) { if ( !other_node->tinyportals ) {
other_node->referencepoint = backwinding->p[0]; other_node->referencepoint = ( *backwinding )[0];
} }
other_node->tinyportals++; other_node->tinyportals++;
@ -462,7 +457,7 @@ void CalcNodeBounds( node_t *node ){
for ( p = node->portals ; p ; p = p->next[s] ) for ( p = node->portals ; p ; p = p->next[s] )
{ {
s = ( p->nodes[1] == node ); s = ( p->nodes[1] == node );
WindingExtendBounds( p->winding, node->minmax ); WindingExtendBounds( *p->winding, node->minmax );
} }
} }
@ -485,7 +480,7 @@ void MakeTreePortals_r( node_t *node ){
if ( !c_worldMinmax.surrounds( node->minmax ) ) { if ( !c_worldMinmax.surrounds( node->minmax ) ) {
if ( node->portals && node->portals->winding ) { if ( node->portals && node->portals->winding ) {
xml_Winding( "WARNING: Node With Unbounded Volume", node->portals->winding->p, node->portals->winding->numpoints, false ); xml_Winding( "WARNING: Node With Unbounded Volume", node->portals->winding->data(), node->portals->winding->size(), false );
} }
} }
if ( node->planenum == PLANENUM_LEAF ) { if ( node->planenum == PLANENUM_LEAF ) {

View File

@ -97,7 +97,7 @@ void CountVisportals_r( node_t *node ){
================= =================
*/ */
void WritePortalFile_r( node_t *node ){ void WritePortalFile_r( node_t *node ){
int i, s, flags; int s, flags;
portal_t *p; portal_t *p;
winding_t *w; winding_t *w;
@ -130,11 +130,11 @@ void WritePortalFile_r( node_t *node ){
// the changeover point between different axis. interpret the // the changeover point between different axis. interpret the
// plane the same way vis will, and flip the side orders if needed // plane the same way vis will, and flip the side orders if needed
// FIXME: is this still relevant? // FIXME: is this still relevant?
if ( vector3_dot( p->plane.normal(), WindingPlane( w ).normal() ) < 0.99 ) { // backwards... if ( vector3_dot( p->plane.normal(), WindingPlane( *w ).normal() ) < 0.99 ) { // backwards...
fprintf( pf, "%i %i %i ", w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster ); fprintf( pf, "%zu %i %i ", w->size(), p->nodes[1]->cluster, p->nodes[0]->cluster );
} }
else{ else{
fprintf( pf, "%i %i %i ", w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster ); fprintf( pf, "%zu %i %i ", w->size(), p->nodes[0]->cluster, p->nodes[1]->cluster );
} }
flags = 0; flags = 0;
@ -152,12 +152,12 @@ void WritePortalFile_r( node_t *node ){
fprintf( pf, "%d ", flags ); fprintf( pf, "%d ", flags );
/* write the winding */ /* write the winding */
for ( i = 0 ; i < w->numpoints ; i++ ) for ( const Vector3 point : *w )
{ {
fprintf( pf, "(" ); fprintf( pf, "(" );
WriteFloat( pf, w->p[i][0] ); WriteFloat( pf, point.x() );
WriteFloat( pf, w->p[i][1] ); WriteFloat( pf, point.y() );
WriteFloat( pf, w->p[i][2] ); WriteFloat( pf, point.z() );
fprintf( pf, ") " ); fprintf( pf, ") " );
} }
fprintf( pf, "\n" ); fprintf( pf, "\n" );
@ -206,7 +206,7 @@ void CountSolidFaces_r( node_t *node ){
================= =================
*/ */
void WriteFaceFile_r( node_t *node ){ void WriteFaceFile_r( node_t *node ){
int i, s; int s;
portal_t *p; portal_t *p;
winding_t *w; winding_t *w;
@ -235,26 +235,26 @@ void WriteFaceFile_r( node_t *node ){
// write out to the file // write out to the file
if ( p->nodes[0] == node ) { if ( p->nodes[0] == node ) {
fprintf( pf, "%i %i ", w->numpoints, p->nodes[0]->cluster ); fprintf( pf, "%zu %i ", w->size(), p->nodes[0]->cluster );
for ( i = 0 ; i < w->numpoints ; i++ ) for ( const Vector3& point : *w )
{ {
fprintf( pf, "(" ); fprintf( pf, "(" );
WriteFloat( pf, w->p[i][0] ); WriteFloat( pf, point.x() );
WriteFloat( pf, w->p[i][1] ); WriteFloat( pf, point.y() );
WriteFloat( pf, w->p[i][2] ); WriteFloat( pf, point.z() );
fprintf( pf, ") " ); fprintf( pf, ") " );
} }
fprintf( pf, "\n" ); fprintf( pf, "\n" );
} }
else else
{ {
fprintf( pf, "%i %i ", w->numpoints, p->nodes[1]->cluster ); fprintf( pf, "%zu %i ", w->size(), p->nodes[1]->cluster );
for ( i = w->numpoints - 1; i >= 0; i-- ) for ( winding_t::const_reverse_iterator point = w->crbegin(); point != w->crend(); ++point )
{ {
fprintf( pf, "(" ); fprintf( pf, "(" );
WriteFloat( pf, w->p[i][0] ); WriteFloat( pf, point->x() );
WriteFloat( pf, w->p[i][1] ); WriteFloat( pf, point->y() );
WriteFloat( pf, w->p[i][2] ); WriteFloat( pf, point->z() );
fprintf( pf, ") " ); fprintf( pf, ") " );
} }
fprintf( pf, "\n" ); fprintf( pf, "\n" );

View File

@ -1559,7 +1559,7 @@ void FreeBrush( brush_t *brushes );
void FreeBrushList( brush_t *brushes ); void FreeBrushList( brush_t *brushes );
brush_t *CopyBrush( const brush_t *brush ); brush_t *CopyBrush( const brush_t *brush );
bool BoundBrush( brush_t *brush ); bool BoundBrush( brush_t *brush );
void SnapWeldVector( const Vector3& a, const Vector3& b, Vector3& out ); Vector3 SnapWeldVector( const Vector3& a, const Vector3& b );
bool CreateBrushWindings( brush_t *brush ); bool CreateBrushWindings( brush_t *brush );
brush_t *BrushFromBounds( const Vector3& mins, const Vector3& maxs ); brush_t *BrushFromBounds( const Vector3& mins, const Vector3& maxs );
float BrushVolume( brush_t *brush ); float BrushVolume( brush_t *brush );
@ -1568,7 +1568,7 @@ void WriteBSPBrushMap( const char *name, brush_t *list );
void FilterDetailBrushesIntoTree( entity_t *e, tree_t *tree ); void FilterDetailBrushesIntoTree( entity_t *e, tree_t *tree );
void FilterStructuralBrushesIntoTree( entity_t *e, tree_t *tree ); void FilterStructuralBrushesIntoTree( entity_t *e, tree_t *tree );
bool WindingIsTiny( winding_t *w ); bool WindingIsTiny( const winding_t& w );
void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back ); void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back );
@ -1703,7 +1703,7 @@ mapDrawSurface_t *MakeCelSurface( mapDrawSurface_t *src, shaderInfo_t
bool IsTriangleDegenerate( bspDrawVert_t *points, int a, int b, int c ); bool IsTriangleDegenerate( bspDrawVert_t *points, int a, int b, int c );
void ClearSurface( mapDrawSurface_t *ds ); void ClearSurface( mapDrawSurface_t *ds );
void AddEntitySurfaceModels( entity_t *e ); void AddEntitySurfaceModels( entity_t *e );
mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, winding_t *w ); mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, const winding_t& w );
mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh ); mapDrawSurface_t *DrawSurfaceForMesh( entity_t *e, parseMesh_t *p, mesh_t *mesh );
mapDrawSurface_t *DrawSurfaceForFlare( int entNum, const Vector3& origin, const Vector3& normal, const Vector3& color, const char *flareShader, int lightStyle ); mapDrawSurface_t *DrawSurfaceForFlare( int entNum, const Vector3& origin, const Vector3& normal, const Vector3& color, const char *flareShader, int lightStyle );
mapDrawSurface_t *DrawSurfaceForShader( const char *shader ); mapDrawSurface_t *DrawSurfaceForShader( const char *shader );
@ -1779,7 +1779,7 @@ void PassagePortalFlow( int portalnum );
/* light.c */ /* light.c */
float PointToPolygonFormFactor( const Vector3& point, const Vector3& normal, const winding_t *w ); float PointToPolygonFormFactor( const Vector3& point, const Vector3& normal, const winding_t& w );
int LightContributionToSample( trace_t *trace ); int LightContributionToSample( trace_t *trace );
void LightingAtSample( trace_t * trace, byte styles[ MAX_LIGHTMAPS ], Vector3 (&colors)[ MAX_LIGHTMAPS ] ); void LightingAtSample( trace_t * trace, byte styles[ MAX_LIGHTMAPS ], Vector3 (&colors)[ MAX_LIGHTMAPS ] );
bool LightContributionToPoint( trace_t *trace ); bool LightContributionToPoint( trace_t *trace );

View File

@ -766,8 +766,7 @@ shaderInfo_t *GetIndexedShader( const shaderInfo_t *parent, const indexMap_t *im
const double SNAP_FLOAT_TO_INT = 8.0; const double SNAP_FLOAT_TO_INT = 8.0;
const double SNAP_INT_TO_FLOAT = ( 1.0 / SNAP_FLOAT_TO_INT ); const double SNAP_INT_TO_FLOAT = ( 1.0 / SNAP_FLOAT_TO_INT );
mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, winding_t *w ){ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, const winding_t& w ){
int i, j, k;
mapDrawSurface_t *ds; mapDrawSurface_t *ds;
shaderInfo_t *si, *parent; shaderInfo_t *si, *parent;
bspDrawVert_t *dv; bspDrawVert_t *dv;
@ -785,8 +784,8 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, windin
} }
/* range check */ /* range check */
if ( w->numpoints > MAX_POINTS_ON_WINDING ) { if ( w.size() > MAX_POINTS_ON_WINDING ) {
Error( "DrawSurfaceForSide: w->numpoints = %d (> %d)", w->numpoints, MAX_POINTS_ON_WINDING ); Error( "DrawSurfaceForSide: w->numpoints = %zu (> %d)", w.size(), MAX_POINTS_ON_WINDING );
} }
/* get shader */ /* get shader */
@ -798,16 +797,16 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, windin
indexed = true; indexed = true;
/* get shader indexes for each point */ /* get shader indexes for each point */
for ( i = 0; i < w->numpoints; i++ ) for ( size_t i = 0; i < w.size(); i++ )
{ {
shaderIndexes[ i ] = GetShaderIndexForPoint( b->im, b->eMinmax, w->p[ i ] ); shaderIndexes[ i ] = GetShaderIndexForPoint( b->im, b->eMinmax, w[ i ] );
offsets[ i ] = b->im->offsets[ shaderIndexes[ i ] ]; offsets[ i ] = b->im->offsets[ shaderIndexes[ i ] ];
//% Sys_Printf( "%f ", offsets[ i ] ); //% Sys_Printf( "%f ", offsets[ i ] );
} }
/* get matching shader and set alpha */ /* get matching shader and set alpha */
parent = si; parent = si;
si = GetIndexedShader( parent, b->im, w->numpoints, shaderIndexes ); si = GetIndexedShader( parent, b->im, w.size(), shaderIndexes );
} }
else{ else{
indexed = false; indexed = false;
@ -836,26 +835,26 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, windin
ds->fogNum = -1; ds->fogNum = -1;
ds->sampleSize = b->lightmapSampleSize; ds->sampleSize = b->lightmapSampleSize;
ds->lightmapScale = b->lightmapScale; ds->lightmapScale = b->lightmapScale;
ds->numVerts = w->numpoints; ds->numVerts = w.size();
ds->verts = safe_calloc( ds->numVerts * sizeof( *ds->verts ) ); ds->verts = safe_calloc( ds->numVerts * sizeof( *ds->verts ) );
/* compute s/t coordinates from brush primitive texture matrix (compute axis base) */ /* compute s/t coordinates from brush primitive texture matrix (compute axis base) */
ComputeAxisBase( mapplanes[ s->planenum ].normal(), texX, texY ); ComputeAxisBase( mapplanes[ s->planenum ].normal(), texX, texY );
/* create the vertexes */ /* create the vertexes */
for ( j = 0; j < w->numpoints; j++ ) for ( size_t j = 0; j < w.size(); j++ )
{ {
/* get the drawvert */ /* get the drawvert */
dv = ds->verts + j; dv = ds->verts + j;
/* copy xyz and do potential z offset */ /* copy xyz and do potential z offset */
dv->xyz = w->p[ j ]; dv->xyz = w[ j ];
if ( indexed ) { if ( indexed ) {
dv->xyz[ 2 ] += offsets[ j ]; dv->xyz[ 2 ] += offsets[ j ];
} }
/* round the xyz to a given precision and translate by origin */ /* round the xyz to a given precision and translate by origin */
for ( i = 0 ; i < 3 ; i++ ) for ( size_t i = 0 ; i < 3 ; i++ )
dv->xyz[ i ] = SNAP_INT_TO_FLOAT * floor( dv->xyz[ i ] * SNAP_FLOAT_TO_INT + 0.5 ); dv->xyz[ i ] = SNAP_INT_TO_FLOAT * floor( dv->xyz[ i ] * SNAP_FLOAT_TO_INT + 0.5 );
vTranslated = dv->xyz + e->originbrush_origin; vTranslated = dv->xyz + e->originbrush_origin;
@ -892,7 +891,7 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, windin
dv->normal = mapplanes[ s->planenum ].normal(); dv->normal = mapplanes[ s->planenum ].normal();
/* ydnar: set color */ /* ydnar: set color */
for ( k = 0; k < MAX_LIGHTMAPS; k++ ) for ( int k = 0; k < MAX_LIGHTMAPS; k++ )
{ {
dv->color[ k ].set( 255 ); dv->color[ k ].set( 255 );
@ -1203,7 +1202,7 @@ static void AddSurfaceFlare( mapDrawSurface_t *ds, const Vector3& entityOrigin )
subdivides a face surface until it is smaller than the specified size (subdivisions) subdivides a face surface until it is smaller than the specified size (subdivisions)
*/ */
static void SubdivideFace_r( entity_t *e, brush_t *brush, side_t *side, winding_t *w, int fogNum, float subdivisions ){ static void SubdivideFace_r( entity_t *e, brush_t *brush, side_t *side, const winding_t *w, int fogNum, float subdivisions ){
int axis; int axis;
MinMax bounds; MinMax bounds;
const float epsilon = 0.1; const float epsilon = 0.1;
@ -1216,12 +1215,12 @@ static void SubdivideFace_r( entity_t *e, brush_t *brush, side_t *side, winding_
if ( w == NULL ) { if ( w == NULL ) {
return; return;
} }
if ( w->numpoints < 3 ) { if ( w->size() < 3 ) {
Error( "SubdivideFace_r: Bad w->numpoints (%d < 3)", w->numpoints ); Error( "SubdivideFace_r: Bad w->numpoints (%zu < 3)", w->size() );
} }
/* determine surface bounds */ /* determine surface bounds */
WindingExtendBounds( w, bounds ); WindingExtendBounds( *w, bounds );
/* split the face */ /* split the face */
for ( axis = 0; axis < 3; axis++ ) for ( axis = 0; axis < 3; axis++ )
@ -1240,7 +1239,7 @@ static void SubdivideFace_r( entity_t *e, brush_t *brush, side_t *side, winding_
/* subdivide if necessary */ /* subdivide if necessary */
if ( ( subCeil - subFloor ) > subdivisions ) { if ( ( subCeil - subFloor ) > subdivisions ) {
/* clip the winding */ /* clip the winding */
ClipWindingEpsilon( w, plane, epsilon, &frontWinding, &backWinding ); /* not strict; we assume we always keep a winding */ ClipWindingEpsilon( *w, plane, epsilon, frontWinding, backWinding ); /* not strict; we assume we always keep a winding */
/* the clip may not produce two polygons if it was epsilon close */ /* the clip may not produce two polygons if it was epsilon close */
if ( frontWinding == NULL ) { if ( frontWinding == NULL ) {
@ -1259,7 +1258,7 @@ static void SubdivideFace_r( entity_t *e, brush_t *brush, side_t *side, winding_
} }
/* create a face surface */ /* create a face surface */
ds = DrawSurfaceForSide( e, brush, side, w ); ds = DrawSurfaceForSide( e, brush, side, *w );
/* set correct fog num */ /* set correct fog num */
ds->fogNum = fogNum; ds->fogNum = fogNum;
@ -1384,8 +1383,8 @@ void ClipSideIntoTree_r( winding_t *w, side_t *side, node_t *node ){
} }
const Plane3f& plane = mapplanes[ node->planenum ].plane; const Plane3f& plane = mapplanes[ node->planenum ].plane;
ClipWindingEpsilonStrict( w, plane, ClipWindingEpsilonStrict( *w, plane,
ON_EPSILON, &front, &back ); /* strict, we handle the "winding disappeared" case */ ON_EPSILON, front, back ); /* strict, we handle the "winding disappeared" case */
if ( !front && !back ) { if ( !front && !back ) {
/* in doubt, register it in both nodes */ /* in doubt, register it in both nodes */
front = CopyWinding( w ); front = CopyWinding( w );
@ -1401,7 +1400,7 @@ void ClipSideIntoTree_r( winding_t *w, side_t *side, node_t *node ){
// if opaque leaf, don't add // if opaque leaf, don't add
if ( !node->opaque ) { if ( !node->opaque ) {
AddWindingToConvexHull( w, &side->visibleHull, mapplanes[ side->planenum ].normal() ); AddWindingToConvexHull( *w, side->visibleHull, mapplanes[ side->planenum ].normal() );
} }
FreeWinding( w ); FreeWinding( w );
@ -1444,7 +1443,7 @@ bool SideInBrush( side_t *side, brush_t *b ){
/* check if side's winding is on or behind the plane */ /* check if side's winding is on or behind the plane */
const Plane3f& plane = mapplanes[ b->sides[ i ].planenum ].plane; const Plane3f& plane = mapplanes[ b->sides[ i ].planenum ].plane;
const EPlaneSide s = WindingOnPlaneSide( side->winding, plane ); const EPlaneSide s = WindingOnPlaneSide( *side->winding, plane );
if ( s == eSideFront || s == eSideCross ) { if ( s == eSideFront || s == eSideCross ) {
return false; return false;
} }
@ -1526,7 +1525,7 @@ void CullSides( entity_t *e ){
if ( w1 == NULL ) { if ( w1 == NULL ) {
continue; continue;
} }
numPoints = w1->numpoints; numPoints = w1->size();
if ( side1->shaderInfo == NULL ) { if ( side1->shaderInfo == NULL ) {
continue; continue;
} }
@ -1543,7 +1542,7 @@ void CullSides( entity_t *e ){
if ( side2->shaderInfo == NULL ) { if ( side2->shaderInfo == NULL ) {
continue; continue;
} }
if ( w1->numpoints != w2->numpoints ) { if ( w1->size() != w2->size() ) {
continue; continue;
} }
if ( side1->culled && side2->culled ) { if ( side1->culled && side2->culled ) {
@ -1569,7 +1568,7 @@ void CullSides( entity_t *e ){
first = -1; first = -1;
for ( k = 0; k < numPoints; k++ ) for ( k = 0; k < numPoints; k++ )
{ {
if ( VectorCompare( w1->p[ 0 ], w2->p[ k ] ) ) { if ( VectorCompare( ( *w1 )[ 0 ], ( *w2 )[ k ] ) ) {
first = k; first = k;
break; break;
} }
@ -1587,7 +1586,7 @@ void CullSides( entity_t *e ){
else{ else{
second = 0; second = 0;
} }
if ( vector3_equal_epsilon( w1->p[ 1 ], w2->p[ second ], CULL_EPSILON ) ) { if ( vector3_equal_epsilon( ( *w1 )[ 1 ], ( *w2 )[ second ], CULL_EPSILON ) ) {
dir = 1; dir = 1;
} }
else else
@ -1598,7 +1597,7 @@ void CullSides( entity_t *e ){
else{ else{
second = numPoints - 1; second = numPoints - 1;
} }
if ( vector3_equal_epsilon( w1->p[ 1 ], w2->p[ second ], CULL_EPSILON ) ) { if ( vector3_equal_epsilon( ( *w1 )[ 1 ], ( *w2 )[ second ], CULL_EPSILON ) ) {
dir = -1; dir = -1;
} }
} }
@ -1610,7 +1609,7 @@ void CullSides( entity_t *e ){
l = first; l = first;
for ( k = 0; k < numPoints; k++ ) for ( k = 0; k < numPoints; k++ )
{ {
if ( !vector3_equal_epsilon( w1->p[ k ], w2->p[ l ], CULL_EPSILON ) ) { if ( !vector3_equal_epsilon( ( *w1 )[ k ], ( *w2 )[ l ], CULL_EPSILON ) ) {
k = 100000; k = 100000;
} }
@ -1721,7 +1720,7 @@ void ClipSidesIntoTree( entity_t *e, tree_t *tree ){
} }
/* save this winding as a visible surface */ /* save this winding as a visible surface */
DrawSurfaceForSide( e, b, side, w ); DrawSurfaceForSide( e, b, side, *w );
/* make a back side for fog */ /* make a back side for fog */
if ( !( si->compileFlags & C_FOG ) ) { if ( !( si->compileFlags & C_FOG ) ) {
@ -1729,14 +1728,14 @@ void ClipSidesIntoTree( entity_t *e, tree_t *tree ){
} }
/* duplicate the up-facing side */ /* duplicate the up-facing side */
w = ReverseWinding( w ); w = ReverseWinding( *w );
newSide = safe_malloc( sizeof( *side ) ); newSide = safe_malloc( sizeof( *side ) );
*newSide = *side; *newSide = *side;
newSide->visibleHull = w; newSide->visibleHull = w;
newSide->planenum ^= 1; newSide->planenum ^= 1;
/* save this winding as a visible surface */ /* save this winding as a visible surface */
DrawSurfaceForSide( e, b, newSide, w ); DrawSurfaceForSide( e, b, newSide, *w );
} }
} }
} }
@ -1912,7 +1911,7 @@ int FilterPointConvexHullIntoTree_r( Vector3 *points[], const int npoints, mapDr
*/ */
int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){
int i, refs = 0; int refs = 0;
winding_t *fat, *front, *back; winding_t *fat, *front, *back;
shaderInfo_t *si; shaderInfo_t *si;
@ -1930,17 +1929,17 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){
/* 'fatten' the winding by the shader mins/maxs (parsed from vertexDeform move) */ /* 'fatten' the winding by the shader mins/maxs (parsed from vertexDeform move) */
/* note this winding is completely invalid (concave, nonplanar, etc) */ /* note this winding is completely invalid (concave, nonplanar, etc) */
fat = AllocWinding( w->numpoints * 3 + 3 ); fat = AllocWinding( w->size() * 3 + 3 );
fat->numpoints = w->numpoints * 3 + 3; fat->resize( w->size() * 3 + 3 );
for ( i = 0; i < w->numpoints; i++ ) for ( size_t i = 0; i < w->size(); i++ )
{ {
fat->p[ i ] = w->p[ i ]; ( *fat )[ i ] = ( *w )[ i ];
fat->p[ i + ( w->numpoints + 1 ) ] = w->p[ i ] + si->minmax.mins; ( *fat )[ i + ( w->size() + 1 ) ] = ( *w )[ i ] + si->minmax.mins;
fat->p[ i + ( w->numpoints + 1 ) * 2 ] = w->p[ i ] + si->minmax.maxs; ( *fat )[ i + ( w->size() + 1 ) * 2 ] = ( *w )[ i ] + si->minmax.maxs;
} }
fat->p[ i ] = w->p[ 0 ]; ( *fat )[ w->size() ] = ( *w )[ 0 ];
fat->p[ i + w->numpoints ] = w->p[ 0 ] + si->minmax.mins; ( *fat )[ w->size() * 2 ] = ( *w )[ 0 ] + si->minmax.mins;
fat->p[ i + w->numpoints * 2 ] = w->p[ 0 ] + si->minmax.maxs; ( *fat )[ w->size() * 3 ] = ( *w )[ 0 ] + si->minmax.maxs;
/* /*
* note: this winding is STILL not suitable for ClipWindingEpsilon, and * note: this winding is STILL not suitable for ClipWindingEpsilon, and
@ -1990,7 +1989,7 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){
} }
/* clip the winding by this plane */ /* clip the winding by this plane */
ClipWindingEpsilonStrict( w, plane1, ON_EPSILON, &front, &back ); /* strict; we handle the "winding disappeared" case */ ClipWindingEpsilonStrict( *w, plane1, ON_EPSILON, front, back ); /* strict; we handle the "winding disappeared" case */
/* filter by this plane */ /* filter by this plane */
refs = 0; refs = 0;
@ -2092,10 +2091,9 @@ static int FilterTrianglesIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
/* make a triangle winding and filter it into the tree */ /* make a triangle winding and filter it into the tree */
w = AllocWinding( 3 ); w = AllocWinding( 3 );
w->numpoints = 3; w->push_back( ds->verts[ ds->indexes[ i ] ].xyz );
w->p[ 0 ] = ds->verts[ ds->indexes[ i ] ].xyz; w->push_back( ds->verts[ ds->indexes[ i + 1 ] ].xyz );
w->p[ 1 ] = ds->verts[ ds->indexes[ i + 1 ] ].xyz; w->push_back( ds->verts[ ds->indexes[ i + 2 ] ].xyz );
w->p[ 2 ] = ds->verts[ ds->indexes[ i + 2 ] ].xyz;
refs += FilterWindingIntoTree_r( w, ds, tree->headnode ); refs += FilterWindingIntoTree_r( w, ds, tree->headnode );
} }
@ -2138,10 +2136,9 @@ static int FilterFoliageIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
/* make a triangle winding and filter it into the tree */ /* make a triangle winding and filter it into the tree */
w = AllocWinding( 3 ); w = AllocWinding( 3 );
w->numpoints = 3; w->push_back( instance->xyz + ds->verts[ ds->indexes[ i ] ].xyz );
w->p[ 0 ] = instance->xyz + ds->verts[ ds->indexes[ i ] ].xyz; w->push_back( instance->xyz + ds->verts[ ds->indexes[ i + 1 ] ].xyz );
w->p[ 1 ] = instance->xyz + ds->verts[ ds->indexes[ i + 1 ] ].xyz; w->push_back( instance->xyz + ds->verts[ ds->indexes[ i + 2 ] ].xyz );
w->p[ 2 ] = instance->xyz + ds->verts[ ds->indexes[ i + 2 ] ].xyz;
refs += FilterWindingIntoTree_r( w, ds, tree->headnode ); refs += FilterWindingIntoTree_r( w, ds, tree->headnode );
} }
@ -2779,8 +2776,8 @@ static void MakeDebugPortalSurfs_r( node_t *node, shaderInfo_t *si ){
} }
/* check max points */ /* check max points */
if ( w->numpoints > 64 ) { if ( w->size() > 64 ) {
Error( "MakePortalSurfs_r: w->numpoints = %d", w->numpoints ); Error( "MakePortalSurfs_r: w->numpoints = %zu", w->size() );
} }
/* allocate a drawsurface */ /* allocate a drawsurface */
@ -2791,7 +2788,7 @@ static void MakeDebugPortalSurfs_r( node_t *node, shaderInfo_t *si ){
ds->planeNum = FindFloatPlane( p->plane.plane, 0, NULL ); ds->planeNum = FindFloatPlane( p->plane.plane, 0, NULL );
ds->lightmapVecs[ 2 ] = p->plane.normal(); ds->lightmapVecs[ 2 ] = p->plane.normal();
ds->fogNum = -1; ds->fogNum = -1;
ds->numVerts = w->numpoints; ds->numVerts = w->size();
ds->verts = safe_calloc( ds->numVerts * sizeof( *ds->verts ) ); ds->verts = safe_calloc( ds->numVerts * sizeof( *ds->verts ) );
/* walk the winding */ /* walk the winding */
@ -2801,7 +2798,7 @@ static void MakeDebugPortalSurfs_r( node_t *node, shaderInfo_t *si ){
dv = ds->verts + i; dv = ds->verts + i;
/* set it */ /* set it */
dv->xyz = w->p[ i ]; dv->xyz = ( *w )[ i ];
dv->normal = p->plane.normal(); dv->normal = p->plane.normal();
dv->st = { 0, 0 }; dv->st = { 0, 0 };
for ( k = 0; k < MAX_LIGHTMAPS; k++ ) for ( k = 0; k < MAX_LIGHTMAPS; k++ )

View File

@ -513,7 +513,7 @@ bool FixBrokenSurface( mapDrawSurface_t *ds ){
/* create an average drawvert */ /* create an average drawvert */
/* ydnar 2002-01-26: added nearest-integer welding preference */ /* ydnar 2002-01-26: added nearest-integer welding preference */
SnapWeldVector( dv1->xyz, dv2->xyz, avg.xyz ); avg.xyz = SnapWeldVector( dv1->xyz, dv2->xyz );
avg.normal = VectorNormalized( dv1->normal + dv2->normal ); avg.normal = VectorNormalized( dv1->normal + dv2->normal );
avg.st = vector2_mid( dv1->st, dv2->st ); avg.st = vector2_mid( dv1->st, dv2->st );