using winding_t = std::vector<Vector3>
This commit is contained in:
parent
dbfb22e273
commit
c3041cc2f8
|
|
@ -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 ) );
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -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] ) {
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 )
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 ) {
|
||||||
|
|
|
||||||
|
|
@ -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" );
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
|
|
|
||||||
|
|
@ -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++ )
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user