more c++ in q3map2
This commit is contained in:
parent
99f4a4a767
commit
f492ab27eb
|
|
@ -40,16 +40,7 @@ void pw( const winding_t& w ){
|
|||
AllocWinding
|
||||
=============
|
||||
*/
|
||||
winding_t *AllocWinding( int points ){
|
||||
if ( points >= MAX_POINTS_ON_WINDING ) {
|
||||
Error( "AllocWinding failed: MAX_POINTS_ON_WINDING exceeded" );
|
||||
}
|
||||
winding_t *w = new winding_t;
|
||||
w->reserve( points );
|
||||
return w;
|
||||
}
|
||||
|
||||
winding_t AllocWinding_( int points ){
|
||||
winding_t AllocWinding( int points ){
|
||||
if ( points >= MAX_POINTS_ON_WINDING ) {
|
||||
Error( "AllocWinding failed: MAX_POINTS_ON_WINDING exceeded" );
|
||||
}
|
||||
|
|
@ -58,18 +49,6 @@ winding_t AllocWinding_( int points ){
|
|||
return w;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
FreeWinding
|
||||
=============
|
||||
*/
|
||||
void FreeWinding( winding_t *w ){
|
||||
if ( !w ) {
|
||||
Error( "FreeWinding: winding is NULL" );
|
||||
}
|
||||
delete w;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
RemoveColinearPoints
|
||||
|
|
@ -255,7 +234,7 @@ winding_accu_t BaseWindingForPlaneAccu( const Plane3& plane ){
|
|||
error, and can lead to all sorts of disappearing triangle problems.
|
||||
=================
|
||||
*/
|
||||
winding_t *BaseWindingForPlane( const Plane3f& plane ){
|
||||
winding_t BaseWindingForPlane( const Plane3f& plane ){
|
||||
int i, x;
|
||||
float max, v;
|
||||
Vector3 org, vright, vup;
|
||||
|
|
@ -302,7 +281,7 @@ winding_t *BaseWindingForPlane( const Plane3f& plane ){
|
|||
vright *= MAX_WORLD_COORD * 2;
|
||||
|
||||
// project a really big axis aligned box onto the plane
|
||||
return new winding_t{
|
||||
return winding_t{
|
||||
org - vright + vup,
|
||||
org + vright + vup,
|
||||
org + vright - vup,
|
||||
|
|
@ -310,25 +289,13 @@ winding_t *BaseWindingForPlane( const Plane3f& plane ){
|
|||
};
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CopyWinding
|
||||
==================
|
||||
*/
|
||||
winding_t *CopyWinding( const winding_t *w ){
|
||||
if ( !w ) {
|
||||
Error( "CopyWinding: winding is NULL" );
|
||||
}
|
||||
return new winding_t( *w );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CopyWindingAccuToRegular
|
||||
==================
|
||||
*/
|
||||
winding_t *CopyWindingAccuToRegular( const winding_accu_t& w ){
|
||||
return new winding_t( w.begin(), w.end() );
|
||||
winding_t CopyWindingAccuToRegular( const winding_accu_t& w ){
|
||||
return winding_t( w.begin(), w.end() );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -336,8 +303,8 @@ winding_t *CopyWindingAccuToRegular( const winding_accu_t& w ){
|
|||
ReverseWinding
|
||||
==================
|
||||
*/
|
||||
winding_t *ReverseWinding( const winding_t& w ){
|
||||
return new winding_t( w.crbegin(), w.crend() );
|
||||
winding_t ReverseWinding( const winding_t& w ){
|
||||
return winding_t( w.crbegin(), w.crend() );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -346,8 +313,7 @@ winding_t *ReverseWinding( const winding_t& w ){
|
|||
ClipWindingEpsilon
|
||||
=============
|
||||
*/
|
||||
void ClipWindingEpsilonStrict( const winding_t& in, const Plane3f& plane,
|
||||
float epsilon, winding_t *&front, winding_t *&back ){
|
||||
std::pair<winding_t, winding_t> ClipWindingEpsilonStrict( const winding_t& in, const Plane3f& plane, float epsilon ){
|
||||
float dists[MAX_POINTS_ON_WINDING + 4];
|
||||
EPlaneSide sides[MAX_POINTS_ON_WINDING + 4];
|
||||
int counts[3] = { 0 };
|
||||
|
|
@ -373,41 +339,37 @@ void ClipWindingEpsilonStrict( const winding_t& in, const Plane3f& plane,
|
|||
sides[i] = sides[0];
|
||||
dists[i] = dists[0];
|
||||
|
||||
front = back = NULL;
|
||||
|
||||
if ( !counts[eSideFront] && !counts[eSideBack] ) {
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
if ( !counts[eSideFront] ) {
|
||||
back = CopyWinding( &in );
|
||||
return;
|
||||
return { {}, in };
|
||||
}
|
||||
if ( !counts[eSideBack] ) {
|
||||
front = CopyWinding( &in );
|
||||
return;
|
||||
return { in, {} };
|
||||
}
|
||||
|
||||
const size_t maxpts = in.size() + 4; // cant use counts[0]+2 because
|
||||
// of fp grouping errors
|
||||
|
||||
front = AllocWinding( maxpts );
|
||||
back = AllocWinding( maxpts );
|
||||
winding_t front = AllocWinding( maxpts );
|
||||
winding_t back = AllocWinding( maxpts );
|
||||
|
||||
for ( i = 0; i < in.size(); i++ )
|
||||
{
|
||||
const Vector3& p1 = in[i];
|
||||
|
||||
if ( sides[i] == eSideOn ) {
|
||||
front->push_back( p1 );
|
||||
back->push_back( p1 );
|
||||
front.push_back( p1 );
|
||||
back.push_back( p1 );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( sides[i] == eSideFront ) {
|
||||
front->push_back( p1 );
|
||||
front.push_back( p1 );
|
||||
}
|
||||
if ( sides[i] == eSideBack ) {
|
||||
back->push_back( p1 );
|
||||
back.push_back( p1 );
|
||||
}
|
||||
|
||||
if ( sides[i + 1] == eSideOn || sides[i + 1] == sides[i] ) {
|
||||
|
|
@ -431,22 +393,24 @@ void ClipWindingEpsilonStrict( const winding_t& in, const Plane3f& plane,
|
|||
}
|
||||
}
|
||||
|
||||
front->push_back( mid );
|
||||
back->push_back( mid );
|
||||
front.push_back( mid );
|
||||
back.push_back( mid );
|
||||
}
|
||||
|
||||
if ( front->size() > MAX_POINTS_ON_WINDING || back->size() > MAX_POINTS_ON_WINDING ) {
|
||||
if ( front.size() > MAX_POINTS_ON_WINDING || back.size() > MAX_POINTS_ON_WINDING ) {
|
||||
Error( "ClipWinding: MAX_POINTS_ON_WINDING" );
|
||||
}
|
||||
|
||||
return { front, back };
|
||||
}
|
||||
|
||||
void ClipWindingEpsilon( const winding_t& in, const Plane3f& plane,
|
||||
float epsilon, winding_t *&front, winding_t *&back ){
|
||||
ClipWindingEpsilonStrict( in, plane, epsilon, front, back );
|
||||
std::pair<winding_t, winding_t> ClipWindingEpsilon( const winding_t& in, const Plane3f& plane, float epsilon ){
|
||||
auto [front, back] = ClipWindingEpsilonStrict( in, plane, epsilon );
|
||||
/* apparently most code expects that in the winding-on-plane case, the back winding is the original winding */
|
||||
if ( !front && !back ) {
|
||||
back = CopyWinding( &in );
|
||||
if ( front.empty() && back.empty() ) {
|
||||
back = in;
|
||||
}
|
||||
return { front, back };
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -587,8 +551,8 @@ void ChopWindingInPlaceAccu( winding_accu_t& inout, const Plane3& plane, float c
|
|||
ChopWindingInPlace
|
||||
=============
|
||||
*/
|
||||
void ChopWindingInPlace( winding_t *&inout, const Plane3f& plane, float epsilon ){
|
||||
winding_t& in = *inout;
|
||||
void ChopWindingInPlace( winding_t& inout, const Plane3f& plane, float epsilon ){
|
||||
const winding_t& in = inout;
|
||||
float dists[MAX_POINTS_ON_WINDING + 4];
|
||||
EPlaneSide sides[MAX_POINTS_ON_WINDING + 4];
|
||||
int counts[3] = { 0 };
|
||||
|
|
@ -614,8 +578,7 @@ void ChopWindingInPlace( winding_t *&inout, const Plane3f& plane, float epsilon
|
|||
dists[i] = dists[0];
|
||||
|
||||
if ( !counts[eSideFront] ) {
|
||||
FreeWinding( inout );
|
||||
inout = NULL;
|
||||
inout.clear();
|
||||
return;
|
||||
}
|
||||
if ( !counts[eSideBack] ) {
|
||||
|
|
@ -668,27 +631,7 @@ void ChopWindingInPlace( winding_t *&inout, const Plane3f& plane, float epsilon
|
|||
Error( "ClipWinding: MAX_POINTS_ON_WINDING" );
|
||||
}
|
||||
|
||||
inout->swap( f );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
ChopWinding
|
||||
|
||||
Returns the fragment of in that is on the front side
|
||||
of the cliping plane. The original is freed.
|
||||
=================
|
||||
*/
|
||||
winding_t *ChopWinding( winding_t *in, const Plane3f& plane ){
|
||||
winding_t *f, *b;
|
||||
|
||||
ClipWindingEpsilon( *in, plane, ON_EPSILON, f, b );
|
||||
FreeWinding( in );
|
||||
if ( b ) {
|
||||
FreeWinding( b );
|
||||
}
|
||||
return f;
|
||||
inout.swap( f );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -794,7 +737,7 @@ EPlaneSide WindingOnPlaneSide( const winding_t& w, const Plane3f& plane ){
|
|||
=================
|
||||
*/
|
||||
#define MAX_HULL_POINTS 128
|
||||
void AddWindingToConvexHull( const winding_t& w, winding_t *&hull, const Vector3& normal ) {
|
||||
void AddWindingToConvexHull( const winding_t& w, winding_t& hull, const Vector3& normal ) {
|
||||
int j, k;
|
||||
int numHullPoints, numNew;
|
||||
Vector3 hullPoints[MAX_HULL_POINTS];
|
||||
|
|
@ -803,13 +746,13 @@ void AddWindingToConvexHull( const winding_t& w, winding_t *&hull, const Vect
|
|||
bool hullSide[MAX_HULL_POINTS];
|
||||
bool outside;
|
||||
|
||||
if ( hull == nullptr ) {
|
||||
hull = CopyWinding( &w );
|
||||
if ( hull.empty() ) {
|
||||
hull = w;
|
||||
return;
|
||||
}
|
||||
|
||||
numHullPoints = hull->size();
|
||||
memcpy( hullPoints, hull->data(), numHullPoints * sizeof( Vector3 ) );
|
||||
numHullPoints = hull.size();
|
||||
memcpy( hullPoints, hull.data(), numHullPoints * sizeof( Vector3 ) );
|
||||
|
||||
for ( const Vector3 &p : w ) {
|
||||
// calculate hull side vectors
|
||||
|
|
@ -861,5 +804,5 @@ void AddWindingToConvexHull( const winding_t& w, winding_t *&hull, const Vect
|
|||
memcpy( hullPoints, newHullPoints, numHullPoints * sizeof( Vector3 ) );
|
||||
}
|
||||
|
||||
*hull = winding_t( hullPoints, hullPoints + numHullPoints );
|
||||
hull = winding_t( hullPoints, hullPoints + numHullPoints );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,28 +40,22 @@ enum EPlaneSide
|
|||
eSideCross = 3,
|
||||
};
|
||||
|
||||
winding_t *AllocWinding( int points );
|
||||
winding_t AllocWinding_( int points );
|
||||
winding_t AllocWinding( int points );
|
||||
float WindingArea( const winding_t& w );
|
||||
Vector3 WindingCenter( const winding_t& w );
|
||||
void ClipWindingEpsilon( const winding_t& in, const Plane3f& plane,
|
||||
float epsilon, winding_t *&front, winding_t *&back );
|
||||
void ClipWindingEpsilonStrict( const winding_t& in, const Plane3f& plane,
|
||||
float epsilon, winding_t *&front, winding_t *&back );
|
||||
winding_t *ChopWinding( winding_t *in, const Plane3f& plane );
|
||||
winding_t *CopyWinding( const winding_t *w );
|
||||
winding_t *ReverseWinding( const winding_t& w );
|
||||
winding_t *BaseWindingForPlane( const Plane3f& plane );
|
||||
std::pair<winding_t, winding_t> ClipWindingEpsilon( const winding_t& in, const Plane3f& plane, float epsilon ); // returns { front, back } windings pair
|
||||
std::pair<winding_t, winding_t> ClipWindingEpsilonStrict( const winding_t& in, const Plane3f& plane, float epsilon ); // returns { front, back } windings pair
|
||||
winding_t ReverseWinding( const winding_t& w );
|
||||
winding_t BaseWindingForPlane( const Plane3f& plane );
|
||||
void CheckWinding( const winding_t& w );
|
||||
Plane3f WindingPlane( const winding_t& w );
|
||||
void RemoveColinearPoints( winding_t& w );
|
||||
EPlaneSide WindingOnPlaneSide( const winding_t& w, const Plane3f& plane );
|
||||
void FreeWinding( winding_t *w );
|
||||
void WindingExtendBounds( const winding_t& w, MinMax& minmax );
|
||||
|
||||
void AddWindingToConvexHull( const 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
|
||||
|
||||
void pw( const winding_t& w );
|
||||
|
|
@ -76,4 +70,4 @@ using winding_accu_t = std::vector<DoubleVector3>;
|
|||
|
||||
winding_accu_t BaseWindingForPlaneAccu( const Plane3& plane );
|
||||
void ChopWindingInPlaceAccu( winding_accu_t& w, const Plane3& plane, float epsilon );
|
||||
winding_t *CopyWindingAccuToRegular( const winding_accu_t& w );
|
||||
winding_t CopyWindingAccuToRegular( const winding_accu_t& w );
|
||||
|
|
|
|||
|
|
@ -44,17 +44,14 @@
|
|||
allocates and assigns a brush side reference
|
||||
*/
|
||||
|
||||
sideRef_t *AllocSideRef( side_t *side, sideRef_t *next ){
|
||||
sideRef_t *sideRef;
|
||||
|
||||
|
||||
sideRef_t *AllocSideRef( const side_t *side, sideRef_t *next ){
|
||||
/* dummy check */
|
||||
if ( side == NULL ) {
|
||||
return next;
|
||||
}
|
||||
|
||||
/* allocate and return */
|
||||
sideRef = safe_malloc( sizeof( *sideRef ) );
|
||||
sideRef_t *sideRef = safe_malloc( sizeof( *sideRef ) );
|
||||
sideRef->side = side;
|
||||
sideRef->next = next;
|
||||
return sideRef;
|
||||
|
|
@ -62,110 +59,6 @@ sideRef_t *AllocSideRef( side_t *side, sideRef_t *next ){
|
|||
|
||||
|
||||
|
||||
/*
|
||||
CountBrushList()
|
||||
counts the number of brushes in a brush linked list
|
||||
*/
|
||||
|
||||
int CountBrushList( brush_t *brushes ){
|
||||
int c = 0;
|
||||
|
||||
|
||||
/* count brushes */
|
||||
for ( ; brushes != NULL; brushes = brushes->next )
|
||||
c++;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
AllocBrush()
|
||||
allocates a new brush
|
||||
*/
|
||||
|
||||
brush_t *AllocBrush( int numSides ){
|
||||
return safe_calloc( offsetof_array( brush_t, sides, numSides ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
FreeBrush()
|
||||
frees a single brush and all sides/windings
|
||||
*/
|
||||
|
||||
void FreeBrush( brush_t *b ){
|
||||
int i;
|
||||
|
||||
|
||||
/* error check */
|
||||
if ( *( (unsigned int*) b ) == 0xFEFEFEFE ) {
|
||||
Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: Attempt to free an already freed brush!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* free brush sides */
|
||||
for ( i = 0; i < b->numsides; i++ )
|
||||
if ( b->sides[i].winding != NULL ) {
|
||||
FreeWinding( b->sides[ i ].winding );
|
||||
}
|
||||
|
||||
/* ydnar: overwrite it */
|
||||
memset( b, 0xFE, offsetof_array( brush_t, sides, b->numsides ) );
|
||||
*( (unsigned int*) b ) = 0xFEFEFEFE;
|
||||
|
||||
/* free it */
|
||||
free( b );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
FreeBrushList()
|
||||
frees a linked list of brushes
|
||||
*/
|
||||
|
||||
void FreeBrushList( brush_t *brushes ){
|
||||
brush_t *next;
|
||||
|
||||
|
||||
/* walk brush list */
|
||||
for ( ; brushes != NULL; brushes = next )
|
||||
{
|
||||
next = brushes->next;
|
||||
FreeBrush( brushes );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
CopyBrush()
|
||||
duplicates the brush, sides, and windings
|
||||
*/
|
||||
|
||||
brush_t *CopyBrush( const brush_t *brush ){
|
||||
/* copy brush */
|
||||
brush_t *newBrush = AllocBrush( brush->numsides );
|
||||
memcpy( newBrush, brush, offsetof_array( brush_t, sides, brush->numsides ) );
|
||||
|
||||
/* ydnar: nuke linked list */
|
||||
newBrush->next = NULL;
|
||||
|
||||
/* copy sides */
|
||||
for ( int i = 0; i < brush->numsides; i++ )
|
||||
{
|
||||
if ( brush->sides[ i ].winding != NULL ) {
|
||||
newBrush->sides[ i ].winding = CopyWinding( brush->sides[ i ].winding );
|
||||
}
|
||||
}
|
||||
|
||||
/* return it */
|
||||
return newBrush;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -174,17 +67,14 @@ brush_t *CopyBrush( const brush_t *brush ){
|
|||
returns false if the brush doesn't enclose a valid volume
|
||||
*/
|
||||
|
||||
bool BoundBrush( brush_t *brush ){
|
||||
brush->minmax.clear();
|
||||
for ( int i = 0; i < brush->numsides; i++ )
|
||||
bool BoundBrush( brush_t& brush ){
|
||||
brush.minmax.clear();
|
||||
for ( const side_t& side : brush.sides )
|
||||
{
|
||||
const winding_t *w = brush->sides[ i ].winding;
|
||||
if ( w != NULL ) {
|
||||
WindingExtendBounds( *w, brush->minmax );
|
||||
}
|
||||
WindingExtendBounds( side.winding, brush.minmax );
|
||||
}
|
||||
|
||||
return brush->minmax.valid() && c_worldMinmax.surrounds( brush->minmax );
|
||||
return brush.minmax.valid() && c_worldMinmax.surrounds( brush.minmax );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -290,19 +180,20 @@ DoubleVector3 SnapWeldVectorAccu( const DoubleVector3& a, const DoubleVector3& b
|
|||
|
||||
#define DEGENERATE_EPSILON 0.1
|
||||
|
||||
bool FixWinding( winding_t *w ){
|
||||
bool FixWinding( winding_t& w ){
|
||||
bool valid = true;
|
||||
|
||||
/* dummy check */
|
||||
if ( !w ) {
|
||||
if ( w.empty() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check all verts */
|
||||
for ( winding_t::iterator i = w->end() - 1, j = w->begin(); j != w->end(); i = j, ++j )
|
||||
for ( winding_t::iterator i = w.begin(); i != w.end(); )
|
||||
{
|
||||
winding_t::iterator j = ( std::next( i ) == w.end() )? w.begin() : std::next( i );
|
||||
/* don't remove points if winding is a triangle */
|
||||
if ( w->size() == 3 ) {
|
||||
if ( w.size() == 3 ) {
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
|
@ -312,17 +203,20 @@ bool FixWinding( winding_t *w ){
|
|||
//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) */
|
||||
*i = SnapWeldVector( *i, *j );
|
||||
//VectorAdd( w->p[ i ], w->p[ j ], vec );
|
||||
//VectorScale( vec, 0.5, w->p[ i ] );
|
||||
*j = SnapWeldVector( *i, *j );
|
||||
//VectorAdd( w[ i ], w[ j ], vec );
|
||||
//VectorScale( vec, 0.5, w[ i ] );
|
||||
|
||||
/* move the remaining verts */
|
||||
w->erase( j );
|
||||
i = w.erase( i );
|
||||
}
|
||||
else{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
/* one last check and return */
|
||||
if ( w->size() < 3 ) {
|
||||
if ( w.size() < 3 ) {
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
|
|
@ -387,25 +281,25 @@ bool FixWindingAccu( winding_accu_t& w ){
|
|||
returns false if the brush doesn't enclose a valid volume
|
||||
*/
|
||||
|
||||
bool CreateBrushWindings( brush_t *brush ){
|
||||
bool CreateBrushWindings( brush_t& brush ){
|
||||
/* walk the list of brush sides */
|
||||
for ( int i = 0; i < brush->numsides; i++ )
|
||||
for ( size_t i = 0; i < brush.sides.size(); ++i )
|
||||
{
|
||||
/* get side and plane */
|
||||
side_t& side = brush->sides[ i ];
|
||||
side_t& side = brush.sides[ i ];
|
||||
const plane_t& plane = mapplanes[ side.planenum ];
|
||||
|
||||
/* make huge winding */
|
||||
#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES
|
||||
winding_accu_t w = BaseWindingForPlaneAccu( ( side.plane.normal() != g_vector3_identity )? side.plane : Plane3( plane.plane ) );
|
||||
#else
|
||||
winding_t *w = BaseWindingForPlane( plane.plane );
|
||||
winding_t w = BaseWindingForPlane( plane.plane );
|
||||
#endif
|
||||
|
||||
/* walk the list of brush sides */
|
||||
for ( int j = 0; j < brush->numsides && !w.empty(); j++ )
|
||||
for ( size_t j = 0; j < brush.sides.size() && !w.empty(); ++j )
|
||||
{
|
||||
const side_t& cside = brush->sides[ j ];
|
||||
const side_t& cside = brush.sides[ j ];
|
||||
const plane_t& cplane = mapplanes[ cside.planenum ^ 1 ];
|
||||
if ( i == j
|
||||
|| cside.planenum == ( side.planenum ^ 1 ) /* back side clipaway */
|
||||
|
|
@ -432,9 +326,12 @@ bool CreateBrushWindings( brush_t *brush ){
|
|||
/* set side winding */
|
||||
#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES
|
||||
FixWindingAccu( w );
|
||||
side.winding = ( w.size() >= 3 ? CopyWindingAccuToRegular( w ) : NULL );
|
||||
if( w.size() >= 3 )
|
||||
side.winding = CopyWindingAccuToRegular( w );
|
||||
else
|
||||
side.winding.clear();
|
||||
#else
|
||||
side.winding = w;
|
||||
side.winding.swap( w );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -452,20 +349,16 @@ bool CreateBrushWindings( brush_t *brush ){
|
|||
Creates a new axial brush
|
||||
==================
|
||||
*/
|
||||
brush_t *BrushFromBounds( const Vector3& mins, const Vector3& maxs ){
|
||||
brush_t *b;
|
||||
int i;
|
||||
float dist;
|
||||
|
||||
b = AllocBrush( 6 );
|
||||
b->numsides = 6;
|
||||
for ( i = 0 ; i < 3 ; i++ )
|
||||
brush_t BrushFromBounds( const Vector3& mins, const Vector3& maxs ){
|
||||
brush_t b;
|
||||
b.sides.resize( 6 );
|
||||
for ( int i = 0 ; i < 3 ; i++ )
|
||||
{
|
||||
dist = maxs[i];
|
||||
b->sides[i].planenum = FindFloatPlane( g_vector3_axes[i], dist, 1, &maxs );
|
||||
float dist = maxs[i];
|
||||
b.sides[i].planenum = FindFloatPlane( g_vector3_axes[i], dist, 1, &maxs );
|
||||
|
||||
dist = -mins[i];
|
||||
b->sides[3 + i].planenum = FindFloatPlane( -g_vector3_axes[i], dist, 1, &mins );
|
||||
b.sides[3 + i].planenum = FindFloatPlane( -g_vector3_axes[i], dist, 1, &mins );
|
||||
}
|
||||
|
||||
CreateBrushWindings( b );
|
||||
|
|
@ -479,45 +372,25 @@ brush_t *BrushFromBounds( const Vector3& mins, const Vector3& maxs ){
|
|||
|
||||
==================
|
||||
*/
|
||||
float BrushVolume( brush_t *brush ){
|
||||
int i;
|
||||
const winding_t *w;
|
||||
Vector3 corner;
|
||||
float volume;
|
||||
|
||||
if ( !brush ) {
|
||||
return 0;
|
||||
}
|
||||
float BrushVolume( const brush_t& brush ){
|
||||
float volume = 0;
|
||||
|
||||
for ( auto i = brush.sides.cbegin(); i != brush.sides.cend(); ++i ){
|
||||
// grab the first valid point as the corner
|
||||
|
||||
w = NULL;
|
||||
for ( i = 0 ; i < brush->numsides ; i++ )
|
||||
if( !i->winding.empty() ){
|
||||
const Vector3 corner = i->winding[0];
|
||||
// make tetrahedrons to all other faces
|
||||
for ( ++i; i != brush.sides.cend(); ++i )
|
||||
{
|
||||
w = brush->sides[i].winding;
|
||||
if ( w ) {
|
||||
if ( !i->winding.empty() ) {
|
||||
volume += -plane3_distance_to_point( mapplanes[i->planenum].plane, corner ) * WindingArea( i->winding );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !w ) {
|
||||
return 0;
|
||||
}
|
||||
corner = ( *w )[0];
|
||||
|
||||
// make tetrahedrons to all other faces
|
||||
|
||||
volume = 0;
|
||||
for ( ; i < brush->numsides ; i++ )
|
||||
{
|
||||
w = brush->sides[i].winding;
|
||||
if ( !w ) {
|
||||
continue;
|
||||
}
|
||||
volume += -plane3_distance_to_point( mapplanes[brush->sides[i].planenum].plane, corner ) * WindingArea( *w );
|
||||
}
|
||||
|
||||
volume /= 3;
|
||||
return volume;
|
||||
return volume / 3;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -527,10 +400,7 @@ float BrushVolume( brush_t *brush ){
|
|||
writes a map with the split bsp brushes
|
||||
*/
|
||||
|
||||
void WriteBSPBrushMap( const char *name, brush_t *list ){
|
||||
side_t *s;
|
||||
int i;
|
||||
|
||||
void WriteBSPBrushMap( const char *name, const brushlist_t& list ){
|
||||
/* note it */
|
||||
Sys_Printf( "Writing %s\n", name );
|
||||
|
||||
|
|
@ -539,22 +409,20 @@ void WriteBSPBrushMap( const char *name, brush_t *list ){
|
|||
|
||||
fprintf( f, "{\n\"classname\" \"worldspawn\"\n" );
|
||||
|
||||
for ( ; list; list = list->next )
|
||||
for ( const brush_t& brush : list )
|
||||
{
|
||||
fprintf( f, "{\n" );
|
||||
for ( i = 0, s = list->sides; i < list->numsides; i++, s++ )
|
||||
for ( const side_t& side : brush.sides )
|
||||
{
|
||||
// TODO: See if we can use a smaller winding to prevent resolution loss.
|
||||
// Is WriteBSPBrushMap() used only to decompile maps?
|
||||
winding_t *w = BaseWindingForPlane( mapplanes[s->planenum].plane );
|
||||
const winding_t& wr = *w;
|
||||
const winding_t w = BaseWindingForPlane( mapplanes[side.planenum].plane );
|
||||
|
||||
fprintf( f, "( %i %i %i ) ", (int)wr[0][0], (int)wr[0][1], (int)wr[0][2] );
|
||||
fprintf( f, "( %i %i %i ) ", (int)wr[1][0], (int)wr[1][1], (int)wr[1][2] );
|
||||
fprintf( f, "( %i %i %i ) ", (int)wr[2][0], (int)wr[2][1], (int)wr[2][2] );
|
||||
fprintf( f, "( %i %i %i ) ", (int)w[0][0], (int)w[0][1], (int)w[0][2] );
|
||||
fprintf( f, "( %i %i %i ) ", (int)w[1][0], (int)w[1][1], (int)w[1][2] );
|
||||
fprintf( f, "( %i %i %i ) ", (int)w[2][0], (int)w[2][1], (int)w[2][2] );
|
||||
|
||||
fprintf( f, "notexture 0 0 0 1 1\n" );
|
||||
FreeWinding( w );
|
||||
}
|
||||
fprintf( f, "}\n" );
|
||||
}
|
||||
|
|
@ -572,10 +440,6 @@ void WriteBSPBrushMap( const char *name, brush_t *list ){
|
|||
*/
|
||||
|
||||
int FilterBrushIntoTree_r( brush_t* b, node_t *node ){
|
||||
brush_t *front, *back;
|
||||
int c;
|
||||
|
||||
|
||||
/* dummy check */
|
||||
if ( b == NULL ) {
|
||||
return 0;
|
||||
|
|
@ -584,8 +448,7 @@ int FilterBrushIntoTree_r( brush_t *b, node_t *node ){
|
|||
/* add it to the leaf list */
|
||||
if ( node->planenum == PLANENUM_LEAF ) {
|
||||
/* something somewhere is hammering brushlist */
|
||||
b->next = node->brushlist;
|
||||
node->brushlist = b;
|
||||
node->brushlist.push_front( std::move( *b ) );
|
||||
|
||||
/* classify the leaf by the structural brush */
|
||||
if ( !b->detail ) {
|
||||
|
|
@ -604,11 +467,10 @@ int FilterBrushIntoTree_r( brush_t *b, node_t *node ){
|
|||
}
|
||||
|
||||
/* split it by the node plane */
|
||||
c = b->numsides;
|
||||
SplitBrush( b, node->planenum, &front, &back );
|
||||
FreeBrush( b );
|
||||
auto [front, back] = SplitBrush( *b, node->planenum );
|
||||
delete b;
|
||||
|
||||
c = 0;
|
||||
int c = 0;
|
||||
c += FilterBrushIntoTree_r( front, node->children[ 0 ] );
|
||||
c += FilterBrushIntoTree_r( back, node->children[ 1 ] );
|
||||
|
||||
|
|
@ -622,11 +484,8 @@ int FilterBrushIntoTree_r( brush_t *b, node_t *node ){
|
|||
fragment all the detail brushes into the structural leafs
|
||||
*/
|
||||
|
||||
void FilterDetailBrushesIntoTree( entity_t *e, tree_t *tree ){
|
||||
brush_t *b, *newb;
|
||||
int r;
|
||||
int c_unique, c_clusters;
|
||||
int i;
|
||||
void FilterDetailBrushesIntoTree( entity_t *e, tree_t& tree ){
|
||||
int c_unique = 0, c_clusters = 0;
|
||||
|
||||
|
||||
/* note it */
|
||||
|
|
@ -635,22 +494,21 @@ void FilterDetailBrushesIntoTree( entity_t *e, tree_t *tree ){
|
|||
/* walk the list of brushes */
|
||||
c_unique = 0;
|
||||
c_clusters = 0;
|
||||
for ( b = e->brushes; b; b = b->next )
|
||||
for ( brush_t& b : e->brushes )
|
||||
{
|
||||
if ( !b->detail ) {
|
||||
if ( !b.detail ) {
|
||||
continue;
|
||||
}
|
||||
c_unique++;
|
||||
newb = CopyBrush( b );
|
||||
r = FilterBrushIntoTree_r( newb, tree->headnode );
|
||||
const int r = FilterBrushIntoTree_r( new brush_t( b ), tree.headnode );
|
||||
c_clusters += r;
|
||||
|
||||
/* mark all sides as visible so drawsurfs are created */
|
||||
if ( r ) {
|
||||
for ( i = 0; i < b->numsides; i++ )
|
||||
for ( side_t& side : b.sides )
|
||||
{
|
||||
if ( b->sides[ i ].winding ) {
|
||||
b->sides[ i ].visible = true;
|
||||
if ( !side.winding.empty() ) {
|
||||
side.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -668,30 +526,24 @@ void FilterDetailBrushesIntoTree( entity_t *e, tree_t *tree ){
|
|||
Mark the leafs as opaque and areaportals
|
||||
=====================
|
||||
*/
|
||||
void FilterStructuralBrushesIntoTree( entity_t *e, tree_t *tree ) {
|
||||
brush_t *b, *newb;
|
||||
int r;
|
||||
int c_unique, c_clusters;
|
||||
int i;
|
||||
void FilterStructuralBrushesIntoTree( entity_t *e, tree_t& tree ) {
|
||||
int c_unique = 0, c_clusters = 0;
|
||||
|
||||
Sys_FPrintf( SYS_VRB, "--- FilterStructuralBrushesIntoTree ---\n" );
|
||||
|
||||
c_unique = 0;
|
||||
c_clusters = 0;
|
||||
for ( b = e->brushes ; b ; b = b->next ) {
|
||||
if ( b->detail ) {
|
||||
for ( brush_t& b : e->brushes ) {
|
||||
if ( b.detail ) {
|
||||
continue;
|
||||
}
|
||||
c_unique++;
|
||||
newb = CopyBrush( b );
|
||||
r = FilterBrushIntoTree_r( newb, tree->headnode );
|
||||
const int r = FilterBrushIntoTree_r( new brush_t( b ), tree.headnode );
|
||||
c_clusters += r;
|
||||
|
||||
// mark all sides as visible so drawsurfs are created
|
||||
if ( r ) {
|
||||
for ( i = 0 ; i < b->numsides ; i++ ) {
|
||||
if ( b->sides[i].winding ) {
|
||||
b->sides[i].visible = true;
|
||||
for ( side_t& side : b.sides ) {
|
||||
if ( !side.winding.empty() ) {
|
||||
side.visible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -703,28 +555,6 @@ void FilterStructuralBrushesIntoTree( entity_t *e, tree_t *tree ) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
AllocTree
|
||||
================
|
||||
*/
|
||||
tree_t *AllocTree( void ){
|
||||
tree_t *tree = safe_calloc( sizeof( *tree ) );
|
||||
tree->minmax.clear();
|
||||
return tree;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
AllocNode
|
||||
================
|
||||
*/
|
||||
node_t *AllocNode( void ){
|
||||
return safe_calloc( sizeof( node_t ) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
WindingIsTiny
|
||||
|
|
@ -776,16 +606,14 @@ bool WindingIsHuge( const winding_t& w ){
|
|||
|
||||
==================
|
||||
*/
|
||||
int BrushMostlyOnSide( brush_t *brush, plane_t *plane ){
|
||||
int BrushMostlyOnSide( const brush_t& brush, const Plane3f& plane ){
|
||||
float max = 0;
|
||||
int side = PSIDE_FRONT;
|
||||
for ( int i = 0 ; i < brush->numsides ; i++ )
|
||||
for ( const side_t& s : brush.sides )
|
||||
{
|
||||
winding_t *w = brush->sides[i].winding;
|
||||
if ( w ) {
|
||||
for ( const Vector3& p : *w )
|
||||
for ( const Vector3& p : s.winding )
|
||||
{
|
||||
const double d = plane3_distance_to_point( plane->plane, p );
|
||||
const double d = plane3_distance_to_point( plane, p );
|
||||
if ( d > max ) {
|
||||
max = d;
|
||||
side = PSIDE_FRONT;
|
||||
|
|
@ -796,7 +624,6 @@ int BrushMostlyOnSide( brush_t *brush, plane_t *plane ){
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return side;
|
||||
}
|
||||
|
||||
|
|
@ -807,30 +634,16 @@ int BrushMostlyOnSide( brush_t *brush, plane_t *plane ){
|
|||
generates two new brushes, leaving the original unchanged
|
||||
*/
|
||||
|
||||
void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back ){
|
||||
brush_t *b[2];
|
||||
int i, j;
|
||||
winding_t *w, *cw[2], *midwinding;
|
||||
plane_t *plane, *plane2;
|
||||
side_t *s, *cs;
|
||||
float d_front, d_back;
|
||||
|
||||
|
||||
*front = NULL;
|
||||
*back = NULL;
|
||||
plane = &mapplanes[planenum];
|
||||
std::pair<brush_t*, brush_t*> SplitBrush( const brush_t& brush, int planenum ){
|
||||
const Plane3f& plane = mapplanes[planenum].plane;
|
||||
|
||||
// check all points
|
||||
d_front = d_back = 0;
|
||||
for ( i = 0 ; i < brush->numsides ; i++ )
|
||||
float d_front = 0, d_back = 0;
|
||||
for ( const side_t& side : brush.sides )
|
||||
{
|
||||
w = brush->sides[i].winding;
|
||||
if ( !w ) {
|
||||
continue;
|
||||
}
|
||||
for ( const Vector3& p : *w )
|
||||
for ( const Vector3& p : side.winding )
|
||||
{
|
||||
const float d = plane3_distance_to_point( plane->plane, p );
|
||||
const float d = plane3_distance_to_point( plane, p );
|
||||
if ( d > 0 ) {
|
||||
value_maximize( d_front, d );
|
||||
}
|
||||
|
|
@ -842,140 +655,117 @@ void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back )
|
|||
|
||||
if ( d_front < 0.1 ) { // PLANESIDE_EPSILON)
|
||||
// only on back
|
||||
*back = CopyBrush( brush );
|
||||
return;
|
||||
return { {}, new brush_t( brush ) };
|
||||
}
|
||||
|
||||
if ( d_back > -0.1 ) { // PLANESIDE_EPSILON)
|
||||
// only on front
|
||||
*front = CopyBrush( brush );
|
||||
return;
|
||||
return { new brush_t( brush ), {} };
|
||||
}
|
||||
|
||||
// create a new winding from the split plane
|
||||
w = BaseWindingForPlane( plane->plane );
|
||||
for ( i = 0 ; i < brush->numsides && w ; i++ )
|
||||
winding_t midwinding = BaseWindingForPlane( plane );
|
||||
for ( const side_t& side : brush.sides )
|
||||
{
|
||||
plane2 = &mapplanes[brush->sides[i].planenum ^ 1];
|
||||
ChopWindingInPlace( w, plane2->plane, 0 ); // PLANESIDE_EPSILON);
|
||||
ChopWindingInPlace( midwinding, mapplanes[side.planenum ^ 1].plane, 0 ); // PLANESIDE_EPSILON);
|
||||
if( midwinding.empty() )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !w || WindingIsTiny( *w ) ) { // the brush isn't really split
|
||||
int side;
|
||||
|
||||
side = BrushMostlyOnSide( brush, plane );
|
||||
if ( side == PSIDE_FRONT ) {
|
||||
*front = CopyBrush( brush );
|
||||
}
|
||||
if ( midwinding.empty() || WindingIsTiny( midwinding ) ) { // the brush isn't really split
|
||||
const int side = BrushMostlyOnSide( brush, plane );
|
||||
if ( side == PSIDE_BACK ) {
|
||||
*back = CopyBrush( brush );
|
||||
return { {}, new brush_t( brush ) };
|
||||
}
|
||||
else { // side == PSIDE_FRONT
|
||||
return { new brush_t( brush ), {} };
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( WindingIsHuge( *w ) ) {
|
||||
if ( WindingIsHuge( midwinding ) ) {
|
||||
Sys_FPrintf( SYS_WRN | SYS_VRBflag, "WARNING: huge winding\n" );
|
||||
}
|
||||
|
||||
midwinding = w;
|
||||
|
||||
// split it for real
|
||||
|
||||
for ( i = 0 ; i < 2 ; i++ )
|
||||
brush_t *b[2];
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
b[i] = AllocBrush( brush->numsides + 1 );
|
||||
memcpy( b[i], brush, sizeof( brush_t ) );
|
||||
b[i]->numsides = 0;
|
||||
b[i]->next = NULL;
|
||||
b[i]->original = brush->original;
|
||||
b[i] = new brush_t( brush );
|
||||
b[i]->sides.clear();
|
||||
}
|
||||
|
||||
// split all the current windings
|
||||
|
||||
for ( i = 0 ; i < brush->numsides ; i++ )
|
||||
for ( const side_t& side : brush.sides )
|
||||
{
|
||||
s = &brush->sides[i];
|
||||
w = s->winding;
|
||||
if ( !w ) {
|
||||
continue;
|
||||
}
|
||||
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 */
|
||||
for ( j = 0 ; j < 2 ; j++ )
|
||||
if ( !side.winding.empty() ) {
|
||||
winding_t cw[2];
|
||||
std::tie( cw[0], cw[1] ) =
|
||||
ClipWindingEpsilonStrict( side.winding, plane, 0 /*PLANESIDE_EPSILON*/ ); /* strict, in parallel case we get the face back because it also is the midwinding */
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
if ( !cw[j] ) {
|
||||
continue;
|
||||
if ( !cw[i].empty() ) {
|
||||
side_t& cs = b[i]->sides.emplace_back( side );
|
||||
cs.winding.swap( cw[i] );
|
||||
}
|
||||
}
|
||||
cs = &b[j]->sides[b[j]->numsides];
|
||||
b[j]->numsides++;
|
||||
*cs = *s;
|
||||
cs->winding = cw[j];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// see if we have valid polygons on both sides
|
||||
for ( i = 0 ; i < 2 ; i++ )
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
if ( b[i]->numsides < 3 || !BoundBrush( b[i] ) ) {
|
||||
if ( b[i]->numsides >= 3 ) {
|
||||
if ( b[i]->sides.size() < 3 || !BoundBrush( *b[i] ) ) {
|
||||
if ( b[i]->sides.size() >= 3 ) {
|
||||
Sys_FPrintf( SYS_WRN | SYS_VRBflag, "bogus brush after clip\n" );
|
||||
}
|
||||
FreeBrush( b[i] );
|
||||
delete b[i];
|
||||
b[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !( b[0] && b[1] ) ) {
|
||||
if ( !b[0] && !b[1] ) {
|
||||
if ( b[0] == nullptr || b[1] == nullptr ) {
|
||||
if ( b[0] == nullptr && b[1] == nullptr ) {
|
||||
Sys_FPrintf( SYS_WRN | SYS_VRBflag, "split removed brush\n" );
|
||||
}
|
||||
else{
|
||||
Sys_FPrintf( SYS_WRN | SYS_VRBflag, "split not on both sides\n" );
|
||||
}
|
||||
if ( b[0] ) {
|
||||
FreeBrush( b[0] );
|
||||
*front = CopyBrush( brush );
|
||||
if ( b[0] != nullptr ) {
|
||||
delete b[0];
|
||||
return { new brush_t( brush ), {} };
|
||||
}
|
||||
if ( b[1] ) {
|
||||
FreeBrush( b[1] );
|
||||
*back = CopyBrush( brush );
|
||||
else if ( b[1] != nullptr ) {
|
||||
delete b[1];
|
||||
return { {}, new brush_t( brush ) };
|
||||
}
|
||||
return;
|
||||
return{};
|
||||
}
|
||||
|
||||
// add the midwinding to both sides
|
||||
for ( i = 0 ; i < 2 ; i++ )
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
cs = &b[i]->sides[b[i]->numsides];
|
||||
b[i]->numsides++;
|
||||
side_t& cs = b[i]->sides.emplace_back();
|
||||
|
||||
cs->planenum = planenum ^ i ^ 1;
|
||||
cs->shaderInfo = NULL;
|
||||
cs.planenum = planenum ^ i ^ 1;
|
||||
cs.shaderInfo = NULL;
|
||||
if ( i == 0 ) {
|
||||
cs->winding = CopyWinding( midwinding );
|
||||
cs.winding = midwinding; // copy
|
||||
}
|
||||
else{
|
||||
cs->winding = midwinding;
|
||||
cs.winding.swap( midwinding ); // move
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
float v1;
|
||||
int i;
|
||||
|
||||
|
||||
for ( i = 0 ; i < 2 ; i++ )
|
||||
{
|
||||
v1 = BrushVolume( b[i] );
|
||||
if ( v1 < 1.0 ) {
|
||||
FreeBrush( b[i] );
|
||||
if ( BrushVolume( *b[i] ) < 1.0 ) {
|
||||
delete b[i];
|
||||
b[i] = NULL;
|
||||
// Sys_FPrintf( SYS_WRN | SYS_VRBflag, "tiny volume after clip\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*front = b[0];
|
||||
*back = b[1];
|
||||
return{ b[0], b[1] };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,11 +47,11 @@ static void autocaulk_write(){
|
|||
int flava = 8;
|
||||
ApplySurfaceParm( "lava", &flava, NULL, NULL );
|
||||
|
||||
for ( brush_t* b = entities[0].brushes; b; b = b->next ) {
|
||||
fprintf( file, "%i ", b->brushNum );
|
||||
shaderInfo_t* contentShader = b->contentShader;
|
||||
for( int i = 0; i < b->numsides; ++i ){
|
||||
if( b->sides[i].visibleHull || ( b->sides[i].compileFlags & C_NODRAW ) ){
|
||||
for ( const brush_t& b : entities[0].brushes ) {
|
||||
fprintf( file, "%i ", b.brushNum );
|
||||
const shaderInfo_t* contentShader = b.contentShader;
|
||||
for( const side_t& side : b.sides ){
|
||||
if( !side.visibleHull.empty() || ( side.compileFlags & C_NODRAW ) ){
|
||||
fprintf( file, "-" );
|
||||
}
|
||||
else if( contentShader->compileFlags & C_LIQUID ){
|
||||
|
|
@ -62,7 +62,7 @@ static void autocaulk_write(){
|
|||
else
|
||||
fprintf( file, "w" );
|
||||
}
|
||||
else if( b->compileFlags & C_TRANSLUCENT ){
|
||||
else if( b.compileFlags & C_TRANSLUCENT ){
|
||||
if( contentShader->compileFlags & C_SOLID )
|
||||
fprintf( file, "N" );
|
||||
else
|
||||
|
|
@ -170,7 +170,7 @@ static void SetCloneModelNumbers( void ){
|
|||
for ( std::size_t i = 1; i < entities.size(); ++i )
|
||||
{
|
||||
/* only entities with brushes or patches get a model number */
|
||||
if ( entities[ i ].brushes == NULL && entities[ i ].patches == NULL ) {
|
||||
if ( entities[ i ].brushes.empty() && entities[ i ].patches == NULL ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -190,7 +190,7 @@ static void SetCloneModelNumbers( void ){
|
|||
for ( std::size_t i = 1; i < entities.size(); ++i )
|
||||
{
|
||||
/* only entities with brushes or patches get a model number */
|
||||
if ( entities[ i ].brushes == NULL && entities[ i ].patches == NULL ) {
|
||||
if ( entities[ i ].brushes.empty() && entities[ i ].patches == NULL ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -220,7 +220,7 @@ static void SetCloneModelNumbers( void ){
|
|||
entities[ i ].setKeyValue( "model", modelValue );
|
||||
|
||||
/* nuke the brushes/patches for this entity (fixme: leak!) */
|
||||
entities[ i ].brushes = NULL;
|
||||
brushlist_t *leak = new brushlist_t( std::move( entities[ i ].brushes ) ); // are brushes referenced elsewhere, so we do not nuke them really?
|
||||
entities[ i ].patches = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -284,8 +284,6 @@ static void FixBrushSides( entity_t *e ){
|
|||
|
||||
void ProcessWorldModel( void ){
|
||||
entity_t *e;
|
||||
tree_t *tree;
|
||||
facelist_t faces;
|
||||
xmlNodePtr polyline, leaknode;
|
||||
char level[ 2 ];
|
||||
const char *value;
|
||||
|
|
@ -321,8 +319,8 @@ void ProcessWorldModel( void ){
|
|||
}
|
||||
|
||||
/* build an initial bsp tree using all of the sides of all of the structural brushes */
|
||||
faces = MakeStructuralBSPFaceList( entities[ 0 ].brushes );
|
||||
tree = FaceBSP( faces );
|
||||
facelist_t faces = MakeStructuralBSPFaceList( entities[ 0 ].brushes );
|
||||
tree_t tree = FaceBSP( faces );
|
||||
MakeTreePortals( tree );
|
||||
FilterStructuralBrushesIntoTree( e, tree );
|
||||
|
||||
|
|
@ -353,7 +351,7 @@ void ProcessWorldModel( void ){
|
|||
|
||||
if ( leakStatus != EFloodEntities::Empty ) { /* if no entities exist, this would accidentally the whole map, and that IS bad */
|
||||
/* rebuild a better bsp tree using only the sides that are visible from the inside */
|
||||
FillOutside( tree->headnode );
|
||||
FillOutside( tree.headnode );
|
||||
|
||||
/* chop the sides to the convex hull of their visible fragments, giving us the smallest polygons */
|
||||
ClipSidesIntoTree( e, tree );
|
||||
|
|
@ -372,7 +370,7 @@ void ProcessWorldModel( void ){
|
|||
|
||||
/* flood again to discard portals in the void (also required for _skybox) */
|
||||
FloodEntities( tree );
|
||||
FillOutside( tree->headnode );
|
||||
FillOutside( tree.headnode );
|
||||
}
|
||||
|
||||
/* save out information for visibility processing */
|
||||
|
|
@ -405,7 +403,7 @@ void ProcessWorldModel( void ){
|
|||
|
||||
/* subdivide each drawsurf as required by shader tesselation */
|
||||
if ( !nosubdivide ) {
|
||||
SubdivideFaceSurfaces( e, tree );
|
||||
SubdivideFaceSurfaces( e );
|
||||
}
|
||||
|
||||
/* add in any vertexes required to fix t-junctions */
|
||||
|
|
@ -433,7 +431,7 @@ void ProcessWorldModel( void ){
|
|||
/* ydnar: fog hull */
|
||||
if ( entities[ 0 ].read_keyvalue( value, "_foghull" ) ) {
|
||||
const auto shader = String64()( "textures/", value );
|
||||
MakeFogHullSurfs( e, tree, shader );
|
||||
MakeFogHullSurfs( e, shader );
|
||||
}
|
||||
|
||||
/* ydnar: bug 645: do flares for lights */
|
||||
|
|
@ -484,7 +482,7 @@ void ProcessWorldModel( void ){
|
|||
FixBrushSides( e );
|
||||
|
||||
/* finish */
|
||||
EndModel( e, tree->headnode );
|
||||
EndModel( e, tree.headnode );
|
||||
FreeTree( tree );
|
||||
}
|
||||
|
||||
|
|
@ -496,15 +494,9 @@ void ProcessWorldModel( void ){
|
|||
*/
|
||||
|
||||
void ProcessSubModel( void ){
|
||||
entity_t *e;
|
||||
tree_t *tree;
|
||||
brush_t *b, *bc;
|
||||
node_t *node;
|
||||
|
||||
|
||||
/* start a brush model */
|
||||
BeginModel();
|
||||
e = &entities[ mapEntityNum ];
|
||||
entity_t *e = &entities[ mapEntityNum ];
|
||||
e->firstDrawSurf = numMapDrawSurfs;
|
||||
|
||||
/* ydnar: gs mods */
|
||||
|
|
@ -514,10 +506,9 @@ void ProcessSubModel( void ){
|
|||
PatchMapDrawSurfs( e );
|
||||
|
||||
/* allocate a tree */
|
||||
node = AllocNode();
|
||||
node->planenum = PLANENUM_LEAF;
|
||||
tree = AllocTree();
|
||||
tree->headnode = node;
|
||||
tree_t tree{};
|
||||
tree.headnode = AllocNode();
|
||||
tree.headnode->planenum = PLANENUM_LEAF;
|
||||
|
||||
/* add the sides to the tree */
|
||||
ClipSidesIntoTree( e, tree );
|
||||
|
|
@ -532,16 +523,11 @@ void ProcessSubModel( void ){
|
|||
EmitBrushes( e->brushes, &e->firstBrush, &e->numBrushes );
|
||||
|
||||
/* just put all the brushes in headnode */
|
||||
for ( b = e->brushes; b; b = b->next )
|
||||
{
|
||||
bc = CopyBrush( b );
|
||||
bc->next = node->brushlist;
|
||||
node->brushlist = bc;
|
||||
}
|
||||
tree.headnode->brushlist = e->brushes;
|
||||
|
||||
/* subdivide each drawsurf as required by shader tesselation */
|
||||
if ( !nosubdivide ) {
|
||||
SubdivideFaceSurfaces( e, tree );
|
||||
SubdivideFaceSurfaces( e );
|
||||
}
|
||||
|
||||
/* add in any vertexes required to fix t-junctions */
|
||||
|
|
@ -568,7 +554,7 @@ void ProcessSubModel( void ){
|
|||
FixBrushSides( e );
|
||||
|
||||
/* finish */
|
||||
EndModel( e, node );
|
||||
EndModel( e, tree.headnode );
|
||||
FreeTree( tree );
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +583,7 @@ void ProcessModels( void ){
|
|||
{
|
||||
/* get entity */
|
||||
const entity_t& entity = entities[ mapEntityNum ];
|
||||
if ( entity.brushes == NULL && entity.patches == NULL ) {
|
||||
if ( entity.brushes.empty() && entity.patches == NULL ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -726,10 +726,7 @@ void PseudoCompileBSP( bool need_tree ){
|
|||
char modelValue[16];
|
||||
entity_t *entity;
|
||||
facelist_t faces;
|
||||
tree_t *tree;
|
||||
node_t *node;
|
||||
brush_t *brush;
|
||||
side_t *side;
|
||||
tree_t tree{};
|
||||
|
||||
SetDrawSurfacesBuffer();
|
||||
mapDrawSurfs = safe_calloc( sizeof( mapDrawSurface_t ) * MAX_MAP_DRAW_SURFS );
|
||||
|
|
@ -741,7 +738,7 @@ void PseudoCompileBSP( bool need_tree ){
|
|||
{
|
||||
/* get entity */
|
||||
entity = &entities[ mapEntityNum ];
|
||||
if ( entity->brushes == NULL && entity->patches == NULL ) {
|
||||
if ( entity->brushes.empty() && entity->patches == NULL ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -762,33 +759,28 @@ void PseudoCompileBSP( bool need_tree ){
|
|||
if ( mapEntityNum == 0 && need_tree ) {
|
||||
faces = MakeStructuralBSPFaceList( entities[0].brushes );
|
||||
tree = FaceBSP( faces );
|
||||
node = tree->headnode;
|
||||
}
|
||||
else
|
||||
{
|
||||
node = AllocNode();
|
||||
node->planenum = PLANENUM_LEAF;
|
||||
tree = AllocTree();
|
||||
tree->headnode = node;
|
||||
tree.headnode = AllocNode();
|
||||
tree.headnode->planenum = PLANENUM_LEAF;
|
||||
}
|
||||
|
||||
/* a minimized ClipSidesIntoTree */
|
||||
for ( brush = entity->brushes; brush; brush = brush->next )
|
||||
for ( const brush_t& brush : entity->brushes )
|
||||
{
|
||||
/* walk the brush sides */
|
||||
for ( int j = 0; j < brush->numsides; j++ )
|
||||
for ( const side_t& side : brush.sides )
|
||||
{
|
||||
/* get side */
|
||||
side = &brush->sides[ j ];
|
||||
if ( side->winding == NULL ) {
|
||||
if ( side.winding.empty() ) {
|
||||
continue;
|
||||
}
|
||||
/* shader? */
|
||||
if ( side->shaderInfo == NULL ) {
|
||||
if ( side.shaderInfo == NULL ) {
|
||||
continue;
|
||||
}
|
||||
/* save this winding as a visible surface */
|
||||
DrawSurfaceForSide( entity, brush, side, *side->winding );
|
||||
DrawSurfaceForSide( entity, brush, side, side.winding );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -805,7 +797,7 @@ void PseudoCompileBSP( bool need_tree ){
|
|||
FilterDetailBrushesIntoTree( entity, tree );
|
||||
|
||||
EmitBrushes( entity->brushes, &entity->firstBrush, &entity->numBrushes );
|
||||
EndModel( entity, node );
|
||||
EndModel( entity, tree.headnode );
|
||||
}
|
||||
EndBSPFile( false );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,14 +47,14 @@ static float Det3x3( float a00, float a01, float a02,
|
|||
+ a02 * ( a10 * a21 - a11 * a20 );
|
||||
}
|
||||
|
||||
void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t *bestVert[3] ){
|
||||
void GetBestSurfaceTriangleMatchForBrushside( const side_t& buildSide, bspDrawVert_t *bestVert[3] ){
|
||||
bspDrawSurface_t *s;
|
||||
int i;
|
||||
int t;
|
||||
float best = 0;
|
||||
float thisarea;
|
||||
bspDrawVert_t *vert[3];
|
||||
const plane_t& buildPlane = mapplanes[buildSide->planenum];
|
||||
const plane_t& buildPlane = mapplanes[buildSide.planenum];
|
||||
int matches = 0;
|
||||
|
||||
// first, start out with NULLs
|
||||
|
|
@ -66,7 +66,7 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t *
|
|||
if ( s->surfaceType != MST_PLANAR && s->surfaceType != MST_TRIANGLE_SOUP ) {
|
||||
continue;
|
||||
}
|
||||
if ( !strEqual( buildSide->shaderInfo->shader, bspShaders[s->shaderNum].shader ) ) {
|
||||
if ( !strEqual( buildSide.shaderInfo->shader, bspShaders[s->shaderNum].shader ) ) {
|
||||
continue;
|
||||
}
|
||||
for ( t = 0; t + 3 <= s->numIndexes; t += 3 )
|
||||
|
|
@ -98,7 +98,7 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t *
|
|||
continue;
|
||||
}
|
||||
// Okay. Correct surface type, correct shader, correct plane. Let's start with the business...
|
||||
winding_t *polygon = CopyWinding( buildSide->winding );
|
||||
winding_t polygon( buildSide.winding );
|
||||
for ( i = 0; i < 3; ++i )
|
||||
{
|
||||
// 0: 1, 2
|
||||
|
|
@ -110,11 +110,11 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t *
|
|||
Plane3f plane( vector3_cross( v2 - v1, buildPlane.normal() ), 0 );
|
||||
plane.dist() = vector3_dot( v1, plane.normal() );
|
||||
ChopWindingInPlace( polygon, plane, distanceEpsilon );
|
||||
if ( !polygon ) {
|
||||
if ( polygon.empty() ) {
|
||||
goto exwinding;
|
||||
}
|
||||
}
|
||||
thisarea = WindingArea( *polygon );
|
||||
thisarea = WindingArea( polygon );
|
||||
if ( thisarea > 0 ) {
|
||||
++matches;
|
||||
}
|
||||
|
|
@ -124,13 +124,12 @@ void GetBestSurfaceTriangleMatchForBrushside( side_t *buildSide, bspDrawVert_t *
|
|||
bestVert[1] = vert[1];
|
||||
bestVert[2] = vert[2];
|
||||
}
|
||||
FreeWinding( polygon );
|
||||
exwinding:
|
||||
;
|
||||
}
|
||||
}
|
||||
//if(!striEqualPrefix(buildSide->shaderInfo->shader, "textures/common/"))
|
||||
// fprintf(stderr, "brushside with %s: %d matches (%f area)\n", buildSide->shaderInfo->shader, matches, best);
|
||||
//if(!striEqualPrefix(buildSide.shaderInfo->shader, "textures/common/"))
|
||||
// fprintf(stderr, "brushside with %s: %d matches (%f area)\n", buildSide.shaderInfo->shader, matches, best);
|
||||
}
|
||||
|
||||
#define FRAC( x ) ( ( x ) - floor( x ) )
|
||||
|
|
@ -195,43 +194,26 @@ static void ConvertOriginBrush( FILE *f, int num, const Vector3& origin, bool br
|
|||
}
|
||||
|
||||
static void ConvertBrushFast( FILE *f, int num, bspBrush_t *brush, const Vector3& origin, bool brushPrimitives ){
|
||||
int i;
|
||||
bspBrushSide_t *side;
|
||||
side_t *buildSide;
|
||||
bspShader_t *shader;
|
||||
const char *texture;
|
||||
plane_t *buildPlane;
|
||||
Vector3 pts[ 3 ];
|
||||
|
||||
|
||||
/* clear out build brush */
|
||||
for ( i = 0; i < buildBrush->numsides; i++ )
|
||||
{
|
||||
buildSide = &buildBrush->sides[ i ];
|
||||
if ( buildSide->winding != NULL ) {
|
||||
FreeWinding( buildSide->winding );
|
||||
buildSide->winding = NULL;
|
||||
}
|
||||
}
|
||||
buildBrush->numsides = 0;
|
||||
buildBrush.sides.clear();
|
||||
|
||||
bool modelclip = false;
|
||||
/* try to guess if thats model clip */
|
||||
if ( force ){
|
||||
int notNoShader = 0;
|
||||
modelclip = true;
|
||||
for ( i = 0; i < brush->numSides; i++ )
|
||||
for ( int i = 0; i < brush->numSides; i++ )
|
||||
{
|
||||
/* get side */
|
||||
side = &bspBrushSides[ brush->firstSide + i ];
|
||||
const bspBrushSide_t& side = bspBrushSides[ brush->firstSide + i ];
|
||||
|
||||
/* get shader */
|
||||
if ( side->shaderNum < 0 || side->shaderNum >= numBSPShaders ) {
|
||||
if ( side.shaderNum < 0 || side.shaderNum >= numBSPShaders ) {
|
||||
continue;
|
||||
}
|
||||
shader = &bspShaders[ side->shaderNum ];
|
||||
const bspShader_t& shader = bspShaders[ side.shaderNum ];
|
||||
//"noshader" happens on modelclip and unwanted sides ( usually breaking complex brushes )
|
||||
if( !striEqual( shader->shader, "noshader" ) ){
|
||||
if( !striEqual( shader.shader, "noshader" ) ){
|
||||
notNoShader++;
|
||||
}
|
||||
if( notNoShader > 1 ){
|
||||
|
|
@ -242,28 +224,26 @@ static void ConvertBrushFast( FILE *f, int num, bspBrush_t *brush, const Vector3
|
|||
}
|
||||
|
||||
/* iterate through bsp brush sides */
|
||||
for ( i = 0; i < brush->numSides; i++ )
|
||||
for ( int i = 0; i < brush->numSides; i++ )
|
||||
{
|
||||
/* get side */
|
||||
side = &bspBrushSides[ brush->firstSide + i ];
|
||||
const bspBrushSide_t& side = bspBrushSides[ brush->firstSide + i ];
|
||||
|
||||
/* get shader */
|
||||
if ( side->shaderNum < 0 || side->shaderNum >= numBSPShaders ) {
|
||||
if ( side.shaderNum < 0 || side.shaderNum >= numBSPShaders ) {
|
||||
continue;
|
||||
}
|
||||
shader = &bspShaders[ side->shaderNum ];
|
||||
const bspShader_t& shader = bspShaders[ side.shaderNum ];
|
||||
//"noshader" happens on modelclip and unwanted sides ( usually breaking complex brushes )
|
||||
if( striEqual( shader->shader, "default" ) || ( striEqual( shader->shader, "noshader" ) && !modelclip ) )
|
||||
if( striEqual( shader.shader, "default" ) || ( striEqual( shader.shader, "noshader" ) && !modelclip ) )
|
||||
continue;
|
||||
|
||||
/* add build side */
|
||||
buildSide = &buildBrush->sides[ buildBrush->numsides ];
|
||||
buildBrush->numsides++;
|
||||
buildBrush.sides.emplace_back();
|
||||
|
||||
/* tag it */
|
||||
buildSide->shaderInfo = ShaderInfoForShader( shader->shader );
|
||||
buildSide->planenum = side->planeNum;
|
||||
buildSide->winding = NULL;
|
||||
buildBrush.sides.back().shaderInfo = ShaderInfoForShader( shader.shader );
|
||||
buildBrush.sides.back().planenum = side.planeNum;
|
||||
}
|
||||
|
||||
if ( !CreateBrushWindings( buildBrush ) ) {
|
||||
|
|
@ -280,31 +260,26 @@ static void ConvertBrushFast( FILE *f, int num, bspBrush_t *brush, const Vector3
|
|||
}
|
||||
|
||||
/* iterate through build brush sides */
|
||||
for ( i = 0; i < buildBrush->numsides; i++ )
|
||||
for ( side_t& buildSide : buildBrush.sides )
|
||||
{
|
||||
/* get build side */
|
||||
buildSide = &buildBrush->sides[ i ];
|
||||
|
||||
/* get plane */
|
||||
buildPlane = &mapplanes[ buildSide->planenum ];
|
||||
const plane_t& buildPlane = mapplanes[ buildSide.planenum ];
|
||||
|
||||
/* dummy check */
|
||||
if ( buildSide->shaderInfo == NULL || buildSide->winding == NULL ) {
|
||||
if ( buildSide.shaderInfo == NULL || buildSide.winding.empty() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* get texture name */
|
||||
if ( striEqualPrefix( buildSide->shaderInfo->shader, "textures/" ) ) {
|
||||
texture = buildSide->shaderInfo->shader + 9;
|
||||
}
|
||||
else{
|
||||
texture = buildSide->shaderInfo->shader;
|
||||
}
|
||||
const char *texture = striEqualPrefix( buildSide.shaderInfo->shader, "textures/" )
|
||||
? buildSide.shaderInfo->shader + 9
|
||||
: buildSide.shaderInfo->shader;
|
||||
|
||||
Vector3 pts[ 3 ];
|
||||
{
|
||||
Vector3 vecs[ 2 ];
|
||||
MakeNormalVectors( buildPlane->normal(), vecs[ 0 ], vecs[ 1 ] );
|
||||
pts[ 0 ] = buildPlane->normal() * buildPlane->dist() + origin;
|
||||
MakeNormalVectors( buildPlane.normal(), vecs[ 0 ], vecs[ 1 ] );
|
||||
pts[ 0 ] = buildPlane.normal() * buildPlane.dist() + origin;
|
||||
pts[ 1 ] = pts[ 0 ] + vecs[ 0 ] * 256.0f;
|
||||
pts[ 2 ] = pts[ 0 ] + vecs[ 1 ] * 256.0f;
|
||||
}
|
||||
|
|
@ -343,43 +318,26 @@ static void ConvertBrushFast( FILE *f, int num, bspBrush_t *brush, const Vector3
|
|||
}
|
||||
|
||||
static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, const Vector3& origin, bool brushPrimitives ){
|
||||
int i, j;
|
||||
bspBrushSide_t *side;
|
||||
side_t *buildSide;
|
||||
bspShader_t *shader;
|
||||
const char *texture;
|
||||
Vector3 pts[ 3 ];
|
||||
bspDrawVert_t *vert[3];
|
||||
|
||||
|
||||
/* clear out build brush */
|
||||
for ( i = 0; i < buildBrush->numsides; i++ )
|
||||
{
|
||||
buildSide = &buildBrush->sides[ i ];
|
||||
if ( buildSide->winding != NULL ) {
|
||||
FreeWinding( buildSide->winding );
|
||||
buildSide->winding = NULL;
|
||||
}
|
||||
}
|
||||
buildBrush->numsides = 0;
|
||||
buildBrush.sides.clear();
|
||||
|
||||
bool modelclip = false;
|
||||
/* try to guess if thats model clip */
|
||||
if ( force ){
|
||||
int notNoShader = 0;
|
||||
modelclip = true;
|
||||
for ( i = 0; i < brush->numSides; i++ )
|
||||
for ( int i = 0; i < brush->numSides; i++ )
|
||||
{
|
||||
/* get side */
|
||||
side = &bspBrushSides[ brush->firstSide + i ];
|
||||
const bspBrushSide_t& side = bspBrushSides[ brush->firstSide + i ];
|
||||
|
||||
/* get shader */
|
||||
if ( side->shaderNum < 0 || side->shaderNum >= numBSPShaders ) {
|
||||
if ( side.shaderNum < 0 || side.shaderNum >= numBSPShaders ) {
|
||||
continue;
|
||||
}
|
||||
shader = &bspShaders[ side->shaderNum ];
|
||||
const bspShader_t& shader = bspShaders[ side.shaderNum ];
|
||||
//"noshader" happens on modelclip and unwanted sides ( usually breaking complex brushes )
|
||||
if( !striEqual( shader->shader, "noshader" ) ){
|
||||
if( !striEqual( shader.shader, "noshader" ) ){
|
||||
notNoShader++;
|
||||
}
|
||||
if( notNoShader > 1 ){
|
||||
|
|
@ -390,28 +348,26 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, const Vector3& or
|
|||
}
|
||||
|
||||
/* iterate through bsp brush sides */
|
||||
for ( i = 0; i < brush->numSides; i++ )
|
||||
for ( int i = 0; i < brush->numSides; i++ )
|
||||
{
|
||||
/* get side */
|
||||
side = &bspBrushSides[ brush->firstSide + i ];
|
||||
const bspBrushSide_t& side = bspBrushSides[ brush->firstSide + i ];
|
||||
|
||||
/* get shader */
|
||||
if ( side->shaderNum < 0 || side->shaderNum >= numBSPShaders ) {
|
||||
if ( side.shaderNum < 0 || side.shaderNum >= numBSPShaders ) {
|
||||
continue;
|
||||
}
|
||||
shader = &bspShaders[ side->shaderNum ];
|
||||
const bspShader_t& shader = bspShaders[ side.shaderNum ];
|
||||
//"noshader" happens on modelclip and unwanted sides ( usually breaking complex brushes )
|
||||
if( striEqual( shader->shader, "default" ) || ( striEqual( shader->shader, "noshader" ) && !modelclip ) )
|
||||
if( striEqual( shader.shader, "default" ) || ( striEqual( shader.shader, "noshader" ) && !modelclip ) )
|
||||
continue;
|
||||
|
||||
/* add build side */
|
||||
buildSide = &buildBrush->sides[ buildBrush->numsides ];
|
||||
buildBrush->numsides++;
|
||||
buildBrush.sides.emplace_back();
|
||||
|
||||
/* tag it */
|
||||
buildSide->shaderInfo = ShaderInfoForShader( shader->shader );
|
||||
buildSide->planenum = side->planeNum;
|
||||
buildSide->winding = NULL;
|
||||
buildBrush.sides.back().shaderInfo = ShaderInfoForShader( shader.shader );
|
||||
buildBrush.sides.back().planenum = side.planeNum;
|
||||
}
|
||||
|
||||
/* make brush windings */
|
||||
|
|
@ -429,42 +385,38 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, const Vector3& or
|
|||
}
|
||||
|
||||
/* iterate through build brush sides */
|
||||
for ( i = 0; i < buildBrush->numsides; i++ )
|
||||
for ( side_t& buildSide : buildBrush.sides )
|
||||
{
|
||||
/* get build side */
|
||||
buildSide = &buildBrush->sides[ i ];
|
||||
|
||||
/* get plane */
|
||||
const plane_t& buildPlane = mapplanes[ buildSide->planenum ];
|
||||
const plane_t& buildPlane = mapplanes[ buildSide.planenum ];
|
||||
|
||||
/* dummy check */
|
||||
if ( buildSide->shaderInfo == NULL || buildSide->winding == NULL ) {
|
||||
if ( buildSide.shaderInfo == NULL || buildSide.winding.empty() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// st-texcoords -> texMat block
|
||||
// start out with dummy
|
||||
buildSide->texMat[0] = { 1 / 32.0, 0, 0 };
|
||||
buildSide->texMat[1] = { 0, 1 / 32.0, 0 };
|
||||
buildSide.texMat[0] = { 1 / 32.0, 0, 0 };
|
||||
buildSide.texMat[1] = { 0, 1 / 32.0, 0 };
|
||||
|
||||
// find surface for this side (by brute force)
|
||||
// surface format:
|
||||
// - meshverts point in pairs of three into verts
|
||||
// - (triangles)
|
||||
// - find the triangle that has most in common with our side
|
||||
// - find the triangle that has most in common with our
|
||||
bspDrawVert_t *vert[3];
|
||||
GetBestSurfaceTriangleMatchForBrushside( buildSide, vert );
|
||||
|
||||
/* get texture name */
|
||||
if ( striEqualPrefix( buildSide->shaderInfo->shader, "textures/" ) ) {
|
||||
texture = buildSide->shaderInfo->shader + 9;
|
||||
}
|
||||
else{
|
||||
texture = buildSide->shaderInfo->shader;
|
||||
}
|
||||
const char *texture = striEqualPrefix( buildSide.shaderInfo->shader, "textures/" )
|
||||
? buildSide.shaderInfo->shader + 9
|
||||
: buildSide.shaderInfo->shader;
|
||||
|
||||
Vector3 pts[ 3 ];
|
||||
/* recheck and fix winding points, fails occur somehow */
|
||||
int match = 0;
|
||||
for ( const Vector3& p : ( *buildSide->winding ) ){
|
||||
for ( const Vector3& p : buildSide.winding ){
|
||||
if ( fabs( plane3_distance_to_point( buildPlane.plane, p ) ) < distanceEpsilon ) {
|
||||
pts[ match ] = p;
|
||||
match++;
|
||||
|
|
@ -476,8 +428,7 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, const Vector3& or
|
|||
|
||||
if( match > 2 ){
|
||||
//Sys_Printf( "pointsKK " );
|
||||
Plane3f testplane;
|
||||
if ( PlaneFromPoints( testplane, pts ) ){
|
||||
if ( Plane3f testplane; PlaneFromPoints( testplane, pts ) ){
|
||||
if( !PlaneEqual( buildPlane, testplane ) ){
|
||||
//Sys_Printf( "1: %f %f %f %f\n2: %f %f %f %f\n", buildPlane->normal[0], buildPlane->normal[1], buildPlane->normal[2], buildPlane->dist, testplane[0], testplane[1], testplane[2], testplane[3] );
|
||||
match--;
|
||||
|
|
@ -493,8 +444,8 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, const Vector3& or
|
|||
if( match > 2 ){
|
||||
//Sys_Printf( "ok " );
|
||||
/* offset by origin */
|
||||
for ( j = 0; j < 3; j++ )
|
||||
pts[ j ] += origin;
|
||||
for ( Vector3& pt : pts )
|
||||
pt += origin;
|
||||
}
|
||||
else{
|
||||
Vector3 vecs[ 2 ];
|
||||
|
|
@ -552,7 +503,7 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, const Vector3& or
|
|||
xyJ[0], xyJ[1], stJ[i],
|
||||
xyK[0], xyK[1], stK[i]
|
||||
);
|
||||
buildSide->texMat[i] = { D0 / D, D1 / D, D2 / D };
|
||||
buildSide.texMat[i] = { D0 / D, D1 / D, D2 / D };
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
|
@ -572,8 +523,8 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, const Vector3& or
|
|||
pts[ 0 ][ 0 ], pts[ 0 ][ 1 ], pts[ 0 ][ 2 ],
|
||||
pts[ 1 ][ 0 ], pts[ 1 ][ 1 ], pts[ 1 ][ 2 ],
|
||||
pts[ 2 ][ 0 ], pts[ 2 ][ 1 ], pts[ 2 ][ 2 ],
|
||||
buildSide->texMat[0][0], buildSide->texMat[0][1], FRAC( buildSide->texMat[0][2] ),
|
||||
buildSide->texMat[1][0], buildSide->texMat[1][1], FRAC( buildSide->texMat[1][2] ),
|
||||
buildSide.texMat[0][0], buildSide.texMat[0][1], FRAC( buildSide.texMat[0][2] ),
|
||||
buildSide.texMat[1][0], buildSide.texMat[1][1], FRAC( buildSide.texMat[1][2] ),
|
||||
texture,
|
||||
0
|
||||
);
|
||||
|
|
@ -609,12 +560,12 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, const Vector3& or
|
|||
tv = 2;
|
||||
}
|
||||
|
||||
stI[0] = vert[0]->st[0] * buildSide->shaderInfo->shaderWidth;
|
||||
stI[1] = vert[0]->st[1] * buildSide->shaderInfo->shaderHeight;
|
||||
stJ[0] = vert[1]->st[0] * buildSide->shaderInfo->shaderWidth;
|
||||
stJ[1] = vert[1]->st[1] * buildSide->shaderInfo->shaderHeight;
|
||||
stK[0] = vert[2]->st[0] * buildSide->shaderInfo->shaderWidth;
|
||||
stK[1] = vert[2]->st[1] * buildSide->shaderInfo->shaderHeight;
|
||||
stI[0] = vert[0]->st[0] * buildSide.shaderInfo->shaderWidth;
|
||||
stI[1] = vert[0]->st[1] * buildSide.shaderInfo->shaderHeight;
|
||||
stJ[0] = vert[1]->st[0] * buildSide.shaderInfo->shaderWidth;
|
||||
stJ[1] = vert[1]->st[1] * buildSide.shaderInfo->shaderHeight;
|
||||
stK[0] = vert[2]->st[0] * buildSide.shaderInfo->shaderWidth;
|
||||
stK[1] = vert[2]->st[1] * buildSide.shaderInfo->shaderHeight;
|
||||
|
||||
D = Det3x3(
|
||||
vert[0]->xyz[sv], vert[0]->xyz[tv], 1,
|
||||
|
|
@ -664,8 +615,8 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, const Vector3& or
|
|||
scale[0] = 1.0 / sqrt( sts[0][0] * sts[0][0] + sts[0][1] * sts[0][1] );
|
||||
scale[1] = 1.0 / sqrt( sts[1][0] * sts[1][0] + sts[1][1] * sts[1][1] );
|
||||
rotate = radians_to_degrees( atan2( sts[0][1] * vecs[0][sv] - sts[1][0] * vecs[1][tv], sts[0][0] * vecs[0][sv] + sts[1][1] * vecs[1][tv] ) );
|
||||
shift[0] = buildSide->shaderInfo->shaderWidth * FRAC( sts[0][2] / buildSide->shaderInfo->shaderWidth );
|
||||
shift[1] = buildSide->shaderInfo->shaderHeight * FRAC( sts[1][2] / buildSide->shaderInfo->shaderHeight );
|
||||
shift[0] = buildSide.shaderInfo->shaderWidth * FRAC( sts[0][2] / buildSide.shaderInfo->shaderWidth );
|
||||
shift[1] = buildSide.shaderInfo->shaderHeight * FRAC( sts[1][2] / buildSide.shaderInfo->shaderHeight );
|
||||
|
||||
/* print brush side */
|
||||
/* ( 640 24 -224 ) ( 448 24 -224 ) ( 448 -232 -224 ) common/caulk 0 48 0 0.500000 0.500000 0 0 0 */
|
||||
|
|
@ -681,11 +632,11 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, const Vector3& or
|
|||
}
|
||||
else
|
||||
{
|
||||
if ( !striEqualPrefix( buildSide->shaderInfo->shader, "textures/common/" )
|
||||
&& !striEqualPrefix( buildSide->shaderInfo->shader, "textures/system/" )
|
||||
&& !strEqual( buildSide->shaderInfo->shader, "noshader" )
|
||||
&& !strEqual( buildSide->shaderInfo->shader, "default" ) ) {
|
||||
//fprintf( stderr, "no matching triangle for brushside using %s (hopefully nobody can see this side anyway)\n", buildSide->shaderInfo->shader );
|
||||
if ( !striEqualPrefix( buildSide.shaderInfo->shader, "textures/common/" )
|
||||
&& !striEqualPrefix( buildSide.shaderInfo->shader, "textures/system/" )
|
||||
&& !strEqual( buildSide.shaderInfo->shader, "noshader" )
|
||||
&& !strEqual( buildSide.shaderInfo->shader, "default" ) ) {
|
||||
//fprintf( stderr, "no matching triangle for brushside using %s (hopefully nobody can see this side anyway)\n", buildSide.shaderInfo->shader );
|
||||
texture = "common/WTF";
|
||||
}
|
||||
|
||||
|
|
@ -882,9 +833,9 @@ static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, const Vector
|
|||
}
|
||||
|
||||
/* allocate a build brush */
|
||||
buildBrush = AllocBrush( 512 );
|
||||
buildBrush->entityNum = 0;
|
||||
buildBrush->original = buildBrush;
|
||||
buildBrush.sides.reserve( MAX_BUILD_SIDES );
|
||||
buildBrush.entityNum = 0;
|
||||
buildBrush.original = &buildBrush;
|
||||
|
||||
if ( origin != g_vector3_identity ) {
|
||||
ConvertOriginBrush( f, -1, origin, brushPrimitives );
|
||||
|
|
@ -903,9 +854,6 @@ static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, const Vector
|
|||
}
|
||||
}
|
||||
|
||||
/* free the build brush */
|
||||
free( buildBrush );
|
||||
|
||||
/* go through each drawsurf in the model */
|
||||
for ( i = 0; i < model->numBSPSurfaces; i++ )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -493,33 +493,29 @@ void ProcessDecals( void ){
|
|||
projects a decal onto a winding
|
||||
*/
|
||||
|
||||
static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds, winding_t *w ){
|
||||
static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds, winding_t& w ){
|
||||
int i, j;
|
||||
winding_t *front, *back;
|
||||
mapDrawSurface_t *ds2;
|
||||
bspDrawVert_t *dv;
|
||||
Plane3f plane;
|
||||
|
||||
|
||||
/* dummy check */
|
||||
if ( w->size() < 3 ) {
|
||||
FreeWinding( w );
|
||||
if ( w.size() < 3 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* offset by entity origin */
|
||||
for ( Vector3& p : *w )
|
||||
for ( Vector3& p : w )
|
||||
p += entityOrigin;
|
||||
|
||||
/* make a plane from the winding */
|
||||
if ( !PlaneFromPoints( plane, w->data() ) ) {
|
||||
FreeWinding( w );
|
||||
if ( !PlaneFromPoints( plane, w.data() ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* backface check */
|
||||
if ( vector3_dot( dp->planes[ 0 ].normal(), plane.normal() ) < -0.0001f ) {
|
||||
FreeWinding( w );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -527,25 +523,20 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
|
|||
for ( i = 0; i < dp->numPlanes; i++ )
|
||||
{
|
||||
/* 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 */
|
||||
FreeWinding( w );
|
||||
auto [front, back] = ClipWindingEpsilonStrict( w, dp->planes[ i ], 0.0625f ); /* strict, if identical plane we don't want to keep it */
|
||||
|
||||
/* lose the front fragment */
|
||||
if ( front != NULL ) {
|
||||
FreeWinding( front );
|
||||
}
|
||||
|
||||
/* if nothing left in back, then bail */
|
||||
if ( back == NULL ) {
|
||||
if ( back.empty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* reset winding */
|
||||
w = back;
|
||||
w.swap( back );
|
||||
}
|
||||
|
||||
/* nothing left? */
|
||||
if ( w == NULL || w->size() < 3 ) {
|
||||
if ( w.size() < 3 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -563,7 +554,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
|
|||
ds2->fogNum = ds->fogNum; /* why was this -1? */
|
||||
ds2->lightmapScale = ds->lightmapScale;
|
||||
ds2->shadeAngleDegrees = ds->shadeAngleDegrees;
|
||||
ds2->numVerts = w->size();
|
||||
ds2->numVerts = w.size();
|
||||
ds2->verts = safe_calloc( ds2->numVerts * sizeof( *ds2->verts ) );
|
||||
|
||||
/* set vertexes */
|
||||
|
|
@ -573,12 +564,12 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
|
|||
dv = &ds2->verts[ i ];
|
||||
|
||||
/* set alpha */
|
||||
const float d = plane3_distance_to_point( dp->planes[ 0 ], ( *w )[ i ] );
|
||||
const float d2 = plane3_distance_to_point( dp->planes[ 1 ], ( *w )[ i ] );
|
||||
const float d = plane3_distance_to_point( dp->planes[ 0 ], w[ i ] );
|
||||
const float d2 = plane3_distance_to_point( dp->planes[ 1 ], w[ i ] );
|
||||
const float alpha = 255.0f * d2 / ( d + d2 );
|
||||
|
||||
/* set misc */
|
||||
dv->xyz = ( *w )[ i ] - entityOrigin;
|
||||
dv->xyz = w[ i ] - entityOrigin;
|
||||
dv->normal = plane.normal();
|
||||
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 ];
|
||||
|
|
@ -614,7 +605,7 @@ static void ProjectDecalOntoFace( decalProjector_t *dp, mapDrawSurface_t *ds ){
|
|||
}
|
||||
|
||||
/* generate decal */
|
||||
winding_t *w = WindingFromDrawSurf( ds );
|
||||
winding_t w = WindingFromDrawSurf( ds );
|
||||
ProjectDecalOntoWinding( dp, ds, w );
|
||||
}
|
||||
|
||||
|
|
@ -628,7 +619,6 @@ static void ProjectDecalOntoFace( decalProjector_t *dp, mapDrawSurface_t *ds ){
|
|||
static void ProjectDecalOntoPatch( decalProjector_t *dp, mapDrawSurface_t *ds ){
|
||||
int x, y, pw[ 5 ], r, iterations;
|
||||
mesh_t src, *mesh, *subdivided;
|
||||
winding_t *w;
|
||||
|
||||
|
||||
/* backface check */
|
||||
|
|
@ -668,18 +658,18 @@ static void ProjectDecalOntoPatch( decalProjector_t *dp, mapDrawSurface_t *ds ){
|
|||
r = ( x + y ) & 1;
|
||||
|
||||
/* generate decal for first triangle */
|
||||
w = AllocWinding( 3 );
|
||||
w->push_back( mesh->verts[ pw[ r + 0 ] ].xyz );
|
||||
w->push_back( mesh->verts[ pw[ r + 1 ] ].xyz );
|
||||
w->push_back( mesh->verts[ pw[ r + 2 ] ].xyz );
|
||||
winding_t w{
|
||||
mesh->verts[ pw[ r + 0 ] ].xyz,
|
||||
mesh->verts[ pw[ r + 1 ] ].xyz,
|
||||
mesh->verts[ pw[ r + 2 ] ].xyz };
|
||||
ProjectDecalOntoWinding( dp, ds, w );
|
||||
|
||||
/* generate decal for second triangle */
|
||||
w = AllocWinding( 3 );
|
||||
w->push_back( mesh->verts[ pw[ r + 0 ] ].xyz );
|
||||
w->push_back( mesh->verts[ pw[ r + 2 ] ].xyz );
|
||||
w->push_back( mesh->verts[ pw[ r + 3 ] ].xyz );
|
||||
ProjectDecalOntoWinding( dp, ds, w );
|
||||
winding_t w2{
|
||||
mesh->verts[ pw[ r + 0 ] ].xyz,
|
||||
mesh->verts[ pw[ r + 2 ] ].xyz,
|
||||
mesh->verts[ pw[ r + 3 ] ].xyz };
|
||||
ProjectDecalOntoWinding( dp, ds, w2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -714,10 +704,10 @@ static void ProjectDecalOntoTriangles( decalProjector_t *dp, mapDrawSurface_t *d
|
|||
for ( int i = 0; i < ds->numIndexes; i += 3 )
|
||||
{
|
||||
/* generate decal */
|
||||
winding_t *w = AllocWinding( 3 );
|
||||
w->push_back( ds->verts[ ds->indexes[ i ] ].xyz );
|
||||
w->push_back( ds->verts[ ds->indexes[ i + 1 ] ].xyz );
|
||||
w->push_back( ds->verts[ ds->indexes[ i + 2 ] ].xyz );
|
||||
winding_t w{
|
||||
ds->verts[ ds->indexes[ i ] ].xyz,
|
||||
ds->verts[ ds->indexes[ i + 1 ] ].xyz,
|
||||
ds->verts[ ds->indexes[ i + 2 ] ].xyz };
|
||||
ProjectDecalOntoWinding( dp, ds, w );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ int c_faceLeafs;
|
|||
finds the best split plane for this node
|
||||
*/
|
||||
|
||||
static void SelectSplitPlaneNum( node_t *node, const facelist_t& list, int *splitPlaneNum, int *compileFlags ){
|
||||
static void SelectSplitPlaneNum( const node_t *node, const facelist_t& list, int *splitPlaneNum, int *compileFlags ){
|
||||
//int frontC,backC,splitsC,facingC;
|
||||
|
||||
|
||||
|
|
@ -217,21 +217,17 @@ void BuildFaceTree_r( node_t *node, facelist_t& list ){
|
|||
|
||||
/* switch on side */
|
||||
if ( side == eSideCross ) {
|
||||
winding_t *frontWinding, *backWinding;
|
||||
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 */
|
||||
if ( frontWinding ) {
|
||||
auto [frontWinding, backWinding] = ClipWindingEpsilonStrict( split.w, plane.plane, CLIP_EPSILON * 2 ); /* strict; if no winding is left, we have a "virtually identical" plane and don't want to split by it */
|
||||
if ( !frontWinding.empty() ) {
|
||||
face_t& newFace = childLists[0].emplace_front();
|
||||
newFace.w.swap( *frontWinding );
|
||||
FreeWinding( frontWinding );
|
||||
newFace.w.swap( frontWinding );
|
||||
newFace.planenum = split.planenum;
|
||||
newFace.priority = split.priority;
|
||||
newFace.compileFlags = split.compileFlags;
|
||||
}
|
||||
if ( backWinding ) {
|
||||
if ( !backWinding.empty() ) {
|
||||
face_t& newFace = childLists[1].emplace_front();
|
||||
newFace.w.swap( *backWinding );
|
||||
FreeWinding( backWinding );
|
||||
newFace.w.swap( backWinding );
|
||||
newFace.planenum = split.planenum;
|
||||
newFace.priority = split.priority;
|
||||
newFace.compileFlags = split.compileFlags;
|
||||
|
|
@ -299,15 +295,15 @@ void BuildFaceTree_r( node_t *node, facelist_t& list ){
|
|||
List will be freed before returning
|
||||
================
|
||||
*/
|
||||
tree_t *FaceBSP( facelist_t& list ) {
|
||||
tree_t FaceBSP( facelist_t& list ) {
|
||||
Sys_FPrintf( SYS_VRB, "--- FaceBSP ---\n" );
|
||||
|
||||
tree_t *tree = AllocTree();
|
||||
tree_t tree{};
|
||||
|
||||
int count = 0;
|
||||
for ( const face_t& face : list )
|
||||
{
|
||||
WindingExtendBounds( face.w, tree->minmax );
|
||||
WindingExtendBounds( face.w, tree.minmax );
|
||||
count++;
|
||||
}
|
||||
Sys_FPrintf( SYS_VRB, "%9d faces\n", count );
|
||||
|
|
@ -317,11 +313,11 @@ tree_t *FaceBSP( facelist_t& list ) {
|
|||
plane.counter = 0;
|
||||
}
|
||||
|
||||
tree->headnode = AllocNode();
|
||||
tree->headnode->minmax = tree->minmax;
|
||||
tree.headnode = AllocNode();
|
||||
tree.headnode->minmax = tree.minmax;
|
||||
c_faceLeafs = 0;
|
||||
|
||||
BuildFaceTree_r( tree->headnode, list );
|
||||
BuildFaceTree_r( tree.headnode, list );
|
||||
|
||||
Sys_FPrintf( SYS_VRB, "%9d leafs\n", c_faceLeafs );
|
||||
|
||||
|
|
@ -335,21 +331,20 @@ tree_t *FaceBSP( facelist_t& list ) {
|
|||
get structural brush faces
|
||||
*/
|
||||
|
||||
facelist_t MakeStructuralBSPFaceList( const brush_t *list ){
|
||||
facelist_t MakeStructuralBSPFaceList( const brushlist_t& list ){
|
||||
facelist_t flist;
|
||||
|
||||
for ( const brush_t *b = list; b != NULL; b = b->next )
|
||||
for ( const brush_t &b : list )
|
||||
{
|
||||
if ( !deepBSP && b->detail ) {
|
||||
if ( !deepBSP && b.detail ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < b->numsides; i++ )
|
||||
for ( const side_t& s : b.sides )
|
||||
{
|
||||
/* get side and winding */
|
||||
const side_t& s = b->sides[ i ];
|
||||
const winding_t *w = s.winding;
|
||||
if ( w == NULL ) {
|
||||
/* get winding */
|
||||
const winding_t& w = s.winding;
|
||||
if ( w.empty() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -360,10 +355,10 @@ facelist_t MakeStructuralBSPFaceList( const brush_t *list ){
|
|||
|
||||
/* allocate a face */
|
||||
face_t& f = flist.emplace_front();
|
||||
f.w = *w;
|
||||
f.w = w;
|
||||
f.planenum = s.planenum & ~1;
|
||||
f.compileFlags = s.compileFlags; /* ydnar */
|
||||
if ( b->detail ) {
|
||||
if ( b.detail ) {
|
||||
f.compileFlags |= C_DETAIL;
|
||||
}
|
||||
|
||||
|
|
@ -394,21 +389,20 @@ facelist_t MakeStructuralBSPFaceList( const brush_t *list ){
|
|||
get visible brush faces
|
||||
*/
|
||||
|
||||
facelist_t MakeVisibleBSPFaceList( const brush_t *list ){
|
||||
facelist_t MakeVisibleBSPFaceList( const brushlist_t& list ){
|
||||
facelist_t flist;
|
||||
|
||||
for ( const brush_t *b = list; b != NULL; b = b->next )
|
||||
for ( const brush_t& b : list )
|
||||
{
|
||||
if ( !deepBSP && b->detail ) {
|
||||
if ( !deepBSP && b.detail ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < b->numsides; i++ )
|
||||
for ( const side_t& s : b.sides )
|
||||
{
|
||||
/* get side and winding */
|
||||
const side_t& s = b->sides[ i ];
|
||||
const winding_t *w = s.visibleHull;
|
||||
if ( w == NULL ) {
|
||||
/* get winding */
|
||||
const winding_t& w = s.visibleHull;
|
||||
if ( w.empty() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -419,10 +413,10 @@ facelist_t MakeVisibleBSPFaceList( const brush_t *list ){
|
|||
|
||||
/* allocate a face */
|
||||
face_t& f = flist.emplace_front();
|
||||
f.w = *w;
|
||||
f.w = w;
|
||||
f.planenum = s.planenum & ~1;
|
||||
f.compileFlags = s.compileFlags; /* ydnar */
|
||||
if ( b->detail ) {
|
||||
if ( b.detail ) {
|
||||
f.compileFlags |= C_DETAIL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -244,9 +244,8 @@ void SplitMeshByPlane( mesh_t *in, const Plane3f& plane, mesh_t **front, mesh_t
|
|||
chops a patch up by a fog brush
|
||||
*/
|
||||
|
||||
bool ChopPatchSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
|
||||
bool ChopPatchSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, const brush_t *b ){
|
||||
int i, j;
|
||||
side_t *s;
|
||||
mesh_t *outside[MAX_BRUSH_SIDES];
|
||||
int numOutside;
|
||||
mesh_t *m, *front, *back;
|
||||
|
|
@ -259,8 +258,7 @@ bool ChopPatchSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
|
|||
// some messy patch clipping issues
|
||||
|
||||
for ( i = 4 ; i <= 5 ; i++ ) {
|
||||
s = &b->sides[ i ];
|
||||
const plane_t& plane = mapplanes[ s->planenum ];
|
||||
const plane_t& plane = mapplanes[ b->sides[ i ].planenum ];
|
||||
|
||||
SplitMeshByPlane( m, plane.plane, &front, &back );
|
||||
|
||||
|
|
@ -331,26 +329,23 @@ bool ChopPatchSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
|
|||
creates a winding from a surface's verts
|
||||
*/
|
||||
|
||||
winding_t *WindingFromDrawSurf( mapDrawSurface_t *ds ){
|
||||
winding_t *w;
|
||||
int i;
|
||||
|
||||
winding_t WindingFromDrawSurf( const mapDrawSurface_t *ds ){
|
||||
// we use the first point of the surface, maybe something more clever would be useful
|
||||
// (actually send the whole draw surface would be cool?)
|
||||
if ( ds->numVerts >= MAX_POINTS_ON_WINDING ) {
|
||||
const int max = std::min( ds->numVerts, 256 );
|
||||
Vector3 p[256];
|
||||
|
||||
for ( i = 0; i < max; i++ ) {
|
||||
for ( int i = 0; i < max; i++ ) {
|
||||
p[i] = ds->verts[i].xyz;
|
||||
}
|
||||
|
||||
xml_Winding( "WindingFromDrawSurf failed: MAX_POINTS_ON_WINDING exceeded", p, max, true );
|
||||
}
|
||||
|
||||
w = AllocWinding( ds->numVerts );
|
||||
for ( i = 0; i < ds->numVerts; i++ ) {
|
||||
w->push_back( ds->verts[i].xyz );
|
||||
winding_t w = AllocWinding( ds->numVerts );
|
||||
for ( int i = 0; i < ds->numVerts; i++ ) {
|
||||
w.push_back( ds->verts[i].xyz );
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
|
@ -362,13 +357,8 @@ winding_t *WindingFromDrawSurf( mapDrawSurface_t *ds ){
|
|||
chops up a face drawsurface by a fog brush, with a potential fragment left inside
|
||||
*/
|
||||
|
||||
bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
|
||||
int i, j;
|
||||
side_t *s;
|
||||
winding_t *w;
|
||||
winding_t *front, *back;
|
||||
winding_t *outside[ MAX_BRUSH_SIDES ];
|
||||
int numOutside;
|
||||
bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, const brush_t *b ){
|
||||
std::list<winding_t> outside;
|
||||
mapDrawSurface_t *newds;
|
||||
|
||||
|
||||
|
|
@ -378,58 +368,51 @@ bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
|
|||
}
|
||||
|
||||
/* initial setup */
|
||||
w = WindingFromDrawSurf( ds );
|
||||
numOutside = 0;
|
||||
winding_t w = WindingFromDrawSurf( ds );
|
||||
|
||||
/* chop by each brush side */
|
||||
for ( i = 0; i < b->numsides; i++ )
|
||||
for ( const side_t& side : b->sides )
|
||||
{
|
||||
/* get brush side and plane */
|
||||
s = &b->sides[ i ];
|
||||
const plane_t& plane = mapplanes[ s->planenum ];
|
||||
/* get brush plane */
|
||||
const plane_t& plane = mapplanes[ side.planenum ];
|
||||
|
||||
/* handle coplanar outfacing (don't fog) */
|
||||
if ( ds->sideRef->side->planenum == s->planenum ) {
|
||||
if ( ds->sideRef->side->planenum == side.planenum ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* handle coplanar infacing (keep inside) */
|
||||
if ( ( ds->sideRef->side->planenum ^ 1 ) == s->planenum ) {
|
||||
if ( ( ds->sideRef->side->planenum ^ 1 ) == side.planenum ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
FreeWinding( w );
|
||||
auto [front, back] = ClipWindingEpsilonStrict( w, plane.plane, ON_EPSILON ); /* strict; if plane is "almost identical" to face, both ways to continue can be wrong, so we better not fog it */
|
||||
|
||||
if ( back == NULL ) {
|
||||
if ( back.empty() ) {
|
||||
/* nothing actually contained inside */
|
||||
for ( j = 0; j < numOutside; j++ )
|
||||
FreeWinding( outside[ j ] );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( front != NULL ) {
|
||||
if ( numOutside == MAX_BRUSH_SIDES ) {
|
||||
if ( !front.empty() ) {
|
||||
if ( outside.size() == MAX_BRUSH_SIDES ) {
|
||||
Error( "MAX_BRUSH_SIDES" );
|
||||
}
|
||||
outside[ numOutside ] = front;
|
||||
numOutside++;
|
||||
outside.push_back( std::move( front ) );
|
||||
}
|
||||
|
||||
w = back;
|
||||
w.swap( back );
|
||||
}
|
||||
|
||||
/* fixme: celshaded surface fragment errata */
|
||||
|
||||
/* all of outside fragments become separate drawsurfs */
|
||||
numFogFragments += numOutside;
|
||||
s = ds->sideRef->side;
|
||||
for ( i = 0; i < numOutside; i++ )
|
||||
numFogFragments += outside.size();
|
||||
const side_t *s = ds->sideRef->side;
|
||||
for ( const winding_t& wi : outside )
|
||||
{
|
||||
newds = DrawSurfaceForSide( e, ds->mapBrush, s, *outside[ i ] );
|
||||
newds = DrawSurfaceForSide( e, *ds->mapBrush, *s, wi );
|
||||
newds->fogNum = ds->fogNum;
|
||||
FreeWinding( outside[ i ] );
|
||||
}
|
||||
|
||||
/* ydnar: the old code neglected to snap to 0.125 for the fragment
|
||||
|
|
@ -437,7 +420,7 @@ bool ChopFaceSurfaceByBrush( entity_t *e, mapDrawSurface_t *ds, brush_t *b ){
|
|||
the right thing and uses the original surface's brush side */
|
||||
|
||||
/* build a drawsurf for it */
|
||||
newds = DrawSurfaceForSide( e, ds->mapBrush, s, *w );
|
||||
newds = DrawSurfaceForSide( e, *ds->mapBrush, *s, w );
|
||||
if ( newds == NULL ) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -562,16 +545,11 @@ void FogDrawSurfaces( entity_t *e ){
|
|||
*/
|
||||
|
||||
int FogForPoint( const Vector3& point, float epsilon ){
|
||||
int fogNum, i, j;
|
||||
bool inside;
|
||||
brush_t *brush;
|
||||
|
||||
|
||||
/* start with bogus fog num */
|
||||
fogNum = defaultFogNum;
|
||||
int fogNum = defaultFogNum;
|
||||
|
||||
/* walk the list of fog volumes */
|
||||
for ( i = 0; i < numMapFogs; i++ )
|
||||
for ( int i = 0; i < numMapFogs; i++ )
|
||||
{
|
||||
/* sof2: global fog doesn't reference a brush */
|
||||
if ( mapFogs[ i ].brush == NULL ) {
|
||||
|
|
@ -579,15 +557,13 @@ int FogForPoint( const Vector3& point, float epsilon ){
|
|||
continue;
|
||||
}
|
||||
|
||||
/* get fog brush */
|
||||
brush = mapFogs[ i ].brush;
|
||||
|
||||
/* check point against all planes */
|
||||
inside = true;
|
||||
for ( j = 0; j < brush->numsides && inside; j++ )
|
||||
bool inside = true;
|
||||
for ( const side_t& side : mapFogs[ i ].brush->sides )
|
||||
{
|
||||
if ( plane3_distance_to_point( mapplanes[ brush->sides[ j ].planenum ].plane, point ) > epsilon ) {
|
||||
if ( plane3_distance_to_point( mapplanes[ side.planenum ].plane, point ) > epsilon ) {
|
||||
inside = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -628,7 +604,7 @@ int FogForBounds( const MinMax& minmax, float epsilon ){
|
|||
}
|
||||
|
||||
/* get fog brush */
|
||||
brush_t *brush = mapFogs[ i ].brush;
|
||||
const brush_t *brush = mapFogs[ i ].brush;
|
||||
|
||||
/* get bounds */
|
||||
const MinMax fogMinmax( brush->minmax.mins - Vector3( epsilon ),
|
||||
|
|
@ -663,11 +639,6 @@ int FogForBounds( const MinMax& minmax, float epsilon ){
|
|||
*/
|
||||
|
||||
void CreateMapFogs( void ){
|
||||
int j;
|
||||
brush_t *brush;
|
||||
fog_t *fog;
|
||||
|
||||
|
||||
/* skip? */
|
||||
if ( nofog ) {
|
||||
return;
|
||||
|
|
@ -680,10 +651,10 @@ void CreateMapFogs( void ){
|
|||
for ( const auto& e : entities )
|
||||
{
|
||||
/* walk entity brushes */
|
||||
for ( brush = e.brushes; brush != NULL; brush = brush->next )
|
||||
for ( const brush_t& brush : e.brushes )
|
||||
{
|
||||
/* ignore non-fog brushes */
|
||||
if ( !brush->contentShader->fogParms ) {
|
||||
if ( !brush.contentShader->fogParms ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -693,21 +664,21 @@ void CreateMapFogs( void ){
|
|||
}
|
||||
|
||||
/* set up fog */
|
||||
fog = &mapFogs[ numMapFogs++ ];
|
||||
fog->si = brush->contentShader;
|
||||
fog->brush = brush;
|
||||
fog->visibleSide = -1;
|
||||
fog_t& fog = mapFogs[ numMapFogs++ ];
|
||||
fog.si = brush.contentShader;
|
||||
fog.brush = &brush;
|
||||
fog.visibleSide = -1;
|
||||
|
||||
/* if shader specifies an explicit direction, then find a matching brush side with an opposed normal */
|
||||
if ( vector3_length( fog->si->fogDir ) ) {
|
||||
if ( vector3_length( fog.si->fogDir ) ) {
|
||||
/* flip it */
|
||||
const Vector3 invFogDir = -fog->si->fogDir;
|
||||
const Vector3 invFogDir = -fog.si->fogDir;
|
||||
|
||||
/* find the brush side */
|
||||
for ( j = 0; j < brush->numsides; j++ )
|
||||
for ( size_t j = 0; j < brush.sides.size(); ++j )
|
||||
{
|
||||
if ( VectorCompare( invFogDir, mapplanes[ brush->sides[ j ].planenum ].normal() ) ) {
|
||||
fog->visibleSide = j;
|
||||
if ( VectorCompare( invFogDir, mapplanes[ brush.sides[ j ].planenum ].normal() ) ) {
|
||||
fog.visibleSide = j;
|
||||
//% Sys_Printf( "Brush num: %d Side num: %d\n", fog->brushNum, fog->visibleSide );
|
||||
break;
|
||||
}
|
||||
|
|
@ -728,20 +699,20 @@ void CreateMapFogs( void ){
|
|||
Sys_FPrintf( SYS_VRB, "Map has global fog shader %s\n", globalFog );
|
||||
|
||||
/* set up fog */
|
||||
fog = &mapFogs[ numMapFogs++ ];
|
||||
fog->si = ShaderInfoForShaderNull( globalFog );
|
||||
if ( fog->si == NULL ) {
|
||||
fog_t& fog = mapFogs[ numMapFogs++ ];
|
||||
fog.si = ShaderInfoForShaderNull( globalFog );
|
||||
if ( fog.si == NULL ) {
|
||||
Error( "Invalid shader \"%s\" referenced trying to add global fog", globalFog );
|
||||
}
|
||||
fog->brush = NULL;
|
||||
fog->visibleSide = -1;
|
||||
fog.brush = NULL;
|
||||
fog.visibleSide = -1;
|
||||
|
||||
/* set as default fog */
|
||||
defaultFogNum = numMapFogs - 1;
|
||||
|
||||
/* mark all worldspawn brushes as fogged */
|
||||
for ( brush = entities[ 0 ].brushes; brush != NULL; brush = brush->next )
|
||||
ApplySurfaceParm( "fog", &brush->contentFlags, NULL, &brush->compileFlags );
|
||||
for ( brush_t& brush : entities[ 0 ].brushes )
|
||||
ApplySurfaceParm( "fog", &brush.contentFlags, NULL, &brush.compileFlags );
|
||||
}
|
||||
|
||||
/* emit some stats */
|
||||
|
|
|
|||
|
|
@ -54,14 +54,14 @@
|
|||
TTimo: builds a polyline xml node
|
||||
=============
|
||||
*/
|
||||
xmlNodePtr LeakFile( tree_t *tree ){
|
||||
xmlNodePtr LeakFile( const tree_t& tree ){
|
||||
Vector3 mid;
|
||||
FILE *linefile;
|
||||
node_t *node;
|
||||
const node_t *node;
|
||||
int count;
|
||||
xmlNodePtr xml_node, point;
|
||||
|
||||
if ( !tree->outside_node.occupied ) {
|
||||
if ( !tree.outside_node.occupied ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -76,12 +76,12 @@ xmlNodePtr LeakFile( tree_t *tree ){
|
|||
xml_node = xmlNewNode( NULL, (const xmlChar*)"polyline" );
|
||||
|
||||
count = 0;
|
||||
node = &tree->outside_node;
|
||||
node = &tree.outside_node;
|
||||
while ( node->occupied > 1 )
|
||||
{
|
||||
int next;
|
||||
portal_t *p, *nextportal = NULL;
|
||||
node_t *nextnode = NULL;
|
||||
const portal_t *p, *nextportal = NULL;
|
||||
const node_t *nextnode = NULL;
|
||||
int s;
|
||||
|
||||
// find the best portal exit
|
||||
|
|
@ -97,7 +97,7 @@ xmlNodePtr LeakFile( tree_t *tree ){
|
|||
}
|
||||
}
|
||||
node = nextnode;
|
||||
mid = WindingCenter( *nextportal->winding );
|
||||
mid = WindingCenter( nextportal->winding );
|
||||
fprintf( linefile, "%f %f %f\n", mid[0], mid[1], mid[2] );
|
||||
point = xml_NodeForVec( mid );
|
||||
xmlAddChild( xml_node, point );
|
||||
|
|
|
|||
|
|
@ -468,7 +468,7 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
|
|||
light.si = si;
|
||||
light.fade = 1.0f;
|
||||
/* create a regular winding */
|
||||
light.w = AllocWinding_( rw->numVerts );
|
||||
light.w = AllocWinding( rw->numVerts );
|
||||
for ( i = 0; i < rw->numVerts; i++ )
|
||||
{
|
||||
light.w.push_back( rw->verts[ i ].xyz );
|
||||
|
|
@ -548,7 +548,7 @@ static void RadSubdivideDiffuseLight( int lightmapNum, bspDrawSurface_t *ds, raw
|
|||
}
|
||||
|
||||
/* create a regular winding */
|
||||
splash.w = AllocWinding_( rw->numVerts );
|
||||
splash.w = AllocWinding( rw->numVerts );
|
||||
for ( i = 0; i < rw->numVerts; i++ )
|
||||
splash.w.push_back( rw->verts[rw->numVerts - 1 - i].xyz + normal * si->backsplashDistance );
|
||||
|
||||
|
|
|
|||
|
|
@ -457,25 +457,20 @@ int MapPlaneFromPoints( DoubleVector3 p[3] ){
|
|||
the content flags and compile flags on all sides of a brush should be the same
|
||||
*/
|
||||
|
||||
void SetBrushContents( brush_t *b ){
|
||||
int contentFlags, compileFlags;
|
||||
side_t *s;
|
||||
int i;
|
||||
//% bool mixed;
|
||||
|
||||
void SetBrushContents( brush_t& b ){
|
||||
if( b.sides.empty() )
|
||||
return;
|
||||
|
||||
//% bool mixed = false;
|
||||
/* get initial compile flags from first side */
|
||||
s = &b->sides[ 0 ];
|
||||
contentFlags = s->contentFlags;
|
||||
compileFlags = s->compileFlags;
|
||||
b->contentShader = s->shaderInfo;
|
||||
//% mixed = false;
|
||||
auto s = b.sides.cbegin();
|
||||
int contentFlags = s->contentFlags;
|
||||
int compileFlags = s->compileFlags;
|
||||
b.contentShader = s->shaderInfo;
|
||||
|
||||
/* get the content/compile flags for every side in the brush */
|
||||
//for ( i = 1; i < b->numsides; i++, s++ )
|
||||
for ( i = 1; i < b->numsides; i++ )
|
||||
for ( ++s; s != b.sides.cend(); ++s )
|
||||
{
|
||||
s = &b->sides[ i ];
|
||||
if ( s->shaderInfo == NULL ) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -486,36 +481,36 @@ void SetBrushContents( brush_t *b ){
|
|||
compileFlags |= s->compileFlags;
|
||||
|
||||
/* resolve inconsistency, when brush content was determined by 1st face */
|
||||
if ( b->contentShader->compileFlags & C_LIQUID ){
|
||||
if ( b.contentShader->compileFlags & C_LIQUID ){
|
||||
continue;
|
||||
}
|
||||
else if ( s->compileFlags & C_LIQUID ){
|
||||
b->contentShader = s->shaderInfo;
|
||||
b.contentShader = s->shaderInfo;
|
||||
}
|
||||
else if ( b->contentShader->compileFlags & C_FOG ){
|
||||
else if ( b.contentShader->compileFlags & C_FOG ){
|
||||
continue;
|
||||
}
|
||||
else if ( s->compileFlags & C_FOG ){
|
||||
b->contentShader = s->shaderInfo;
|
||||
b.contentShader = s->shaderInfo;
|
||||
}
|
||||
//playerclip
|
||||
else if ( b->contentShader->contentFlags & 0x10000 ){
|
||||
else if ( b.contentShader->contentFlags & 0x10000 ){
|
||||
continue;
|
||||
}
|
||||
else if ( s->contentFlags & 0x10000 ){
|
||||
b->contentShader = s->shaderInfo;
|
||||
b.contentShader = s->shaderInfo;
|
||||
}
|
||||
else if (!( b->contentShader->compileFlags & C_SOLID )){
|
||||
else if (!( b.contentShader->compileFlags & C_SOLID )){
|
||||
continue;
|
||||
}
|
||||
else if (!( s->compileFlags & C_SOLID )){
|
||||
b->contentShader = s->shaderInfo;
|
||||
b.contentShader = s->shaderInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/* ydnar: getting rid of this stupid warning */
|
||||
//% if( mixed )
|
||||
//% Sys_FPrintf( SYS_WRN | SYS_VRBflag, "Entity %i, Brush %i: mixed face contentFlags\n", b->entitynum, b->brushnum );
|
||||
//% Sys_FPrintf( SYS_WRN | SYS_VRBflag, "Entity %i, Brush %i: mixed face contentFlags\n", b.entitynum, b.brushnum );
|
||||
|
||||
/* check for detail & structural */
|
||||
if ( ( compileFlags & C_DETAIL ) && ( compileFlags & C_STRUCTURAL ) ) {
|
||||
|
|
@ -536,20 +531,20 @@ void SetBrushContents( brush_t *b ){
|
|||
/* detail? */
|
||||
if ( compileFlags & C_DETAIL ) {
|
||||
c_detail++;
|
||||
b->detail = true;
|
||||
b.detail = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
c_structural++;
|
||||
b->detail = false;
|
||||
b.detail = false;
|
||||
}
|
||||
|
||||
/* opaque? */
|
||||
if ( compileFlags & C_TRANSLUCENT ) {
|
||||
b->opaque = false;
|
||||
b.opaque = false;
|
||||
}
|
||||
else{
|
||||
b->opaque = true;
|
||||
b.opaque = true;
|
||||
}
|
||||
|
||||
/* areaportal? */
|
||||
|
|
@ -558,8 +553,8 @@ void SetBrushContents( brush_t *b ){
|
|||
}
|
||||
|
||||
/* set brush flags */
|
||||
b->contentFlags = contentFlags;
|
||||
b->compileFlags = compileFlags;
|
||||
b.contentFlags = contentFlags;
|
||||
b.compileFlags = compileFlags;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -572,102 +567,89 @@ void SetBrushContents( brush_t *b ){
|
|||
*/
|
||||
|
||||
void AddBrushBevels( void ){
|
||||
int axis, dir;
|
||||
int i, k, order;
|
||||
side_t sidetemp;
|
||||
side_t *s, *s2;
|
||||
const winding_t *w, *w2;
|
||||
Plane3f plane;
|
||||
Vector3 vec, vec2;
|
||||
float d, minBack;
|
||||
int surfaceFlagsMask = game->brushBevelsSurfaceFlagsMask;
|
||||
const int surfaceFlagsMask = game->brushBevelsSurfaceFlagsMask;
|
||||
auto& sides = buildBrush.sides;
|
||||
|
||||
//
|
||||
// add the axial planes
|
||||
//
|
||||
order = 0;
|
||||
for ( axis = 0; axis < 3; axis++ ) {
|
||||
for ( dir = -1; dir <= 1; dir += 2, order++ ) {
|
||||
size_t order = 0;
|
||||
for ( size_t axis = 0; axis < 3; axis++ ) {
|
||||
for ( int dir = -1; dir <= 1; dir += 2, order++ ) {
|
||||
// see if the plane is already present
|
||||
for ( i = 0, s = buildBrush->sides; i < buildBrush->numsides; i++, s++ )
|
||||
size_t i = 0;
|
||||
for ( ; i < sides.size(); ++i )
|
||||
{
|
||||
/* ydnar: testing disabling of mre code */
|
||||
#if 0
|
||||
if ( dir > 0 ) {
|
||||
if ( mapplanes[s->planenum].normal()[axis] >= 0.9999f ) {
|
||||
if ( mapplanes[sides[i].planenum].normal()[axis] >= 0.9999f ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( mapplanes[s->planenum].normal()[axis] <= -0.9999f ) {
|
||||
if ( mapplanes[sides[i].planenum].normal()[axis] <= -0.9999f ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ( ( dir > 0 && mapplanes[ s->planenum ].normal()[ axis ] == 1.0f ) ||
|
||||
( dir < 0 && mapplanes[ s->planenum ].normal()[ axis ] == -1.0f ) ) {
|
||||
if ( ( dir > 0 && mapplanes[ sides[i].planenum ].normal()[ axis ] == 1.0f ) ||
|
||||
( dir < 0 && mapplanes[ sides[i].planenum ].normal()[ axis ] == -1.0f ) ) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( i == buildBrush->numsides ) {
|
||||
if ( i == sides.size() ) {
|
||||
// add a new side
|
||||
if ( buildBrush->numsides == MAX_BUILD_SIDES ) {
|
||||
xml_Select( "MAX_BUILD_SIDES", buildBrush->entityNum, buildBrush->brushNum, true );
|
||||
if ( sides.size() == MAX_BUILD_SIDES ) {
|
||||
xml_Select( "MAX_BUILD_SIDES", buildBrush.entityNum, buildBrush.brushNum, true );
|
||||
}
|
||||
memset( s, 0, sizeof( *s ) );
|
||||
buildBrush->numsides++;
|
||||
side_t& s = sides.emplace_back();
|
||||
Plane3f plane;
|
||||
plane.normal().set( 0 );
|
||||
plane.normal()[axis] = dir;
|
||||
|
||||
if ( dir == 1 ) {
|
||||
/* ydnar: adding bevel plane snapping for fewer bsp planes */
|
||||
if ( bevelSnap > 0 ) {
|
||||
plane.dist() = floor( buildBrush->minmax.maxs[ axis ] / bevelSnap ) * bevelSnap;
|
||||
plane.dist() = floor( buildBrush.minmax.maxs[ axis ] / bevelSnap ) * bevelSnap;
|
||||
}
|
||||
else{
|
||||
plane.dist() = buildBrush->minmax.maxs[ axis ];
|
||||
plane.dist() = buildBrush.minmax.maxs[ axis ];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ydnar: adding bevel plane snapping for fewer bsp planes */
|
||||
if ( bevelSnap > 0 ) {
|
||||
plane.dist() = -ceil( buildBrush->minmax.mins[ axis ] / bevelSnap ) * bevelSnap;
|
||||
plane.dist() = -ceil( buildBrush.minmax.mins[ axis ] / bevelSnap ) * bevelSnap;
|
||||
}
|
||||
else{
|
||||
plane.dist() = -buildBrush->minmax.mins[ axis ];
|
||||
plane.dist() = -buildBrush.minmax.mins[ axis ];
|
||||
}
|
||||
}
|
||||
|
||||
s->planenum = FindFloatPlane( plane, 0, NULL );
|
||||
s->contentFlags = buildBrush->sides[ 0 ].contentFlags;
|
||||
s.planenum = FindFloatPlane( plane, 0, NULL );
|
||||
s.contentFlags = sides[ 0 ].contentFlags;
|
||||
/* handle bevel surfaceflags for topmost one only: assuming that only walkable ones are meaningful */
|
||||
if( axis == 2 && dir == 1 ){
|
||||
for ( int j = 0; j < buildBrush->numsides; j++ ) {
|
||||
s2 = buildBrush->sides + j;
|
||||
w = s2->winding;
|
||||
if ( !w ) {
|
||||
continue;
|
||||
}
|
||||
for ( const Vector3& po : *w ) {
|
||||
if ( fabs( plane.dist() - po[axis] ) < .1f ) {
|
||||
s->surfaceFlags |= ( s2->surfaceFlags & surfaceFlagsMask );
|
||||
for ( const side_t& side : sides ) {
|
||||
for ( const Vector3& point : side.winding ) {
|
||||
if ( fabs( plane.dist() - point[axis] ) < .1f ) {
|
||||
s.surfaceFlags |= ( side.surfaceFlags & surfaceFlagsMask );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
s->bevel = true;
|
||||
s.bevel = true;
|
||||
c_boxbevels++;
|
||||
}
|
||||
|
||||
// if the plane is not in it canonical order, swap it
|
||||
if ( i != order ) {
|
||||
sidetemp = buildBrush->sides[order];
|
||||
buildBrush->sides[order] = buildBrush->sides[i];
|
||||
buildBrush->sides[i] = sidetemp;
|
||||
std::swap( sides[order], sides[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -675,76 +657,70 @@ void AddBrushBevels( void ){
|
|||
//
|
||||
// add the edge bevels
|
||||
//
|
||||
if ( buildBrush->numsides == 6 ) {
|
||||
if ( sides.size() == 6 ) {
|
||||
return; // pure axial
|
||||
}
|
||||
|
||||
// test the non-axial plane edges
|
||||
for ( i = 6; i < buildBrush->numsides; i++ ) {
|
||||
s = buildBrush->sides + i;
|
||||
w = s->winding;
|
||||
if ( !w ) {
|
||||
continue;
|
||||
}
|
||||
for ( size_t j = 0; j < w->size(); j++ ) {
|
||||
k = ( j + 1 ) % w->size();
|
||||
vec = ( *w )[j] - ( *w )[k];
|
||||
for ( size_t i = 6; i < sides.size(); ++i ) {
|
||||
for ( size_t j = 0; j < sides[i].winding.size(); j++ ) {
|
||||
Vector3 vec = sides[i].winding[j] - sides[i].winding[( ( j + 1 ) == sides[i].winding.size() )? 0 : ( j + 1 )];
|
||||
if ( VectorNormalize( vec ) < 0.5f ) {
|
||||
continue;
|
||||
}
|
||||
SnapNormal( vec );
|
||||
for ( k = 0; k < 3; k++ ) {
|
||||
if ( vec[k] == -1.0f || vec[k] == 1.0f || ( vec[k] == 0.0f && vec[( k + 1 ) % 3] == 0.0f ) ) {
|
||||
break; // axial
|
||||
}
|
||||
}
|
||||
if ( k != 3 ) {
|
||||
continue; // only test non-axial edges
|
||||
if ( vec[0] == -1.0f || vec[0] == 1.0f || ( vec[0] == 0.0f && vec[1] == 0.0f )
|
||||
|| vec[1] == -1.0f || vec[1] == 1.0f || ( vec[1] == 0.0f && vec[2] == 0.0f )
|
||||
|| vec[2] == -1.0f || vec[2] == 1.0f || ( vec[2] == 0.0f && vec[0] == 0.0f ) ) {
|
||||
continue; // axial, only test non-axial edges
|
||||
}
|
||||
|
||||
/* debug code */
|
||||
//% Sys_Printf( "-------------\n" );
|
||||
|
||||
// try the six possible slanted axials from this edge
|
||||
for ( axis = 0; axis < 3; axis++ ) {
|
||||
for ( dir = -1; dir <= 1; dir += 2 ) {
|
||||
for ( int axis = 0; axis < 3; axis++ ) {
|
||||
for ( int dir = -1; dir <= 1; dir += 2 ) {
|
||||
// construct a plane
|
||||
vec2.set( 0 );
|
||||
Vector3 vec2( 0 );
|
||||
vec2[axis] = dir;
|
||||
Plane3f plane;
|
||||
plane.normal() = vector3_cross( vec, vec2 );
|
||||
if ( VectorNormalize( plane.normal() ) < 0.5f ) {
|
||||
continue;
|
||||
}
|
||||
plane.dist() = vector3_dot( ( *w )[j], plane.normal() );
|
||||
plane.dist() = vector3_dot( sides[i].winding[j], plane.normal() );
|
||||
|
||||
// if all the points on all the sides are
|
||||
// behind this plane, it is a proper edge bevel
|
||||
for ( k = 0; k < buildBrush->numsides; k++ ) {
|
||||
auto iside = sides.begin();
|
||||
for ( ; iside != sides.end(); ++iside ) {
|
||||
|
||||
// if this plane has already been used, skip it
|
||||
if ( PlaneEqual( mapplanes[buildBrush->sides[k].planenum], plane ) ) {
|
||||
if( buildBrush->sides[k].bevel ){ /* handle bevel surfaceflags */
|
||||
buildBrush->sides[k].surfaceFlags |= ( s->surfaceFlags & surfaceFlagsMask );
|
||||
if ( PlaneEqual( mapplanes[iside->planenum], plane ) ) {
|
||||
if( iside->bevel ){ /* handle bevel surfaceflags */
|
||||
iside->surfaceFlags |= ( sides[i].surfaceFlags & surfaceFlagsMask );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
w2 = buildBrush->sides[k].winding;
|
||||
if ( !w2 ) {
|
||||
const winding_t& w2 = iside->winding;
|
||||
if ( w2.empty() ) {
|
||||
continue;
|
||||
}
|
||||
minBack = 0.0f;
|
||||
bool point_in_front = false;
|
||||
for ( const Vector3& point : *w2 ) {
|
||||
d = plane3_distance_to_point( plane, point );
|
||||
float minBack = 0.0f;
|
||||
const auto point_in_front = [&w2, &plane, &minBack](){
|
||||
for ( const Vector3& point : w2 ) {
|
||||
const float d = plane3_distance_to_point( plane, point );
|
||||
if ( d > 0.1f ) {
|
||||
point_in_front = true;
|
||||
break; // point in front
|
||||
return true;
|
||||
}
|
||||
value_minimize( minBack, d );
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// if some point was at the front
|
||||
if ( point_in_front ) {
|
||||
if ( point_in_front() ) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -755,7 +731,7 @@ void AddBrushBevels( void ){
|
|||
}
|
||||
}
|
||||
|
||||
if ( k != buildBrush->numsides ) {
|
||||
if ( iside != sides.end() ) {
|
||||
continue; // wasn't part of the outer hull
|
||||
}
|
||||
|
||||
|
|
@ -763,17 +739,15 @@ void AddBrushBevels( void ){
|
|||
//% Sys_Printf( "n = %f %f %f\n", normal[ 0 ], normal[ 1 ], normal[ 2 ] );
|
||||
|
||||
// add this plane
|
||||
if ( buildBrush->numsides == MAX_BUILD_SIDES ) {
|
||||
xml_Select( "MAX_BUILD_SIDES", buildBrush->entityNum, buildBrush->brushNum, true );
|
||||
if ( sides.size() == MAX_BUILD_SIDES ) {
|
||||
xml_Select( "MAX_BUILD_SIDES", buildBrush.entityNum, buildBrush.brushNum, true );
|
||||
}
|
||||
s2 = &buildBrush->sides[buildBrush->numsides];
|
||||
buildBrush->numsides++;
|
||||
memset( s2, 0, sizeof( *s2 ) );
|
||||
side_t& s2 = sides.emplace_back();
|
||||
|
||||
s2->planenum = FindFloatPlane( plane, 1, &( *w )[ j ] );
|
||||
s2->contentFlags = buildBrush->sides[0].contentFlags;
|
||||
s2->surfaceFlags = ( s->surfaceFlags & surfaceFlagsMask ); /* handle bevel surfaceflags */
|
||||
s2->bevel = true;
|
||||
s2.planenum = FindFloatPlane( plane, 1, &sides[i].winding[ j ] );
|
||||
s2.contentFlags = sides[0].contentFlags;
|
||||
s2.surfaceFlags = ( sides[i].surfaceFlags & surfaceFlagsMask ); /* handle bevel surfaceflags */
|
||||
s2.bevel = true;
|
||||
c_edgebevels++;
|
||||
}
|
||||
}
|
||||
|
|
@ -783,12 +757,6 @@ void AddBrushBevels( void ){
|
|||
|
||||
|
||||
|
||||
/*
|
||||
FinishBrush()
|
||||
produces a final brush based on the buildBrush->sides array
|
||||
and links it to the current entity
|
||||
*/
|
||||
|
||||
static void MergeOrigin( entity_t& ent, const Vector3& origin ){
|
||||
char string[128];
|
||||
|
||||
|
|
@ -801,38 +769,41 @@ static void MergeOrigin( entity_t& ent, const Vector3& origin ){
|
|||
ent.setKeyValue( "origin", string );
|
||||
}
|
||||
|
||||
brush_t *FinishBrush( bool noCollapseGroups ){
|
||||
brush_t *b;
|
||||
|
||||
/*
|
||||
FinishBrush()
|
||||
produces a final brush based on the buildBrush->sides array
|
||||
and links it to the current entity
|
||||
*/
|
||||
|
||||
static void FinishBrush( bool noCollapseGroups ){
|
||||
/* create windings for sides and bounds for brush */
|
||||
if ( !CreateBrushWindings( buildBrush ) ) {
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* origin brushes are removed, but they set the rotation origin for the rest of the brushes in the entity.
|
||||
after the entire entity is parsed, the planenums and texinfos will be adjusted for the origin brush */
|
||||
if ( buildBrush->compileFlags & C_ORIGIN ) {
|
||||
if ( buildBrush.compileFlags & C_ORIGIN ) {
|
||||
Sys_Printf( "Entity %i (%s), Brush %i: origin brush detected\n",
|
||||
mapEnt->mapEntityNum, mapEnt->classname(), entitySourceBrushes );
|
||||
|
||||
if ( entities.size() == 1 ) {
|
||||
Sys_FPrintf( SYS_WRN, "Entity %i, Brush %i: origin brushes not allowed in world\n",
|
||||
mapEnt->mapEntityNum, entitySourceBrushes );
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
MergeOrigin( entities.back(), buildBrush->minmax.origin() );
|
||||
MergeOrigin( entities.back(), buildBrush.minmax.origin() );
|
||||
|
||||
/* don't keep this brush */
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* determine if the brush is an area portal */
|
||||
if ( buildBrush->compileFlags & C_AREAPORTAL ) {
|
||||
if ( buildBrush.compileFlags & C_AREAPORTAL ) {
|
||||
if ( entities.size() != 1 ) {
|
||||
Sys_FPrintf( SYS_WRN, "Entity %zu (%s), Brush %i: areaportals only allowed in world\n", entities.size() - 1, mapEnt->classname(), entitySourceBrushes );
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -842,47 +813,30 @@ brush_t *FinishBrush( bool noCollapseGroups ){
|
|||
}
|
||||
|
||||
/* keep it */
|
||||
b = CopyBrush( buildBrush );
|
||||
/* link opaque brushes to head of list, translucent brushes to end */
|
||||
brush_t& b = ( buildBrush.opaque )? mapEnt->brushes.emplace_front( buildBrush )
|
||||
: mapEnt->brushes.emplace_back( buildBrush );
|
||||
|
||||
/* set map entity and brush numbering */
|
||||
b->entityNum = mapEnt->mapEntityNum;
|
||||
b->brushNum = entitySourceBrushes;
|
||||
b.entityNum = mapEnt->mapEntityNum;
|
||||
b.brushNum = entitySourceBrushes;
|
||||
|
||||
/* set original */
|
||||
b->original = b;
|
||||
|
||||
/* link opaque brushes to head of list, translucent brushes to end */
|
||||
if ( b->opaque || mapEnt->lastBrush == NULL ) {
|
||||
b->next = mapEnt->brushes;
|
||||
mapEnt->brushes = b;
|
||||
if ( mapEnt->lastBrush == NULL ) {
|
||||
mapEnt->lastBrush = b;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b->next = NULL;
|
||||
mapEnt->lastBrush->next = b;
|
||||
mapEnt->lastBrush = b;
|
||||
}
|
||||
b.original = &b;
|
||||
|
||||
/* link colorMod volume brushes to the entity directly */
|
||||
if ( b->contentShader != NULL &&
|
||||
b->contentShader->colorMod != NULL &&
|
||||
b->contentShader->colorMod->type == EColorMod::Volume ) {
|
||||
b->nextColorModBrush = mapEnt->colorModBrushes;
|
||||
mapEnt->colorModBrushes = b;
|
||||
if ( b.contentShader != NULL &&
|
||||
b.contentShader->colorMod != NULL &&
|
||||
b.contentShader->colorMod->type == EColorMod::Volume ) {
|
||||
mapEnt->colorModBrushes.push_back( &b );
|
||||
}
|
||||
|
||||
/* return to sender */
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
TextureAxisFromPlane()
|
||||
determines best orthagonal axis to project a texture onto a wall
|
||||
determines best orthogonal axis to project a texture onto a wall
|
||||
(must be identical in radiant!)
|
||||
*/
|
||||
|
||||
|
|
@ -1003,19 +957,9 @@ void QuakeTextureVecs( const plane_t& plane, float shift[ 2 ], float rotate, flo
|
|||
*/
|
||||
|
||||
static void ParseRawBrush( bool onlyLights ){
|
||||
side_t *side;
|
||||
DoubleVector3 planePoints[ 3 ];
|
||||
int planenum;
|
||||
shaderInfo_t *si;
|
||||
float shift[ 2 ];
|
||||
float rotate = 0;
|
||||
float scale[ 2 ];
|
||||
int flags;
|
||||
|
||||
|
||||
/* initial setup */
|
||||
buildBrush->numsides = 0;
|
||||
buildBrush->detail = false;
|
||||
buildBrush.sides.clear();
|
||||
buildBrush.detail = false;
|
||||
|
||||
/* bp */
|
||||
if ( g_brushType == EBrushType::Bp ) {
|
||||
|
|
@ -1048,29 +992,41 @@ static void ParseRawBrush( bool onlyLights ){
|
|||
UnGetToken();
|
||||
|
||||
/* test side count */
|
||||
if ( buildBrush->numsides >= MAX_BUILD_SIDES ) {
|
||||
xml_Select( "MAX_BUILD_SIDES", buildBrush->entityNum, buildBrush->brushNum, true );
|
||||
if ( buildBrush.sides.size() >= MAX_BUILD_SIDES ) {
|
||||
xml_Select( "MAX_BUILD_SIDES", buildBrush.entityNum, buildBrush.brushNum, true );
|
||||
}
|
||||
|
||||
/* add side */
|
||||
side = &buildBrush->sides[ buildBrush->numsides ];
|
||||
memset( side, 0, sizeof( *side ) );
|
||||
buildBrush->numsides++;
|
||||
side_t& side = buildBrush.sides.emplace_back();
|
||||
|
||||
/* read the three point plane definition */
|
||||
DoubleVector3 planePoints[ 3 ];
|
||||
Parse1DMatrix( 3, planePoints[ 0 ].data() );
|
||||
Parse1DMatrix( 3, planePoints[ 1 ].data() );
|
||||
Parse1DMatrix( 3, planePoints[ 2 ].data() );
|
||||
|
||||
/* find the plane number */
|
||||
side.planenum = MapPlaneFromPoints( planePoints );
|
||||
PlaneFromPoints( side.plane, planePoints );
|
||||
|
||||
/* bp: read the texture matrix */
|
||||
if ( g_brushType == EBrushType::Bp ) {
|
||||
Parse2DMatrix( 2, 3, side->texMat->data() );
|
||||
Parse2DMatrix( 2, 3, side.texMat->data() );
|
||||
}
|
||||
|
||||
/* read shader name */
|
||||
GetToken( false );
|
||||
const auto shader = String64()( "textures/", token );
|
||||
|
||||
/* set default flags and values */
|
||||
shaderInfo_t *si = onlyLights? &shaderInfo[ 0 ]
|
||||
: ShaderInfoForShader( shader );
|
||||
side.shaderInfo = si;
|
||||
side.surfaceFlags = si->surfaceFlags;
|
||||
side.contentFlags = si->contentFlags;
|
||||
side.compileFlags = si->compileFlags;
|
||||
side.value = si->value;
|
||||
|
||||
/* AP or 220? */
|
||||
if ( g_brushType == EBrushType::Undefined ){
|
||||
GetToken( false );
|
||||
|
|
@ -1086,6 +1042,8 @@ static void ParseRawBrush( bool onlyLights ){
|
|||
}
|
||||
|
||||
if ( g_brushType == EBrushType::Quake ) {
|
||||
float shift[ 2 ], rotate, scale[ 2 ];
|
||||
|
||||
GetToken( false );
|
||||
shift[ 0 ] = atof( token );
|
||||
GetToken( false );
|
||||
|
|
@ -1096,19 +1054,27 @@ static void ParseRawBrush( bool onlyLights ){
|
|||
scale[ 0 ] = atof( token );
|
||||
GetToken( false );
|
||||
scale[ 1 ] = atof( token );
|
||||
|
||||
/* ydnar: gs mods: bias texture shift */
|
||||
if ( !si->globalTexture ) {
|
||||
shift[ 0 ] -= ( floor( shift[ 0 ] / si->shaderWidth ) * si->shaderWidth );
|
||||
shift[ 1 ] -= ( floor( shift[ 1 ] / si->shaderHeight ) * si->shaderHeight );
|
||||
}
|
||||
|
||||
/* get the texture mapping for this texturedef / plane combination */
|
||||
QuakeTextureVecs( mapplanes[ side.planenum ], shift, rotate, scale, side.vecs );
|
||||
}
|
||||
else if ( g_brushType == EBrushType::Valve220 ){
|
||||
int axis, comp;
|
||||
for ( axis = 0; axis < 2; ++axis ){
|
||||
for ( int axis = 0; axis < 2; ++axis ){
|
||||
MatchToken( "[" );
|
||||
for ( comp = 0; comp < 4; ++comp ){
|
||||
for ( int comp = 0; comp < 4; ++comp ){
|
||||
GetToken( false );
|
||||
side->vecs[axis][comp] = atof( token );
|
||||
side.vecs[axis][comp] = atof( token );
|
||||
}
|
||||
MatchToken( "]" );
|
||||
}
|
||||
GetToken( false );
|
||||
rotate = atof( token );
|
||||
GetToken( false ); // rotate
|
||||
float scale[2];
|
||||
GetToken( false );
|
||||
scale[ 0 ] = atof( token );
|
||||
GetToken( false );
|
||||
|
|
@ -1116,27 +1082,8 @@ static void ParseRawBrush( bool onlyLights ){
|
|||
|
||||
if ( !scale[0] ) scale[0] = 1.f;
|
||||
if ( !scale[1] ) scale[1] = 1.f;
|
||||
for ( axis = 0; axis < 2; ++axis )
|
||||
side->vecs[axis].vec3() /= scale[axis];
|
||||
}
|
||||
|
||||
/* set default flags and values */
|
||||
if ( onlyLights ) {
|
||||
si = &shaderInfo[ 0 ];
|
||||
}
|
||||
else{
|
||||
si = ShaderInfoForShader( shader );
|
||||
}
|
||||
side->shaderInfo = si;
|
||||
side->surfaceFlags = si->surfaceFlags;
|
||||
side->contentFlags = si->contentFlags;
|
||||
side->compileFlags = si->compileFlags;
|
||||
side->value = si->value;
|
||||
|
||||
/* ydnar: gs mods: bias texture shift */
|
||||
if ( !si->globalTexture ) {
|
||||
shift[ 0 ] -= ( floor( shift[ 0 ] / si->shaderWidth ) * si->shaderWidth );
|
||||
shift[ 1 ] -= ( floor( shift[ 1 ] / si->shaderHeight ) * si->shaderHeight );
|
||||
for ( int axis = 0; axis < 2; ++axis )
|
||||
side.vecs[axis].vec3() /= scale[axis];
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1153,9 +1100,9 @@ static void ParseRawBrush( bool onlyLights ){
|
|||
if ( TokenAvailable() ) {
|
||||
/* get detail bit from map content flags */
|
||||
GetToken( false );
|
||||
flags = atoi( token );
|
||||
const int flags = atoi( token );
|
||||
if ( flags & C_DETAIL ) {
|
||||
side->compileFlags |= C_DETAIL;
|
||||
side.compileFlags |= C_DETAIL;
|
||||
}
|
||||
|
||||
/* historical */
|
||||
|
|
@ -1164,16 +1111,6 @@ static void ParseRawBrush( bool onlyLights ){
|
|||
GetToken( false );
|
||||
//% td.value = atoi( token );
|
||||
}
|
||||
|
||||
/* find the plane number */
|
||||
planenum = MapPlaneFromPoints( planePoints );
|
||||
side->planenum = planenum;
|
||||
PlaneFromPoints( side->plane, planePoints );
|
||||
|
||||
/* bp: get the texture mapping for this texturedef / plane combination */
|
||||
if ( g_brushType == EBrushType::Quake ) {
|
||||
QuakeTextureVecs( mapplanes[ planenum ], shift, rotate, scale, side->vecs );
|
||||
}
|
||||
}
|
||||
|
||||
/* bp */
|
||||
|
|
@ -1193,44 +1130,37 @@ static void ParseRawBrush( bool onlyLights ){
|
|||
also removes planes without any normal
|
||||
*/
|
||||
|
||||
bool RemoveDuplicateBrushPlanes( brush_t *b ){
|
||||
int i, j, k;
|
||||
side_t *sides;
|
||||
|
||||
sides = b->sides;
|
||||
|
||||
for ( i = 1 ; i < b->numsides ; i++ ) {
|
||||
bool RemoveDuplicateBrushPlanes( brush_t& b ){
|
||||
auto& sides = b.sides;
|
||||
|
||||
for( auto it = sides.cbegin(); it != sides.cend(); ){
|
||||
// check for a degenerate plane
|
||||
if ( sides[i].planenum == -1 ) {
|
||||
xml_Select( "degenerate plane", b->entityNum, b->brushNum, false );
|
||||
if ( it->planenum == -1 ) {
|
||||
xml_Select( "degenerate plane", b.entityNum, b.brushNum, false );
|
||||
// remove it
|
||||
for ( k = i + 1 ; k < b->numsides ; k++ ) {
|
||||
sides[k - 1] = sides[k];
|
||||
it = sides.erase( it );
|
||||
}
|
||||
else{
|
||||
++it;
|
||||
}
|
||||
b->numsides--;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( size_t i = 0; i < sides.size(); ++i ) {
|
||||
// check for duplication and mirroring
|
||||
for ( j = 0 ; j < i ; j++ ) {
|
||||
for ( size_t j = i + 1; j < sides.size(); ) {
|
||||
if ( sides[i].planenum == sides[j].planenum ) {
|
||||
xml_Select( "duplicate plane", b->entityNum, b->brushNum, false );
|
||||
xml_Select( "duplicate plane", b.entityNum, b.brushNum, false );
|
||||
// remove the second duplicate
|
||||
for ( k = i + 1 ; k < b->numsides ; k++ ) {
|
||||
sides[k - 1] = sides[k];
|
||||
sides.erase( sides.cbegin() + j );
|
||||
}
|
||||
b->numsides--;
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( sides[i].planenum == ( sides[j].planenum ^ 1 ) ) {
|
||||
else if ( sides[i].planenum == ( sides[j].planenum ^ 1 ) ) {
|
||||
// mirror plane, brush is invalid
|
||||
xml_Select( "mirrored plane", b->entityNum, b->brushNum, false );
|
||||
xml_Select( "mirrored plane", b.entityNum, b.brushNum, false );
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1253,10 +1183,10 @@ static void ParseBrush( bool onlyLights, bool noCollapseGroups ){
|
|||
}
|
||||
|
||||
/* set some defaults */
|
||||
buildBrush->portalareas[ 0 ] = -1;
|
||||
buildBrush->portalareas[ 1 ] = -1;
|
||||
buildBrush->entityNum = numMapEntities - 1;
|
||||
buildBrush->brushNum = entitySourceBrushes;
|
||||
buildBrush.portalareas[ 0 ] = -1;
|
||||
buildBrush.portalareas[ 1 ] = -1;
|
||||
buildBrush.entityNum = numMapEntities - 1;
|
||||
buildBrush.brushNum = entitySourceBrushes;
|
||||
|
||||
/* if there are mirrored planes, the entire brush is invalid */
|
||||
if ( !RemoveDuplicateBrushPlanes( buildBrush ) ) {
|
||||
|
|
@ -1267,20 +1197,17 @@ static void ParseBrush( bool onlyLights, bool noCollapseGroups ){
|
|||
SetBrushContents( buildBrush );
|
||||
|
||||
/* allow detail brushes to be removed */
|
||||
if ( nodetail && ( buildBrush->compileFlags & C_DETAIL ) ) {
|
||||
//% FreeBrush( buildBrush );
|
||||
if ( nodetail && ( buildBrush.compileFlags & C_DETAIL ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* allow liquid brushes to be removed */
|
||||
if ( nowater && ( buildBrush->compileFlags & C_LIQUID ) ) {
|
||||
//% FreeBrush( buildBrush );
|
||||
if ( nowater && ( buildBrush.compileFlags & C_LIQUID ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* ydnar: allow hint brushes to be removed */
|
||||
if ( noHint && ( buildBrush->compileFlags & C_HINT ) ) {
|
||||
//% FreeBrush( buildBrush );
|
||||
if ( noHint && ( buildBrush.compileFlags & C_HINT ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1299,49 +1226,36 @@ static void ParseBrush( bool onlyLights, bool noCollapseGroups ){
|
|||
|
||||
void AdjustBrushesForOrigin( entity_t *ent );
|
||||
void MoveBrushesToWorld( entity_t *ent ){
|
||||
brush_t *b, *next;
|
||||
parseMesh_t *pm;
|
||||
|
||||
/* we need to undo the common/origin adjustment, and instead shift them by the entity key origin */
|
||||
ent->originbrush_origin = -ent->origin;
|
||||
AdjustBrushesForOrigin( ent );
|
||||
ent->originbrush_origin.set( 0 );
|
||||
|
||||
/* move brushes */
|
||||
for ( b = ent->brushes; b != NULL; b = next )
|
||||
for ( brushlist_t::const_iterator next, b = ent->brushes.begin(); b != ent->brushes.end(); b = next )
|
||||
{
|
||||
/* get next brush */
|
||||
next = b->next;
|
||||
next = std::next( b );
|
||||
|
||||
/* link opaque brushes to head of list, translucent brushes to end */
|
||||
if ( b->opaque || entities[ 0 ].lastBrush == NULL ) {
|
||||
b->next = entities[ 0 ].brushes;
|
||||
entities[ 0 ].brushes = b;
|
||||
if ( entities[ 0 ].lastBrush == NULL ) {
|
||||
entities[ 0 ].lastBrush = b;
|
||||
}
|
||||
if ( b->opaque ) {
|
||||
entities[ 0 ].brushes.splice( entities[ 0 ].brushes.begin(), ent->brushes, b );
|
||||
}
|
||||
else
|
||||
{
|
||||
b->next = NULL;
|
||||
entities[ 0 ].lastBrush->next = b;
|
||||
entities[ 0 ].lastBrush = b;
|
||||
entities[ 0 ].brushes.splice( entities[ 0 ].brushes.end(), ent->brushes, b );
|
||||
}
|
||||
}
|
||||
ent->brushes = NULL;
|
||||
|
||||
/* ydnar: move colormod brushes */
|
||||
if ( ent->colorModBrushes != NULL ) {
|
||||
for ( b = ent->colorModBrushes; b->nextColorModBrush != NULL; b = b->nextColorModBrush ) ;
|
||||
|
||||
b->nextColorModBrush = entities[ 0 ].colorModBrushes;
|
||||
entities[ 0 ].colorModBrushes = ent->colorModBrushes;
|
||||
|
||||
ent->colorModBrushes = NULL;
|
||||
if ( !ent->colorModBrushes.empty() ) {
|
||||
entities[ 0 ].colorModBrushes.insert( entities[ 0 ].colorModBrushes.end(), ent->colorModBrushes.begin(), ent->colorModBrushes.end() );
|
||||
ent->colorModBrushes.clear();
|
||||
}
|
||||
|
||||
/* move patches */
|
||||
if ( ent->patches != NULL ) {
|
||||
parseMesh_t *pm;
|
||||
for ( pm = ent->patches; pm->next != NULL; pm = pm->next ) ;
|
||||
|
||||
pm->next = entities[ 0 ].patches;
|
||||
|
|
@ -1358,28 +1272,18 @@ void MoveBrushesToWorld( entity_t *ent ){
|
|||
*/
|
||||
|
||||
void AdjustBrushesForOrigin( entity_t *ent ){
|
||||
|
||||
int i;
|
||||
side_t *s;
|
||||
float newdist;
|
||||
brush_t *b;
|
||||
parseMesh_t *p;
|
||||
|
||||
/* walk brush list */
|
||||
for ( b = ent->brushes; b != NULL; b = b->next )
|
||||
for ( brush_t& b : ent->brushes )
|
||||
{
|
||||
/* offset brush planes */
|
||||
for ( i = 0; i < b->numsides; i++ )
|
||||
for ( side_t& side : b.sides )
|
||||
{
|
||||
/* get brush side */
|
||||
s = &b->sides[ i ];
|
||||
|
||||
/* offset side plane */
|
||||
newdist = -plane3_distance_to_point( mapplanes[ s->planenum ].plane, ent->originbrush_origin );
|
||||
const float newdist = -plane3_distance_to_point( mapplanes[ side.planenum ].plane, ent->originbrush_origin );
|
||||
|
||||
/* find a new plane */
|
||||
s->planenum = FindFloatPlane( mapplanes[ s->planenum ].normal(), newdist, 0, NULL );
|
||||
s->plane.dist() = -plane3_distance_to_point( s->plane, ent->originbrush_origin );
|
||||
side.planenum = FindFloatPlane( mapplanes[ side.planenum ].normal(), newdist, 0, NULL );
|
||||
side.plane.dist() = -plane3_distance_to_point( side.plane, ent->originbrush_origin );
|
||||
}
|
||||
|
||||
/* rebuild brush windings (ydnar: just offsetting the winding above should be fine) */
|
||||
|
|
@ -1387,9 +1291,9 @@ void AdjustBrushesForOrigin( entity_t *ent ){
|
|||
}
|
||||
|
||||
/* walk patch list */
|
||||
for ( p = ent->patches; p != NULL; p = p->next )
|
||||
for ( parseMesh_t *p = ent->patches; p != NULL; p = p->next )
|
||||
{
|
||||
for ( i = 0; i < ( p->mesh.width * p->mesh.height ); i++ )
|
||||
for ( int i = 0; i < ( p->mesh.width * p->mesh.height ); i++ )
|
||||
p->mesh.verts[ i ].xyz -= ent->originbrush_origin;
|
||||
}
|
||||
}
|
||||
|
|
@ -1402,20 +1306,16 @@ void AdjustBrushesForOrigin( entity_t *ent ){
|
|||
*/
|
||||
|
||||
void SetEntityBounds( entity_t *e ){
|
||||
int i;
|
||||
brush_t *b;
|
||||
parseMesh_t *p;
|
||||
MinMax minmax;
|
||||
|
||||
|
||||
/* walk the entity's brushes/patches and determine bounds */
|
||||
for ( b = e->brushes; b; b = b->next )
|
||||
for ( const brush_t& b : e->brushes )
|
||||
{
|
||||
minmax.extend( b->minmax );
|
||||
minmax.extend( b.minmax );
|
||||
}
|
||||
for ( p = e->patches; p; p = p->next )
|
||||
for ( parseMesh_t *p = e->patches; p; p = p->next )
|
||||
{
|
||||
for ( i = 0; i < ( p->mesh.width * p->mesh.height ); i++ )
|
||||
for ( int i = 0; i < ( p->mesh.width * p->mesh.height ); i++ )
|
||||
minmax.extend( p->mesh.verts[ i ].xyz );
|
||||
}
|
||||
|
||||
|
|
@ -1424,11 +1324,11 @@ void SetEntityBounds( entity_t *e ){
|
|||
e->read_keyvalue( minmax.maxs, "max" );
|
||||
|
||||
/* store the bounds */
|
||||
for ( b = e->brushes; b; b = b->next )
|
||||
for ( brush_t& b : e->brushes )
|
||||
{
|
||||
b->eMinmax = minmax;
|
||||
b.eMinmax = minmax;
|
||||
}
|
||||
for ( p = e->patches; p; p = p->next )
|
||||
for ( parseMesh_t *p = e->patches; p; p = p->next )
|
||||
{
|
||||
p->eMinmax = minmax;
|
||||
}
|
||||
|
|
@ -1447,12 +1347,10 @@ void LoadEntityIndexMap( entity_t *e ){
|
|||
byte *pixels;
|
||||
unsigned int *pixels32;
|
||||
indexMap_t *im;
|
||||
brush_t *b;
|
||||
parseMesh_t *p;
|
||||
|
||||
|
||||
/* this only works with bmodel ents */
|
||||
if ( e->brushes == NULL && e->patches == NULL ) {
|
||||
if ( e->brushes.empty() && e->patches == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1566,9 +1464,9 @@ void LoadEntityIndexMap( entity_t *e ){
|
|||
}
|
||||
|
||||
/* store the index map in every brush/patch in the entity */
|
||||
for ( b = e->brushes; b != NULL; b = b->next )
|
||||
b->im = im;
|
||||
for ( p = e->patches; p != NULL; p = p->next )
|
||||
for ( brush_t& b : e->brushes )
|
||||
b.im = im;
|
||||
for ( parseMesh_t *p = e->patches; p != NULL; p = p->next )
|
||||
p->im = im;
|
||||
}
|
||||
|
||||
|
|
@ -1584,9 +1482,6 @@ void LoadEntityIndexMap( entity_t *e ){
|
|||
*/
|
||||
|
||||
static bool ParseMapEntity( bool onlyLights, bool noCollapseGroups ){
|
||||
brush_t *brush;
|
||||
parseMesh_t *patch;
|
||||
|
||||
/* eof check */
|
||||
if ( !GetToken( true ) ) {
|
||||
return false;
|
||||
|
|
@ -1716,18 +1611,18 @@ static bool ParseMapEntity( bool onlyLights, bool noCollapseGroups ){
|
|||
Sys_Printf( "Entity %d (%s) has lightmap sample size of %d\n", mapEnt->mapEntityNum, classname, lightmapSampleSize );
|
||||
|
||||
/* attach stuff to everything in the entity */
|
||||
for ( brush = mapEnt->brushes; brush != NULL; brush = brush->next )
|
||||
for ( brush_t& brush : mapEnt->brushes )
|
||||
{
|
||||
brush->entityNum = mapEnt->mapEntityNum;
|
||||
brush->castShadows = castShadows;
|
||||
brush->recvShadows = recvShadows;
|
||||
brush->lightmapSampleSize = lightmapSampleSize;
|
||||
brush->lightmapScale = lightmapScale;
|
||||
brush->celShader = celShader;
|
||||
brush->shadeAngleDegrees = shadeAngle;
|
||||
brush.entityNum = mapEnt->mapEntityNum;
|
||||
brush.castShadows = castShadows;
|
||||
brush.recvShadows = recvShadows;
|
||||
brush.lightmapSampleSize = lightmapSampleSize;
|
||||
brush.lightmapScale = lightmapScale;
|
||||
brush.celShader = celShader;
|
||||
brush.shadeAngleDegrees = shadeAngle;
|
||||
}
|
||||
|
||||
for ( patch = mapEnt->patches; patch != NULL; patch = patch->next )
|
||||
for ( parseMesh_t *patch = mapEnt->patches; patch != NULL; patch = patch->next )
|
||||
{
|
||||
patch->entityNum = mapEnt->mapEntityNum;
|
||||
patch->castShadows = castShadows;
|
||||
|
|
@ -1775,8 +1670,7 @@ static bool ParseMapEntity( bool onlyLights, bool noCollapseGroups ){
|
|||
|
||||
void LoadMapFile( char *filename, bool onlyLights, bool noCollapseGroups ){
|
||||
FILE *file;
|
||||
brush_t *b;
|
||||
int oldNumEntities = 0, numMapBrushes;
|
||||
int oldNumEntities = 0;
|
||||
|
||||
|
||||
/* note it */
|
||||
|
|
@ -1804,7 +1698,7 @@ void LoadMapFile( char *filename, bool onlyLights, bool noCollapseGroups ){
|
|||
g_brushType = EBrushType::Undefined;
|
||||
|
||||
/* allocate a very large temporary brush for building the brushes as they are loaded */
|
||||
buildBrush = AllocBrush( MAX_BUILD_SIDES );
|
||||
buildBrush.sides.reserve( MAX_BUILD_SIDES );
|
||||
|
||||
/* parse the map file */
|
||||
while ( ParseMapEntity( onlyLights, noCollapseGroups ) ) ;
|
||||
|
|
@ -1818,13 +1712,13 @@ void LoadMapFile( char *filename, bool onlyLights, bool noCollapseGroups ){
|
|||
{
|
||||
/* set map bounds */
|
||||
g_mapMinmax.clear();
|
||||
for ( b = entities[ 0 ].brushes; b; b = b->next )
|
||||
for ( const brush_t& brush : entities[ 0 ].brushes )
|
||||
{
|
||||
g_mapMinmax.extend( b->minmax );
|
||||
g_mapMinmax.extend( brush.minmax );
|
||||
}
|
||||
|
||||
/* get brush counts */
|
||||
numMapBrushes = CountBrushList( entities[ 0 ].brushes );
|
||||
const int numMapBrushes = entities[ 0 ].brushes.size();
|
||||
if ( (float) c_detail / (float) numMapBrushes < 0.10f && numMapBrushes > 500 ) {
|
||||
Sys_Warning( "Over 90 percent structural map detected. Compile time may be adversely affected.\n" );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -718,13 +718,12 @@ void InsertModel( const char *name, int skin, int frame, const Matrix4& transfor
|
|||
if ( PlaneFromPoints( plane, points ) ) {
|
||||
|
||||
/* build a brush */
|
||||
buildBrush = AllocBrush( 48 );
|
||||
buildBrush->entityNum = mapEntityNum;
|
||||
buildBrush->original = buildBrush;
|
||||
buildBrush->contentShader = si;
|
||||
buildBrush->compileFlags = si->compileFlags;
|
||||
buildBrush->contentFlags = si->contentFlags;
|
||||
buildBrush->detail = true;
|
||||
buildBrush.sides.reserve( MAX_BUILD_SIDES );
|
||||
buildBrush.entityNum = mapEntityNum;
|
||||
buildBrush.contentShader = si;
|
||||
buildBrush.compileFlags = si->compileFlags;
|
||||
buildBrush.contentFlags = si->contentFlags;
|
||||
buildBrush.detail = true;
|
||||
|
||||
//snap points before using them for further calculations
|
||||
//precision suffers a lot, when two of normal values are under .00025 (often no collision, knocking up effect in ioq3)
|
||||
|
|
@ -893,24 +892,25 @@ void InsertModel( const char *name, int skin, int frame, const Matrix4& transfor
|
|||
}
|
||||
#endif
|
||||
/* set up brush sides */
|
||||
buildBrush->numsides = 4;
|
||||
buildBrush->sides[ 0 ].shaderInfo = si;
|
||||
buildBrush->sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < buildBrush->numsides; j++ ) {
|
||||
buildBrush.sides.clear(); // clear, so resize() will value-initialize elements
|
||||
buildBrush.sides.resize( 4 );
|
||||
buildBrush.sides[ 0 ].shaderInfo = si;
|
||||
buildBrush.sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < 4; j++ ) {
|
||||
if ( debugClip ) {
|
||||
buildBrush->sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush->sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
buildBrush.sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush.sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
}
|
||||
else {
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
buildBrush.sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush.sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush.sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush.sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush.sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1033,25 +1033,26 @@ void InsertModel( const char *name, int skin, int frame, const Matrix4& transfor
|
|||
}
|
||||
#endif
|
||||
/* set up brush sides */
|
||||
buildBrush->numsides = 5;
|
||||
buildBrush->sides[ 0 ].shaderInfo = si;
|
||||
buildBrush->sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < buildBrush->numsides; j++ ) {
|
||||
buildBrush.sides.clear(); // clear, so resize() will value-initialize elements
|
||||
buildBrush.sides.resize( 5 );
|
||||
buildBrush.sides[ 0 ].shaderInfo = si;
|
||||
buildBrush.sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < 5; j++ ) {
|
||||
if ( debugClip ) {
|
||||
buildBrush->sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush->sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
buildBrush.sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush.sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
}
|
||||
else {
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
buildBrush.sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
buildBrush.sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush.sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush.sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush.sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush.sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1087,25 +1088,26 @@ void InsertModel( const char *name, int skin, int frame, const Matrix4& transfor
|
|||
reverse.dist() += clipDepth;
|
||||
|
||||
/* set up brush sides */
|
||||
buildBrush->numsides = 5;
|
||||
buildBrush->sides[ 0 ].shaderInfo = si;
|
||||
buildBrush->sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < buildBrush->numsides; j++ ) {
|
||||
buildBrush.sides.clear(); // clear, so resize() will value-initialize elements
|
||||
buildBrush.sides.resize( 5 );
|
||||
buildBrush.sides[ 0 ].shaderInfo = si;
|
||||
buildBrush.sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < 5; j++ ) {
|
||||
if ( debugClip ) {
|
||||
buildBrush->sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush->sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
buildBrush.sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush.sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
}
|
||||
else {
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
buildBrush.sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
buildBrush.sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush.sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush.sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush.sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush.sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1166,25 +1168,26 @@ void InsertModel( const char *name, int skin, int frame, const Matrix4& transfor
|
|||
reverse.dist() += clipDepth;
|
||||
|
||||
/* set up brush sides */
|
||||
buildBrush->numsides = 5;
|
||||
buildBrush->sides[ 0 ].shaderInfo = si;
|
||||
buildBrush->sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < buildBrush->numsides; j++ ) {
|
||||
buildBrush.sides.clear(); // clear, so resize() will value-initialize elements
|
||||
buildBrush.sides.resize( 5 );
|
||||
buildBrush.sides[ 0 ].shaderInfo = si;
|
||||
buildBrush.sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < 5; j++ ) {
|
||||
if ( debugClip ) {
|
||||
buildBrush->sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush->sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
buildBrush.sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush.sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
}
|
||||
else {
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
buildBrush.sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
buildBrush.sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush.sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush.sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush.sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush.sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1230,25 +1233,26 @@ void InsertModel( const char *name, int skin, int frame, const Matrix4& transfor
|
|||
}
|
||||
#endif
|
||||
/* set up brush sides */
|
||||
buildBrush->numsides = 5;
|
||||
buildBrush->sides[ 0 ].shaderInfo = si;
|
||||
buildBrush->sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < buildBrush->numsides; j++ ) {
|
||||
buildBrush.sides.clear(); // clear, so resize() will value-initialize elements
|
||||
buildBrush.sides.resize( 5 );
|
||||
buildBrush.sides[ 0 ].shaderInfo = si;
|
||||
buildBrush.sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < 5; j++ ) {
|
||||
if ( debugClip ) {
|
||||
buildBrush->sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush->sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
buildBrush.sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush.sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
}
|
||||
else {
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
buildBrush.sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
buildBrush.sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush.sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush.sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush.sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush.sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1293,30 +1297,30 @@ void InsertModel( const char *name, int skin, int frame, const Matrix4& transfor
|
|||
}
|
||||
#endif
|
||||
/* set up brush sides */
|
||||
buildBrush->numsides = 4;
|
||||
buildBrush->sides[ 0 ].shaderInfo = si;
|
||||
buildBrush->sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < buildBrush->numsides; j++ ) {
|
||||
buildBrush.sides.clear(); // clear, so resize() will value-initialize elements
|
||||
buildBrush.sides.resize( 4 );
|
||||
buildBrush.sides[ 0 ].shaderInfo = si;
|
||||
buildBrush.sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < 4; j++ ) {
|
||||
if ( debugClip ) {
|
||||
buildBrush->sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush->sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
buildBrush.sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush.sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
}
|
||||
else {
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
buildBrush.sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 1 ] ); // p[0] contains points[1] and points[2]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 0 ] ); // p[1] contains points[0] and points[1]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush.sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush.sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 1 ] ); // p[0] contains points[1] and points[2]
|
||||
buildBrush.sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 0 ] ); // p[1] contains points[0] and points[1]
|
||||
buildBrush.sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped\n",
|
||||
points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name );
|
||||
free( buildBrush );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -1359,25 +1363,26 @@ default_CLIPMODEL:
|
|||
}
|
||||
#endif
|
||||
/* set up brush sides */
|
||||
buildBrush->numsides = 5;
|
||||
buildBrush->sides[ 0 ].shaderInfo = si;
|
||||
buildBrush->sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < buildBrush->numsides; j++ ) {
|
||||
buildBrush.sides.clear(); // clear, so resize() will value-initialize elements
|
||||
buildBrush.sides.resize( 5 );
|
||||
buildBrush.sides[ 0 ].shaderInfo = si;
|
||||
buildBrush.sides[ 0 ].surfaceFlags = si->surfaceFlags;
|
||||
for ( j = 1; j < 5; j++ ) {
|
||||
if ( debugClip ) {
|
||||
buildBrush->sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush->sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
buildBrush.sides[ 0 ].shaderInfo = ShaderInfoForShader( "debugclip2" );
|
||||
buildBrush.sides[ j ].shaderInfo = ShaderInfoForShader( "debugclip" );
|
||||
}
|
||||
else {
|
||||
buildBrush->sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
buildBrush.sides[ j ].shaderInfo = NULL; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
}
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
|
||||
buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
buildBrush.sides[ 0 ].planenum = FindFloatPlane( plane, 3, points );
|
||||
buildBrush.sides[ 1 ].planenum = FindFloatPlane( p[0], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
|
||||
buildBrush.sides[ 2 ].planenum = FindFloatPlane( p[1], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
|
||||
buildBrush.sides[ 3 ].planenum = FindFloatPlane( p[2], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
|
||||
buildBrush.sides[ 4 ].planenum = FindFloatPlane( reverse, 0, NULL );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1385,14 +1390,13 @@ default_CLIPMODEL:
|
|||
if ( CreateBrushWindings( buildBrush ) ) {
|
||||
AddBrushBevels();
|
||||
//% EmitBrushes( buildBrush, NULL, NULL );
|
||||
buildBrush->next = entities[ mapEntityNum ].brushes;
|
||||
entities[ mapEntityNum ].brushes = buildBrush;
|
||||
brush_t& newBrush = entities[ mapEntityNum ].brushes.emplace_front( buildBrush );
|
||||
newBrush.original = &newBrush;
|
||||
entities[ mapEntityNum ].numBrushes++;
|
||||
}
|
||||
else{
|
||||
Sys_Warning( "triangle (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) (%6.0f %6.0f %6.0f) of %s was not autoclipped\n",
|
||||
points[0][0], points[0][1], points[0][2], points[1][0], points[1][1], points[1][2], points[2][0], points[2][1], points[2][2], name );
|
||||
free( buildBrush );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,24 +34,7 @@
|
|||
|
||||
|
||||
/* ydnar: to fix broken portal windings */
|
||||
extern bool FixWinding( winding_t *w );
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
AllocPortal
|
||||
===========
|
||||
*/
|
||||
portal_t *AllocPortal( void ){
|
||||
return safe_calloc( sizeof( portal_t ) );
|
||||
}
|
||||
|
||||
void FreePortal( portal_t *p ){
|
||||
if ( p->winding ) {
|
||||
FreeWinding( p->winding );
|
||||
}
|
||||
free( p );
|
||||
}
|
||||
extern bool FixWinding( winding_t& w );
|
||||
|
||||
|
||||
|
||||
|
|
@ -157,7 +140,7 @@ void RemovePortalFromNode( portal_t *portal, node_t *l ){
|
|||
//============================================================================
|
||||
|
||||
void PrintPortal( const portal_t *p ){
|
||||
for ( const Vector3& point : ( *p->winding ) )
|
||||
for ( const Vector3& point : p->winding )
|
||||
Sys_Printf( "(%5.0f,%5.0f,%5.0f)\n", point[0], point[1], point[2] );
|
||||
}
|
||||
|
||||
|
|
@ -169,59 +152,46 @@ void PrintPortal( const portal_t *p ){
|
|||
================
|
||||
*/
|
||||
#define SIDESPACE 8
|
||||
void MakeHeadnodePortals( tree_t *tree ){
|
||||
int i, j, n;
|
||||
portal_t *p, *portals[6];
|
||||
plane_t bplanes[6];
|
||||
node_t *node;
|
||||
|
||||
node = tree->headnode;
|
||||
void MakeHeadnodePortals( tree_t& tree ){
|
||||
portal_t *portals[6];
|
||||
|
||||
// pad with some space so there will never be null volume leafs
|
||||
const MinMax bounds( tree->minmax.mins - Vector3( SIDESPACE ),
|
||||
tree->minmax.maxs + Vector3( SIDESPACE ) );
|
||||
const MinMax bounds( tree.minmax.mins - Vector3( SIDESPACE ),
|
||||
tree.minmax.maxs + Vector3( SIDESPACE ) );
|
||||
if ( !bounds.valid() ) {
|
||||
Error( "Backwards tree volume" );
|
||||
}
|
||||
|
||||
tree->outside_node.planenum = PLANENUM_LEAF;
|
||||
tree->outside_node.brushlist = NULL;
|
||||
tree->outside_node.portals = NULL;
|
||||
tree->outside_node.opaque = false;
|
||||
tree.outside_node.planenum = PLANENUM_LEAF;
|
||||
tree.outside_node.brushlist.clear();
|
||||
tree.outside_node.portals = NULL;
|
||||
tree.outside_node.opaque = false;
|
||||
|
||||
for ( i = 0 ; i < 3 ; i++ )
|
||||
for ( j = 0 ; j < 2 ; j++ )
|
||||
for ( int i = 0 ; i < 3 ; i++ )
|
||||
for ( int j = 0 ; j < 2 ; j++ )
|
||||
{
|
||||
n = j * 3 + i;
|
||||
portal_t *p = portals[j * 3 + i] = AllocPortal();
|
||||
|
||||
p = AllocPortal();
|
||||
portals[n] = p;
|
||||
|
||||
plane_t *pl = &bplanes[n];
|
||||
memset( pl, 0, sizeof( *pl ) );
|
||||
if ( j ) {
|
||||
pl->normal()[i] = -1;
|
||||
pl->dist() = -bounds.maxs[i];
|
||||
p->plane.plane = Plane3f( -g_vector3_axes[i], -bounds.maxs[i] );
|
||||
}
|
||||
else
|
||||
{
|
||||
pl->normal()[i] = 1;
|
||||
pl->dist() = bounds.mins[i];
|
||||
p->plane.plane = Plane3f( g_vector3_axes[i], bounds.mins[i] );
|
||||
}
|
||||
p->plane = *pl;
|
||||
p->winding = BaseWindingForPlane( pl->plane );
|
||||
AddPortalToNodes( p, node, &tree->outside_node );
|
||||
p->winding = BaseWindingForPlane( p->plane.plane );
|
||||
AddPortalToNodes( p, tree.headnode, &tree.outside_node );
|
||||
}
|
||||
|
||||
// clip the basewindings by all the other planes
|
||||
for ( i = 0 ; i < 6 ; i++ )
|
||||
for ( int i = 0 ; i < 6 ; i++ )
|
||||
{
|
||||
for ( j = 0 ; j < 6 ; j++ )
|
||||
for ( int j = 0 ; j < 6 ; j++ )
|
||||
{
|
||||
if ( j == i ) {
|
||||
continue;
|
||||
}
|
||||
ChopWindingInPlace( portals[i]->winding, bplanes[j].plane, ON_EPSILON );
|
||||
ChopWindingInPlace( portals[i]->winding, portals[j]->plane.plane, ON_EPSILON );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -237,14 +207,11 @@ void MakeHeadnodePortals( tree_t *tree ){
|
|||
#define BASE_WINDING_EPSILON 0.001
|
||||
#define SPLIT_WINDING_EPSILON 0.001
|
||||
|
||||
winding_t *BaseWindingForNode( node_t *node ){
|
||||
winding_t *w;
|
||||
node_t *n;
|
||||
|
||||
w = BaseWindingForPlane( mapplanes[node->planenum].plane );
|
||||
winding_t BaseWindingForNode( const node_t *node ){
|
||||
winding_t w = BaseWindingForPlane( mapplanes[node->planenum].plane );
|
||||
|
||||
// clip by all the parents
|
||||
for ( n = node->parent ; n && w ; )
|
||||
for ( const node_t *n = node->parent; n && !w.empty(); )
|
||||
{
|
||||
const plane_t& plane = mapplanes[n->planenum];
|
||||
|
||||
|
|
@ -273,14 +240,12 @@ winding_t *BaseWindingForNode( node_t *node ){
|
|||
==================
|
||||
*/
|
||||
void MakeNodePortal( node_t *node ){
|
||||
portal_t *new_portal, *p;
|
||||
winding_t *w;
|
||||
int side;
|
||||
|
||||
w = BaseWindingForNode( node );
|
||||
winding_t w = BaseWindingForNode( node );
|
||||
|
||||
// clip the portal by all the other portals in the node
|
||||
for ( p = node->portals ; p && w; p = p->next[side] )
|
||||
for ( const portal_t *p = node->portals; p && !w.empty(); p = p->next[side] )
|
||||
{
|
||||
if ( p->nodes[0] == node ) {
|
||||
side = 0;
|
||||
|
|
@ -296,7 +261,7 @@ void MakeNodePortal( node_t *node ){
|
|||
|
||||
}
|
||||
|
||||
if ( !w ) {
|
||||
if ( w.empty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -305,21 +270,19 @@ void MakeNodePortal( node_t *node ){
|
|||
#if 0
|
||||
if ( !FixWinding( w ) ) {
|
||||
c_badportals++;
|
||||
FreeWinding( w );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( WindingIsTiny( *w ) ) {
|
||||
if ( WindingIsTiny( w ) ) {
|
||||
c_tinyportals++;
|
||||
FreeWinding( w );
|
||||
return;
|
||||
}
|
||||
|
||||
new_portal = AllocPortal();
|
||||
portal_t *new_portal = AllocPortal();
|
||||
new_portal->plane = mapplanes[node->planenum];
|
||||
new_portal->onnode = node;
|
||||
new_portal->winding = w;
|
||||
new_portal->winding.swap( w );
|
||||
new_portal->compileFlags = node->compileFlags;
|
||||
AddPortalToNodes( new_portal, node->children[0], node->children[1] );
|
||||
}
|
||||
|
|
@ -334,17 +297,15 @@ void MakeNodePortal( node_t *node ){
|
|||
==============
|
||||
*/
|
||||
void SplitNodePortals( node_t *node ){
|
||||
portal_t *p, *next_portal, *new_portal;
|
||||
node_t *f, *b, *other_node;
|
||||
int side;
|
||||
winding_t *frontwinding, *backwinding;
|
||||
|
||||
const plane_t& plane = mapplanes[node->planenum];
|
||||
f = node->children[0];
|
||||
b = node->children[1];
|
||||
|
||||
for ( p = node->portals ; p ; p = next_portal )
|
||||
for ( portal_t *next_portal, *p = node->portals; p; p = next_portal )
|
||||
{
|
||||
int side;
|
||||
if ( p->nodes[0] == node ) {
|
||||
side = 0;
|
||||
}
|
||||
|
|
@ -363,45 +324,41 @@ void SplitNodePortals( node_t *node ){
|
|||
//
|
||||
// cut the portal into two portals, one on each side of the cut plane
|
||||
//
|
||||
ClipWindingEpsilon( *p->winding, plane.plane,
|
||||
SPLIT_WINDING_EPSILON, frontwinding, backwinding ); /* not strict, we want to always keep one of them even if coplanar */
|
||||
auto [frontwinding, backwinding] = ClipWindingEpsilon( p->winding, plane.plane, SPLIT_WINDING_EPSILON ); /* not strict, we want to always keep one of them even if coplanar */
|
||||
|
||||
if ( frontwinding && WindingIsTiny( *frontwinding ) ) {
|
||||
if ( !frontwinding.empty() && WindingIsTiny( frontwinding ) ) {
|
||||
if ( !f->tinyportals ) {
|
||||
f->referencepoint = ( *frontwinding )[0];
|
||||
f->referencepoint = frontwinding[0];
|
||||
}
|
||||
f->tinyportals++;
|
||||
if ( !other_node->tinyportals ) {
|
||||
other_node->referencepoint = ( *frontwinding )[0];
|
||||
other_node->referencepoint = frontwinding[0];
|
||||
}
|
||||
other_node->tinyportals++;
|
||||
|
||||
FreeWinding( frontwinding );
|
||||
frontwinding = NULL;
|
||||
frontwinding.clear();
|
||||
c_tinyportals++;
|
||||
}
|
||||
|
||||
if ( backwinding && WindingIsTiny( *backwinding ) ) {
|
||||
if ( !backwinding.empty() && WindingIsTiny( backwinding ) ) {
|
||||
if ( !b->tinyportals ) {
|
||||
b->referencepoint = ( *backwinding )[0];
|
||||
b->referencepoint = backwinding[0];
|
||||
}
|
||||
b->tinyportals++;
|
||||
if ( !other_node->tinyportals ) {
|
||||
other_node->referencepoint = ( *backwinding )[0];
|
||||
other_node->referencepoint = backwinding[0];
|
||||
}
|
||||
other_node->tinyportals++;
|
||||
|
||||
FreeWinding( backwinding );
|
||||
backwinding = NULL;
|
||||
backwinding.clear();
|
||||
c_tinyportals++;
|
||||
}
|
||||
|
||||
if ( !frontwinding && !backwinding ) { // tiny windings on both sides
|
||||
if ( frontwinding.empty() && backwinding.empty() ) { // tiny windings on both sides
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !frontwinding ) {
|
||||
FreeWinding( backwinding );
|
||||
if ( frontwinding.empty() ) {
|
||||
if ( side == 0 ) {
|
||||
AddPortalToNodes( p, b, other_node );
|
||||
}
|
||||
|
|
@ -410,8 +367,7 @@ void SplitNodePortals( node_t *node ){
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if ( !backwinding ) {
|
||||
FreeWinding( frontwinding );
|
||||
if ( backwinding.empty() ) {
|
||||
if ( side == 0 ) {
|
||||
AddPortalToNodes( p, f, other_node );
|
||||
}
|
||||
|
|
@ -422,11 +378,10 @@ void SplitNodePortals( node_t *node ){
|
|||
}
|
||||
|
||||
// the winding is split
|
||||
new_portal = AllocPortal();
|
||||
*new_portal = *p;
|
||||
new_portal->winding = backwinding;
|
||||
FreeWinding( p->winding );
|
||||
p->winding = frontwinding;
|
||||
p->winding.clear();
|
||||
portal_t *new_portal = new portal_t( *p ); // AllocPortal()
|
||||
new_portal->winding.swap( backwinding );
|
||||
p->winding.swap( frontwinding );
|
||||
|
||||
if ( side == 0 ) {
|
||||
AddPortalToNodes( p, f, other_node );
|
||||
|
|
@ -457,7 +412,7 @@ void CalcNodeBounds( node_t *node ){
|
|||
for ( p = node->portals; p; p = p->next[s] )
|
||||
{
|
||||
s = ( p->nodes[1] == node );
|
||||
WindingExtendBounds( *p->winding, node->minmax );
|
||||
WindingExtendBounds( p->winding, node->minmax );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -479,8 +434,8 @@ void MakeTreePortals_r( node_t *node ){
|
|||
}
|
||||
|
||||
if ( !c_worldMinmax.surrounds( node->minmax ) ) {
|
||||
if ( node->portals && node->portals->winding ) {
|
||||
xml_Winding( "WARNING: Node With Unbounded Volume", node->portals->winding->data(), node->portals->winding->size(), false );
|
||||
if ( node->portals && !node->portals->winding.empty() ) {
|
||||
xml_Winding( "WARNING: Node With Unbounded Volume", node->portals->winding.data(), node->portals->winding.size(), false );
|
||||
}
|
||||
}
|
||||
if ( node->planenum == PLANENUM_LEAF ) {
|
||||
|
|
@ -499,10 +454,10 @@ void MakeTreePortals_r( node_t *node ){
|
|||
MakeTreePortals
|
||||
==================
|
||||
*/
|
||||
void MakeTreePortals( tree_t *tree ){
|
||||
void MakeTreePortals( tree_t& tree ){
|
||||
Sys_FPrintf( SYS_VRB, "--- MakeTreePortals ---\n" );
|
||||
MakeHeadnodePortals( tree );
|
||||
MakeTreePortals_r( tree->headnode );
|
||||
MakeTreePortals_r( tree.headnode );
|
||||
Sys_FPrintf( SYS_VRB, "%9d tiny portals\n", c_tinyportals );
|
||||
Sys_FPrintf( SYS_VRB, "%9d bad portals\n", c_badportals ); /* ydnar */
|
||||
}
|
||||
|
|
@ -591,16 +546,14 @@ bool PlaceOccupant( node_t *headnode, const Vector3& origin, const entity_t *occ
|
|||
=============
|
||||
*/
|
||||
|
||||
EFloodEntities FloodEntities( tree_t *tree ){
|
||||
EFloodEntities FloodEntities( tree_t& tree ){
|
||||
bool r, inside, skybox;
|
||||
node_t *headnode;
|
||||
const char *value;
|
||||
|
||||
|
||||
headnode = tree->headnode;
|
||||
Sys_FPrintf( SYS_VRB, "--- FloodEntities ---\n" );
|
||||
inside = false;
|
||||
tree->outside_node.occupied = 0;
|
||||
tree.outside_node.occupied = 0;
|
||||
|
||||
c_floodedleafs = 0;
|
||||
for ( std::size_t i = 1; i < entities.size(); ++i )
|
||||
|
|
@ -617,7 +570,7 @@ EFloodEntities FloodEntities( tree_t *tree ){
|
|||
}
|
||||
#endif
|
||||
/* also allow bmodel entities outside, as they could be on a moving path that will go into the map */
|
||||
if ( e.brushes != NULL || e.patches != NULL || e.classname_is( "_decal" ) ) { //_decal primitive is freed at this point
|
||||
if ( !e.brushes.empty() || e.patches != NULL || e.classname_is( "_decal" ) ) { //_decal primitive is freed at this point
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -653,7 +606,7 @@ EFloodEntities FloodEntities( tree_t *tree ){
|
|||
//% origin[ 2 ] += 4096;
|
||||
|
||||
/* find leaf */
|
||||
r = PlaceOccupant( headnode, origin, &e, skybox );
|
||||
r = PlaceOccupant( tree.headnode, origin, &e, skybox );
|
||||
if ( r ) {
|
||||
inside = true;
|
||||
}
|
||||
|
|
@ -668,7 +621,7 @@ EFloodEntities FloodEntities( tree_t *tree ){
|
|||
Sys_FPrintf( SYS_WRN | SYS_VRBflag, "no entities in open -- no filling\n" );
|
||||
return EFloodEntities::Empty;
|
||||
}
|
||||
if ( tree->outside_node.occupied ) {
|
||||
if ( tree.outside_node.occupied ) {
|
||||
Sys_FPrintf( SYS_WRN | SYS_VRBflag, "entity reached from outside -- leak detected\n" );
|
||||
return EFloodEntities::Leaked;
|
||||
}
|
||||
|
|
@ -696,7 +649,6 @@ int c_areas;
|
|||
void FloodAreas_r( node_t *node ){
|
||||
int s;
|
||||
portal_t *p;
|
||||
brush_t *b;
|
||||
|
||||
|
||||
if ( node->areaportal ) {
|
||||
|
|
@ -705,7 +657,7 @@ void FloodAreas_r( node_t *node ){
|
|||
}
|
||||
|
||||
/* this node is part of an area portal brush */
|
||||
b = node->brushlist->original;
|
||||
brush_t *b = node->brushlist.front().original;
|
||||
|
||||
/* if the current area has already touched this portal, we are done */
|
||||
if ( b->portalareas[ 0 ] == c_areas || b->portalareas[ 1 ] == c_areas ) {
|
||||
|
|
@ -786,9 +738,7 @@ void FindAreas_r( node_t *node ){
|
|||
CheckAreas_r
|
||||
=============
|
||||
*/
|
||||
void CheckAreas_r( node_t *node ){
|
||||
brush_t *b;
|
||||
|
||||
void CheckAreas_r( const node_t *node ){
|
||||
if ( node->planenum != PLANENUM_LEAF ) {
|
||||
CheckAreas_r( node->children[0] );
|
||||
CheckAreas_r( node->children[1] );
|
||||
|
|
@ -805,7 +755,7 @@ void CheckAreas_r( node_t *node ){
|
|||
}
|
||||
}
|
||||
if ( node->areaportal ) {
|
||||
b = node->brushlist->original;
|
||||
const brush_t *b = node->brushlist.front().original;
|
||||
|
||||
// check if the areaportal touches two areas
|
||||
if ( b->portalareas[0] == -1 || b->portalareas[1] == -1 ) {
|
||||
|
|
@ -846,16 +796,16 @@ void FloodSkyboxArea_r( node_t *node ){
|
|||
mark each leaf with an area, bounded by C_AREAPORTAL
|
||||
*/
|
||||
|
||||
void FloodAreas( tree_t *tree ){
|
||||
void FloodAreas( tree_t& tree ){
|
||||
Sys_FPrintf( SYS_VRB, "--- FloodAreas ---\n" );
|
||||
FindAreas_r( tree->headnode );
|
||||
FindAreas_r( tree.headnode );
|
||||
|
||||
/* ydnar: flood all skybox nodes */
|
||||
FloodSkyboxArea_r( tree->headnode );
|
||||
FloodSkyboxArea_r( tree.headnode );
|
||||
|
||||
/* check for areaportal brushes that don't touch two areas */
|
||||
/* ydnar: fix this rather than just silence the warnings */
|
||||
//% CheckAreas_r( tree->headnode );
|
||||
//% CheckAreas_r( tree.headnode );
|
||||
|
||||
Sys_FPrintf( SYS_VRB, "%9d areas\n", c_areas );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ void WriteFloat( FILE *f, float v ){
|
|||
}
|
||||
}
|
||||
|
||||
void CountVisportals_r( node_t *node ){
|
||||
void CountVisportals_r( const node_t *node ){
|
||||
int s;
|
||||
|
||||
// decision node
|
||||
|
|
@ -75,9 +75,8 @@ void CountVisportals_r( node_t *node ){
|
|||
|
||||
for ( const portal_t *p = node->portals; p; p = p->next[s] )
|
||||
{
|
||||
const winding_t *w = p->winding;
|
||||
s = ( p->nodes[1] == node );
|
||||
if ( w && p->nodes[0] == node ) {
|
||||
if ( !p->winding.empty() && p->nodes[0] == node ) {
|
||||
if ( !PortalPassable( p ) ) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -94,7 +93,7 @@ void CountVisportals_r( node_t *node ){
|
|||
WritePortalFile_r
|
||||
=================
|
||||
*/
|
||||
void WritePortalFile_r( node_t *node ){
|
||||
void WritePortalFile_r( const node_t *node ){
|
||||
int s, flags;
|
||||
|
||||
// decision node
|
||||
|
|
@ -110,9 +109,9 @@ void WritePortalFile_r( node_t *node ){
|
|||
|
||||
for (const portal_t *p = node->portals; p; p = p->next[s] )
|
||||
{
|
||||
const winding_t *w = p->winding;
|
||||
const winding_t& w = p->winding;
|
||||
s = ( p->nodes[1] == node );
|
||||
if ( w && p->nodes[0] == node ) {
|
||||
if ( !w.empty() && p->nodes[0] == node ) {
|
||||
if ( !PortalPassable( p ) ) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -126,11 +125,11 @@ void WritePortalFile_r( node_t *node ){
|
|||
// the changeover point between different axis. interpret the
|
||||
// plane the same way vis will, and flip the side orders if needed
|
||||
// FIXME: is this still relevant?
|
||||
if ( vector3_dot( p->plane.normal(), WindingPlane( *w ).normal() ) < 0.99 ) { // backwards...
|
||||
fprintf( pf, "%zu %i %i ", w->size(), p->nodes[1]->cluster, p->nodes[0]->cluster );
|
||||
if ( vector3_dot( p->plane.normal(), WindingPlane( w ).normal() ) < 0.99 ) { // backwards...
|
||||
fprintf( pf, "%zu %i %i ", w.size(), p->nodes[1]->cluster, p->nodes[0]->cluster );
|
||||
}
|
||||
else{
|
||||
fprintf( pf, "%zu %i %i ", w->size(), 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;
|
||||
|
|
@ -148,7 +147,7 @@ void WritePortalFile_r( node_t *node ){
|
|||
fprintf( pf, "%d ", flags );
|
||||
|
||||
/* write the winding */
|
||||
for ( const Vector3 point : *w )
|
||||
for ( const Vector3 point : w )
|
||||
{
|
||||
fprintf( pf, "(" );
|
||||
WriteFloat( pf, point.x() );
|
||||
|
|
@ -162,7 +161,7 @@ void WritePortalFile_r( node_t *node ){
|
|||
|
||||
}
|
||||
|
||||
void CountSolidFaces_r( node_t *node ){
|
||||
void CountSolidFaces_r( const node_t *node ){
|
||||
int s;
|
||||
|
||||
// decision node
|
||||
|
|
@ -178,9 +177,8 @@ void CountSolidFaces_r( node_t *node ){
|
|||
|
||||
for ( const portal_t *p = node->portals; p; p = p->next[s] )
|
||||
{
|
||||
const winding_t *w = p->winding;
|
||||
s = ( p->nodes[1] == node );
|
||||
if ( w ) {
|
||||
if ( !p->winding.empty() ) {
|
||||
if ( PortalPassable( p ) ) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -199,7 +197,7 @@ void CountSolidFaces_r( node_t *node ){
|
|||
WriteFaceFile_r
|
||||
=================
|
||||
*/
|
||||
void WriteFaceFile_r( node_t *node ){
|
||||
void WriteFaceFile_r( const node_t *node ){
|
||||
int s;
|
||||
|
||||
// decision node
|
||||
|
|
@ -215,9 +213,9 @@ void WriteFaceFile_r( node_t *node ){
|
|||
|
||||
for ( const portal_t *p = node->portals; p; p = p->next[s] )
|
||||
{
|
||||
const winding_t *w = p->winding;
|
||||
const winding_t& w = p->winding;
|
||||
s = ( p->nodes[1] == node );
|
||||
if ( w ) {
|
||||
if ( !w.empty() ) {
|
||||
if ( PortalPassable( p ) ) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -227,8 +225,8 @@ void WriteFaceFile_r( node_t *node ){
|
|||
// write out to the file
|
||||
|
||||
if ( p->nodes[0] == node ) {
|
||||
fprintf( pf, "%zu %i ", w->size(), p->nodes[0]->cluster );
|
||||
for ( const Vector3& point : *w )
|
||||
fprintf( pf, "%zu %i ", w.size(), p->nodes[0]->cluster );
|
||||
for ( const Vector3& point : w )
|
||||
{
|
||||
fprintf( pf, "(" );
|
||||
WriteFloat( pf, point.x() );
|
||||
|
|
@ -240,8 +238,8 @@ void WriteFaceFile_r( node_t *node ){
|
|||
}
|
||||
else
|
||||
{
|
||||
fprintf( pf, "%zu %i ", w->size(), p->nodes[1]->cluster );
|
||||
for ( winding_t::const_reverse_iterator point = w->crbegin(); point != w->crend(); ++point )
|
||||
fprintf( pf, "%zu %i ", w.size(), p->nodes[1]->cluster );
|
||||
for ( winding_t::const_reverse_iterator point = w.crbegin(); point != w.crend(); ++point )
|
||||
{
|
||||
fprintf( pf, "(" );
|
||||
WriteFloat( pf, point->x() );
|
||||
|
|
@ -332,7 +330,7 @@ void NumberLeafs_r( node_t *node, int c ){
|
|||
NumberClusters
|
||||
================
|
||||
*/
|
||||
void NumberClusters( tree_t *tree ) {
|
||||
void NumberClusters( tree_t& tree ) {
|
||||
num_visclusters = 0;
|
||||
num_visportals = 0;
|
||||
num_solidfaces = 0;
|
||||
|
|
@ -340,9 +338,9 @@ void NumberClusters( tree_t *tree ) {
|
|||
Sys_FPrintf( SYS_VRB, "--- NumberClusters ---\n" );
|
||||
|
||||
// set the cluster field in every leaf and count the total number of portals
|
||||
NumberLeafs_r( tree->headnode, -1 );
|
||||
CountVisportals_r( tree->headnode );
|
||||
CountSolidFaces_r( tree->headnode );
|
||||
NumberLeafs_r( tree.headnode, -1 );
|
||||
CountVisportals_r( tree.headnode );
|
||||
CountSolidFaces_r( tree.headnode );
|
||||
|
||||
Sys_FPrintf( SYS_VRB, "%9d visclusters\n", num_visclusters );
|
||||
Sys_FPrintf( SYS_VRB, "%9d visportals\n", num_visportals );
|
||||
|
|
@ -354,7 +352,7 @@ void NumberClusters( tree_t *tree ) {
|
|||
WritePortalFile
|
||||
================
|
||||
*/
|
||||
void WritePortalFile( tree_t *tree ){
|
||||
void WritePortalFile( const tree_t& tree ){
|
||||
Sys_FPrintf( SYS_VRB, "--- WritePortalFile ---\n" );
|
||||
|
||||
// write the file
|
||||
|
|
@ -367,8 +365,8 @@ void WritePortalFile( tree_t *tree ){
|
|||
fprintf( pf, "%i\n", num_visportals );
|
||||
fprintf( pf, "%i\n", num_solidfaces );
|
||||
|
||||
WritePortalFile_r( tree->headnode );
|
||||
WriteFaceFile_r( tree->headnode );
|
||||
WritePortalFile_r( tree.headnode );
|
||||
WriteFaceFile_r( tree.headnode );
|
||||
|
||||
fclose( pf );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -739,9 +739,9 @@ struct side_t
|
|||
Vector3 texMat[ 2 ]; /* brush primitive texture matrix */
|
||||
Vector4 vecs[ 2 ]; /* old-style texture coordinate mapping */
|
||||
|
||||
Plane3 plane; /* optional plane in double precision for building windings */
|
||||
winding_t *winding;
|
||||
winding_t *visibleHull; /* convex hull of all visible fragments */
|
||||
Plane3 plane{ 0, 0, 0, 0 }; /* optional plane in double precision for building windings */
|
||||
winding_t winding;
|
||||
winding_t visibleHull; /* convex hull of all visible fragments */
|
||||
|
||||
shaderInfo_t *shaderInfo;
|
||||
|
||||
|
|
@ -759,7 +759,7 @@ struct side_t
|
|||
struct sideRef_t
|
||||
{
|
||||
sideRef_t *next;
|
||||
side_t *side;
|
||||
const side_t *side;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -775,8 +775,6 @@ struct indexMap_t
|
|||
|
||||
struct brush_t
|
||||
{
|
||||
brush_t *next;
|
||||
brush_t *nextColorModBrush; /* ydnar: colorMod volume brushes go here */
|
||||
brush_t *original; /* chopped up brushes will reference the originals */
|
||||
|
||||
int entityNum, brushNum; /* editor numbering */
|
||||
|
|
@ -804,16 +802,16 @@ struct brush_t
|
|||
int portalareas[ 2 ];
|
||||
|
||||
MinMax minmax;
|
||||
int numsides;
|
||||
|
||||
side_t sides[]; /* variably sized */
|
||||
std::vector<side_t> sides;
|
||||
};
|
||||
using brushlist_t = std::list<brush_t>;
|
||||
|
||||
|
||||
struct fog_t
|
||||
{
|
||||
shaderInfo_t *si;
|
||||
brush_t *brush;
|
||||
const brush_t *brush;
|
||||
int visibleSide; /* the brush side that ray tests need to clip against (-1 == none) */
|
||||
};
|
||||
|
||||
|
|
@ -914,7 +912,7 @@ struct mapDrawSurface_t
|
|||
|
||||
shaderInfo_t *shaderInfo;
|
||||
shaderInfo_t *celShader;
|
||||
brush_t *mapBrush;
|
||||
const brush_t *mapBrush;
|
||||
parseMesh_t *mapMesh;
|
||||
sideRef_t *sideRef;
|
||||
|
||||
|
|
@ -974,7 +972,7 @@ struct drawSurfRef_t
|
|||
struct metaTriangle_t
|
||||
{
|
||||
shaderInfo_t *si;
|
||||
side_t *side;
|
||||
const side_t *side;
|
||||
int entityNum, surfaceNum, planeNum, fogNum, sampleSize, castShadows, recvShadows;
|
||||
float shadeAngleDegrees;
|
||||
Plane3f plane;
|
||||
|
|
@ -992,7 +990,8 @@ struct epair_t
|
|||
struct entity_t
|
||||
{
|
||||
Vector3 origin{ 0 };
|
||||
brush_t *brushes, *lastBrush, *colorModBrushes;
|
||||
brushlist_t brushes;
|
||||
std::vector<brush_t*> colorModBrushes;
|
||||
parseMesh_t *patches;
|
||||
int mapEntityNum, firstDrawSurf;
|
||||
int firstBrush, numBrushes; /* only valid during BSP compile */
|
||||
|
|
@ -1059,10 +1058,8 @@ struct node_t
|
|||
int planenum; /* -1 = leaf node */
|
||||
node_t *parent;
|
||||
MinMax minmax; /* valid after portalization */
|
||||
brush_t *volume; /* one for each leaf/node */
|
||||
|
||||
/* nodes only */
|
||||
side_t *side; /* the side that created the node */
|
||||
node_t *children[ 2 ];
|
||||
int compileFlags; /* ydnar: hint, antiportal */
|
||||
int tinyportals;
|
||||
|
|
@ -1075,7 +1072,7 @@ struct node_t
|
|||
bool sky; /* ydnar: a sky leaf */
|
||||
int cluster; /* for portalfile writing */
|
||||
int area; /* for areaportals */
|
||||
brush_t *brushlist; /* fragments of all brushes in this leaf */
|
||||
brushlist_t brushlist; /* fragments of all brushes in this leaf */
|
||||
drawSurfRef_t *drawSurfReferences;
|
||||
|
||||
int occupied; /* 1 or greater can reach entity */
|
||||
|
|
@ -1093,11 +1090,10 @@ struct portal_t
|
|||
node_t *onnode; /* NULL = outside box */
|
||||
node_t *nodes[ 2 ]; /* [ 0 ] = front side of plane */
|
||||
portal_t *next[ 2 ];
|
||||
winding_t *winding;
|
||||
winding_t winding;
|
||||
|
||||
bool sidefound; /* false if ->side hasn't been checked */
|
||||
int compileFlags; /* from original face that caused the split */
|
||||
side_t *side; /* NULL = non-visible */
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1551,28 +1547,20 @@ int ConvertBSPToOBJ( char *bspName );
|
|||
|
||||
|
||||
/* brush.c */
|
||||
sideRef_t *AllocSideRef( side_t *side, sideRef_t *next );
|
||||
int CountBrushList( brush_t *brushes );
|
||||
brush_t *AllocBrush( int numsides );
|
||||
void FreeBrush( brush_t *brushes );
|
||||
void FreeBrushList( brush_t *brushes );
|
||||
brush_t *CopyBrush( const brush_t *brush );
|
||||
bool BoundBrush( brush_t *brush );
|
||||
sideRef_t *AllocSideRef( const side_t *side, sideRef_t *next );
|
||||
bool BoundBrush( brush_t& brush );
|
||||
Vector3 SnapWeldVector( const Vector3& a, const Vector3& b );
|
||||
bool CreateBrushWindings( brush_t *brush );
|
||||
brush_t *BrushFromBounds( const Vector3& mins, const Vector3& maxs );
|
||||
float BrushVolume( brush_t *brush );
|
||||
void WriteBSPBrushMap( const char *name, brush_t *list );
|
||||
bool CreateBrushWindings( brush_t& brush );
|
||||
brush_t BrushFromBounds( const Vector3& mins, const Vector3& maxs );
|
||||
float BrushVolume( const brush_t& brush );
|
||||
void WriteBSPBrushMap( const char *name, const brushlist_t& list );
|
||||
|
||||
void FilterDetailBrushesIntoTree( entity_t *e, tree_t *tree );
|
||||
void FilterStructuralBrushesIntoTree( entity_t *e, tree_t *tree );
|
||||
void FilterDetailBrushesIntoTree( entity_t *e, tree_t& tree );
|
||||
void FilterStructuralBrushesIntoTree( entity_t *e, tree_t& tree );
|
||||
|
||||
bool WindingIsTiny( const winding_t& w );
|
||||
|
||||
void SplitBrush( brush_t *brush, int planenum, brush_t **front, brush_t **back );
|
||||
|
||||
tree_t *AllocTree( void );
|
||||
node_t *AllocNode( void );
|
||||
std::pair<brush_t*, brush_t*> SplitBrush( const brush_t& brush, int planenum );
|
||||
|
||||
|
||||
/* mesh.c */
|
||||
|
|
@ -1600,11 +1588,10 @@ inline int FindFloatPlane( const Vector3& normal, float dist, i
|
|||
}
|
||||
bool PlaneEqual( const plane_t& p, const Plane3f& plane );
|
||||
void AddBrushBevels( void );
|
||||
brush_t *FinishBrush( bool noCollapseGroups );
|
||||
|
||||
|
||||
/* portals.c */
|
||||
void MakeHeadnodePortals( tree_t *tree );
|
||||
void MakeHeadnodePortals( tree_t& tree );
|
||||
void MakeNodePortal( node_t *node );
|
||||
void SplitNodePortals( node_t *node );
|
||||
|
||||
|
|
@ -1616,32 +1603,33 @@ enum class EFloodEntities
|
|||
Good,
|
||||
Empty
|
||||
};
|
||||
EFloodEntities FloodEntities( tree_t *tree );
|
||||
EFloodEntities FloodEntities( tree_t& tree );
|
||||
void FillOutside( node_t *headnode );
|
||||
void FloodAreas( tree_t *tree );
|
||||
void FreePortal( portal_t *p );
|
||||
void FloodAreas( tree_t& tree );
|
||||
inline portal_t *AllocPortal( void ){ return new portal_t(); }
|
||||
inline void FreePortal( portal_t *p ){ delete p; }
|
||||
|
||||
void MakeTreePortals( tree_t *tree );
|
||||
void MakeTreePortals( tree_t& tree );
|
||||
|
||||
|
||||
/* leakfile.c */
|
||||
xmlNodePtr LeakFile( tree_t *tree );
|
||||
xmlNodePtr LeakFile( const tree_t& tree );
|
||||
|
||||
|
||||
/* prtfile.c */
|
||||
void NumberClusters( tree_t *tree );
|
||||
void WritePortalFile( tree_t *tree );
|
||||
void NumberClusters( tree_t& tree );
|
||||
void WritePortalFile( const tree_t& tree );
|
||||
|
||||
|
||||
/* writebsp.c */
|
||||
void SetModelNumbers( void );
|
||||
void SetLightStyles( void );
|
||||
|
||||
int EmitShader( const char *shader, int *contentFlags, int *surfaceFlags );
|
||||
int EmitShader( const char *shader, const int *contentFlags, const int *surfaceFlags );
|
||||
|
||||
void BeginBSPFile( void );
|
||||
void EndBSPFile( bool do_write );
|
||||
void EmitBrushes( brush_t *brushes, int *firstBrush, int *numBrushes );
|
||||
void EmitBrushes( brushlist_t& brushes, int *firstBrush, int *numBrushes );
|
||||
void EmitFogs( void );
|
||||
|
||||
void BeginModel( void );
|
||||
|
|
@ -1649,10 +1637,11 @@ void EndModel( entity_t *e, node_t *headnode );
|
|||
|
||||
|
||||
/* tree.c */
|
||||
void FreeTree( tree_t *tree );
|
||||
void FreeTree( tree_t& tree );
|
||||
void FreeTree_r( node_t *node );
|
||||
void PrintTree_r( node_t *node, int depth );
|
||||
void PrintTree_r( const node_t *node, int depth );
|
||||
void FreeTreePortals_r( node_t *node );
|
||||
inline node_t *AllocNode(){ return new node_t(); }
|
||||
|
||||
|
||||
/* patch.c */
|
||||
|
|
@ -1667,7 +1656,7 @@ void FixTJunctions( entity_t *e );
|
|||
|
||||
|
||||
/* fog.c */
|
||||
winding_t *WindingFromDrawSurf( mapDrawSurface_t *ds );
|
||||
winding_t WindingFromDrawSurf( const mapDrawSurface_t *ds );
|
||||
void FogDrawSurfaces( entity_t *e );
|
||||
int FogForPoint( const Vector3& point, float epsilon );
|
||||
int FogForBounds( const MinMax& minmax, float epsilon );
|
||||
|
|
@ -1675,9 +1664,9 @@ void CreateMapFogs( void );
|
|||
|
||||
|
||||
/* facebsp.c */
|
||||
facelist_t MakeStructuralBSPFaceList( const brush_t *list );
|
||||
facelist_t MakeVisibleBSPFaceList( const brush_t *list );
|
||||
tree_t *FaceBSP( facelist_t& list );
|
||||
facelist_t MakeStructuralBSPFaceList( const brushlist_t& list );
|
||||
facelist_t MakeVisibleBSPFaceList( const brushlist_t& list );
|
||||
tree_t FaceBSP( facelist_t& list );
|
||||
|
||||
|
||||
/* model.c */
|
||||
|
|
@ -1701,17 +1690,17 @@ mapDrawSurface_t *MakeCelSurface( mapDrawSurface_t *src, shaderInfo_t
|
|||
bool IsTriangleDegenerate( bspDrawVert_t *points, int a, int b, int c );
|
||||
void ClearSurface( mapDrawSurface_t *ds );
|
||||
void AddEntitySurfaceModels( entity_t *e );
|
||||
mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, const winding_t& w );
|
||||
mapDrawSurface_t *DrawSurfaceForSide( const entity_t *e, const brush_t& b, const side_t& s, const winding_t& w );
|
||||
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 *DrawSurfaceForShader( const char *shader );
|
||||
void ClipSidesIntoTree( entity_t *e, tree_t *tree );
|
||||
void MakeDebugPortalSurfs( tree_t *tree );
|
||||
void MakeFogHullSurfs( entity_t *e, tree_t *tree, const char *shader );
|
||||
void SubdivideFaceSurfaces( entity_t *e, tree_t *tree );
|
||||
void ClipSidesIntoTree( entity_t *e, const tree_t& tree );
|
||||
void MakeDebugPortalSurfs( const tree_t& tree );
|
||||
void MakeFogHullSurfs( entity_t *e, const char *shader );
|
||||
void SubdivideFaceSurfaces( entity_t *e );
|
||||
void AddEntitySurfaceModels( entity_t *e );
|
||||
int AddSurfaceModels( mapDrawSurface_t *ds );
|
||||
void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree );
|
||||
void FilterDrawsurfsIntoTree( entity_t *e, tree_t& tree );
|
||||
void EmitPatchSurface( entity_t *e, mapDrawSurface_t *ds );
|
||||
void EmitTriangleSurface( mapDrawSurface_t *ds );
|
||||
|
||||
|
|
@ -2112,7 +2101,7 @@ Q_EXTERN int numMapFogs Q_ASSIGN( 0 );
|
|||
Q_EXTERN fog_t mapFogs[ MAX_MAP_FOGS ];
|
||||
|
||||
Q_EXTERN entity_t *mapEnt;
|
||||
Q_EXTERN brush_t *buildBrush;
|
||||
Q_EXTERN brush_t buildBrush;
|
||||
Q_EXTERN EBrushType g_brushType Q_ASSIGN( EBrushType::Undefined );
|
||||
|
||||
Q_EXTERN int numStrippedLights Q_ASSIGN( 0 );
|
||||
|
|
|
|||
|
|
@ -761,12 +761,13 @@ shaderInfo_t *GetIndexedShader( const shaderInfo_t *parent, const indexMap_t *im
|
|||
/*
|
||||
DrawSurfaceForSide()
|
||||
creates a SURF_FACE drawsurface from a given brush side and winding
|
||||
stores references to given brush and side
|
||||
*/
|
||||
|
||||
const double SNAP_FLOAT_TO_INT = 8.0;
|
||||
const double SNAP_INT_TO_FLOAT = ( 1.0 / SNAP_FLOAT_TO_INT );
|
||||
|
||||
mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, const winding_t& w ){
|
||||
mapDrawSurface_t *DrawSurfaceForSide( const entity_t *e, const brush_t& b, const side_t& s, const winding_t& w ){
|
||||
mapDrawSurface_t *ds;
|
||||
shaderInfo_t *si, *parent;
|
||||
bspDrawVert_t *dv;
|
||||
|
|
@ -779,7 +780,7 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, const
|
|||
|
||||
|
||||
/* ydnar: don't make a drawsurf for culled sides */
|
||||
if ( s->culled ) {
|
||||
if ( s.culled ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -789,24 +790,24 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, const
|
|||
}
|
||||
|
||||
/* get shader */
|
||||
si = s->shaderInfo;
|
||||
si = s.shaderInfo;
|
||||
|
||||
/* ydnar: gs mods: check for indexed shader */
|
||||
if ( si->indexed && b->im != NULL ) {
|
||||
if ( si->indexed && b.im != NULL ) {
|
||||
/* indexed */
|
||||
indexed = true;
|
||||
|
||||
/* get shader indexes for each point */
|
||||
for ( size_t i = 0; i < w.size(); i++ )
|
||||
{
|
||||
shaderIndexes[ i ] = GetShaderIndexForPoint( b->im, b->eMinmax, w[ i ] );
|
||||
offsets[ i ] = b->im->offsets[ shaderIndexes[ i ] ];
|
||||
shaderIndexes[ i ] = GetShaderIndexForPoint( b.im, b.eMinmax, w[ i ] );
|
||||
offsets[ i ] = b.im->offsets[ shaderIndexes[ i ] ];
|
||||
//% Sys_Printf( "%f ", offsets[ i ] );
|
||||
}
|
||||
|
||||
/* get matching shader and set alpha */
|
||||
parent = si;
|
||||
si = GetIndexedShader( parent, b->im, w.size(), shaderIndexes );
|
||||
si = GetIndexedShader( parent, b.im, w.size(), shaderIndexes );
|
||||
}
|
||||
else{
|
||||
indexed = false;
|
||||
|
|
@ -821,25 +822,25 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, const
|
|||
|
||||
/* ydnar: gs mods */
|
||||
ds = AllocDrawSurface( ESurfaceType::Face );
|
||||
ds->entityNum = b->entityNum;
|
||||
ds->castShadows = b->castShadows;
|
||||
ds->recvShadows = b->recvShadows;
|
||||
ds->entityNum = b.entityNum;
|
||||
ds->castShadows = b.castShadows;
|
||||
ds->recvShadows = b.recvShadows;
|
||||
|
||||
ds->planar = true;
|
||||
ds->planeNum = s->planenum;
|
||||
ds->lightmapVecs[ 2 ] = mapplanes[ s->planenum ].normal();
|
||||
ds->planeNum = s.planenum;
|
||||
ds->lightmapVecs[ 2 ] = mapplanes[ s.planenum ].normal();
|
||||
|
||||
ds->shaderInfo = si;
|
||||
ds->mapBrush = b;
|
||||
ds->sideRef = AllocSideRef( s, NULL );
|
||||
ds->mapBrush = &b;
|
||||
ds->sideRef = AllocSideRef( &s, NULL );
|
||||
ds->fogNum = -1;
|
||||
ds->sampleSize = b->lightmapSampleSize;
|
||||
ds->lightmapScale = b->lightmapScale;
|
||||
ds->sampleSize = b.lightmapSampleSize;
|
||||
ds->lightmapScale = b.lightmapScale;
|
||||
ds->numVerts = w.size();
|
||||
ds->verts = safe_calloc( ds->numVerts * sizeof( *ds->verts ) );
|
||||
|
||||
/* 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 */
|
||||
for ( size_t j = 0; j < w.size(); j++ )
|
||||
|
|
@ -874,21 +875,21 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, const
|
|||
/* calculate texture s/t from brush primitive texture matrix */
|
||||
x = vector3_dot( vTranslated, texX );
|
||||
y = vector3_dot( vTranslated, texY );
|
||||
dv->st[ 0 ] = s->texMat[ 0 ][ 0 ] * x + s->texMat[ 0 ][ 1 ] * y + s->texMat[ 0 ][ 2 ];
|
||||
dv->st[ 1 ] = s->texMat[ 1 ][ 0 ] * x + s->texMat[ 1 ][ 1 ] * y + s->texMat[ 1 ][ 2 ];
|
||||
dv->st[ 0 ] = s.texMat[ 0 ][ 0 ] * x + s.texMat[ 0 ][ 1 ] * y + s.texMat[ 0 ][ 2 ];
|
||||
dv->st[ 1 ] = s.texMat[ 1 ][ 0 ] * x + s.texMat[ 1 ][ 1 ] * y + s.texMat[ 1 ][ 2 ];
|
||||
}
|
||||
|
||||
/* old quake-style or valve 220 texturing */
|
||||
else {
|
||||
/* nearest-axial projection */
|
||||
dv->st[ 0 ] = s->vecs[ 0 ][ 3 ] + vector3_dot( s->vecs[ 0 ].vec3(), vTranslated );
|
||||
dv->st[ 1 ] = s->vecs[ 1 ][ 3 ] + vector3_dot( s->vecs[ 1 ].vec3(), vTranslated );
|
||||
dv->st[ 0 ] = s.vecs[ 0 ][ 3 ] + vector3_dot( s.vecs[ 0 ].vec3(), vTranslated );
|
||||
dv->st[ 1 ] = s.vecs[ 1 ][ 3 ] + vector3_dot( s.vecs[ 1 ].vec3(), vTranslated );
|
||||
dv->st[ 0 ] /= si->shaderWidth;
|
||||
dv->st[ 1 ] /= si->shaderHeight;
|
||||
}
|
||||
|
||||
/* copy normal */
|
||||
dv->normal = mapplanes[ s->planenum ].normal();
|
||||
dv->normal = mapplanes[ s.planenum ].normal();
|
||||
|
||||
/* ydnar: set color */
|
||||
for ( int k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
|
|
@ -902,11 +903,11 @@ mapDrawSurface_t *DrawSurfaceForSide( entity_t *e, brush_t *b, side_t *s, const
|
|||
}
|
||||
|
||||
/* set cel shader */
|
||||
ds->celShader = b->celShader;
|
||||
ds->celShader = b.celShader;
|
||||
|
||||
/* set shade angle */
|
||||
if ( b->shadeAngleDegrees > 0.0f ) {
|
||||
ds->shadeAngleDegrees = b->shadeAngleDegrees;
|
||||
if ( b.shadeAngleDegrees > 0.0f ) {
|
||||
ds->shadeAngleDegrees = b.shadeAngleDegrees;
|
||||
}
|
||||
|
||||
/* ydnar: gs mods: moved st biasing elsewhere */
|
||||
|
|
@ -1202,25 +1203,24 @@ static void AddSurfaceFlare( mapDrawSurface_t *ds, const Vector3& entityOrigin )
|
|||
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, const winding_t *w, int fogNum, float subdivisions ){
|
||||
static void SubdivideFace_r( entity_t *e, const brush_t& brush, const side_t& side, winding_t& w, int fogNum, float subdivisions ){
|
||||
int axis;
|
||||
MinMax bounds;
|
||||
const float epsilon = 0.1;
|
||||
int subFloor, subCeil;
|
||||
winding_t *frontWinding, *backWinding;
|
||||
mapDrawSurface_t *ds;
|
||||
|
||||
|
||||
/* dummy check */
|
||||
if ( w == NULL ) {
|
||||
if ( w.empty() ) {
|
||||
return;
|
||||
}
|
||||
if ( w->size() < 3 ) {
|
||||
Error( "SubdivideFace_r: Bad w->numpoints (%zu < 3)", w->size() );
|
||||
if ( w.size() < 3 ) {
|
||||
Error( "SubdivideFace_r: Bad w->numpoints (%zu < 3)", w.size() );
|
||||
}
|
||||
|
||||
/* determine surface bounds */
|
||||
WindingExtendBounds( *w, bounds );
|
||||
WindingExtendBounds( w, bounds );
|
||||
|
||||
/* split the face */
|
||||
for ( axis = 0; axis < 3; axis++ )
|
||||
|
|
@ -1239,14 +1239,14 @@ static void SubdivideFace_r( entity_t *e, brush_t *brush, side_t *side, const wi
|
|||
/* subdivide if necessary */
|
||||
if ( ( subCeil - subFloor ) > subdivisions ) {
|
||||
/* clip the winding */
|
||||
ClipWindingEpsilon( *w, plane, epsilon, frontWinding, backWinding ); /* not strict; we assume we always keep a winding */
|
||||
auto [frontWinding, backWinding] = ClipWindingEpsilon( w, plane, epsilon ); /* not strict; we assume we always keep a winding */
|
||||
|
||||
/* the clip may not produce two polygons if it was epsilon close */
|
||||
if ( frontWinding == NULL ) {
|
||||
w = backWinding;
|
||||
if ( frontWinding.empty() ) {
|
||||
w.swap( backWinding );
|
||||
}
|
||||
else if ( backWinding == NULL ) {
|
||||
w = frontWinding;
|
||||
else if ( backWinding.empty() ) {
|
||||
w.swap( frontWinding );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1258,7 +1258,7 @@ static void SubdivideFace_r( entity_t *e, brush_t *brush, side_t *side, const wi
|
|||
}
|
||||
|
||||
/* create a face surface */
|
||||
ds = DrawSurfaceForSide( e, brush, side, *w );
|
||||
ds = DrawSurfaceForSide( e, brush, side, w );
|
||||
|
||||
/* set correct fog num */
|
||||
ds->fogNum = fogNum;
|
||||
|
|
@ -1272,13 +1272,9 @@ static void SubdivideFace_r( entity_t *e, brush_t *brush, side_t *side, const wi
|
|||
ydnar: and subdivide surfaces that exceed specified texture coordinate range
|
||||
*/
|
||||
|
||||
void SubdivideFaceSurfaces( entity_t *e, tree_t *tree ){
|
||||
void SubdivideFaceSurfaces( entity_t *e ){
|
||||
int i, j, numBaseDrawSurfs, fogNum;
|
||||
mapDrawSurface_t *ds;
|
||||
brush_t *brush;
|
||||
side_t *side;
|
||||
shaderInfo_t *si;
|
||||
winding_t *w;
|
||||
float range, size, subdivisions, s2;
|
||||
|
||||
|
||||
|
|
@ -1298,11 +1294,11 @@ void SubdivideFaceSurfaces( entity_t *e, tree_t *tree ){
|
|||
}
|
||||
|
||||
/* get bits */
|
||||
brush = ds->mapBrush;
|
||||
side = ds->sideRef->side;
|
||||
const brush_t *brush = ds->mapBrush;
|
||||
const side_t& side = *ds->sideRef->side;
|
||||
|
||||
/* check subdivision for shader */
|
||||
si = side->shaderInfo;
|
||||
const shaderInfo_t *si = side.shaderInfo;
|
||||
if ( si == NULL ) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1347,11 +1343,11 @@ void SubdivideFaceSurfaces( entity_t *e, tree_t *tree ){
|
|||
fogNum = ds->fogNum;
|
||||
|
||||
/* make a winding and free the surface */
|
||||
w = WindingFromDrawSurf( ds );
|
||||
winding_t w = WindingFromDrawSurf( ds );
|
||||
ClearSurface( ds );
|
||||
|
||||
/* subdivide it */
|
||||
SubdivideFace_r( e, brush, side, w, fogNum, subdivisions );
|
||||
SubdivideFace_r( e, *brush, side, w, fogNum, subdivisions );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1365,46 +1361,40 @@ void SubdivideFaceSurfaces( entity_t *e, tree_t *tree ){
|
|||
====================
|
||||
*/
|
||||
|
||||
void ClipSideIntoTree_r( winding_t *w, side_t *side, node_t *node ){
|
||||
winding_t *front, *back;
|
||||
|
||||
if ( !w ) {
|
||||
void ClipSideIntoTree_r( const winding_t& w, side_t& side, const node_t *node ){
|
||||
if ( w.empty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( node->planenum != PLANENUM_LEAF ) {
|
||||
if ( side->planenum == node->planenum ) {
|
||||
if ( side.planenum == node->planenum ) {
|
||||
ClipSideIntoTree_r( w, side, node->children[0] );
|
||||
return;
|
||||
}
|
||||
if ( side->planenum == ( node->planenum ^ 1 ) ) {
|
||||
if ( side.planenum == ( node->planenum ^ 1 ) ) {
|
||||
ClipSideIntoTree_r( w, side, node->children[1] );
|
||||
return;
|
||||
}
|
||||
|
||||
const Plane3f& plane = mapplanes[ node->planenum ].plane;
|
||||
ClipWindingEpsilonStrict( *w, plane,
|
||||
ON_EPSILON, front, back ); /* strict, we handle the "winding disappeared" case */
|
||||
if ( !front && !back ) {
|
||||
auto [front, back] = ClipWindingEpsilonStrict( w, plane, ON_EPSILON ); /* strict, we handle the "winding disappeared" case */
|
||||
if ( front.empty() && back.empty() ) {
|
||||
/* in doubt, register it in both nodes */
|
||||
front = CopyWinding( w );
|
||||
back = CopyWinding( w );
|
||||
ClipSideIntoTree_r( w, side, node->children[0] );
|
||||
ClipSideIntoTree_r( w, side, node->children[1] );
|
||||
}
|
||||
FreeWinding( w );
|
||||
|
||||
else{
|
||||
ClipSideIntoTree_r( front, side, node->children[0] );
|
||||
ClipSideIntoTree_r( back, side, node->children[1] );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if opaque leaf, don't add
|
||||
if ( !node->opaque ) {
|
||||
AddWindingToConvexHull( *w, side->visibleHull, mapplanes[ side->planenum ].normal() );
|
||||
AddWindingToConvexHull( w, side.visibleHull, mapplanes[ side.planenum ].normal() );
|
||||
}
|
||||
|
||||
FreeWinding( w );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1422,44 +1412,42 @@ static int g_numHiddenFaces, g_numCoinFaces;
|
|||
determines if a brushside lies inside another brush
|
||||
*/
|
||||
|
||||
bool SideInBrush( side_t *side, brush_t *b ){
|
||||
bool SideInBrush( side_t& side, const brush_t& b ){
|
||||
/* ignore sides w/o windings or shaders */
|
||||
if ( side->winding == NULL || side->shaderInfo == NULL ) {
|
||||
if ( side.winding.empty() || side.shaderInfo == NULL ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ignore culled sides and translucent brushes */
|
||||
if ( side->culled || ( b->compileFlags & C_TRANSLUCENT ) ) {
|
||||
if ( side.culled || ( b.compileFlags & C_TRANSLUCENT ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* side iterator */
|
||||
for ( int i = 0; i < b->numsides; i++ )
|
||||
for ( const side_t& bside : b.sides )
|
||||
{
|
||||
/* fail if any sides are caulk */
|
||||
if ( b->sides[ i ].compileFlags & C_NODRAW ) {
|
||||
if ( bside.compileFlags & C_NODRAW ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check if side's winding is on or behind the plane */
|
||||
const Plane3f& plane = mapplanes[ b->sides[ i ].planenum ].plane;
|
||||
const EPlaneSide s = WindingOnPlaneSide( *side->winding, plane );
|
||||
const Plane3f& plane = mapplanes[ bside.planenum ].plane;
|
||||
const EPlaneSide s = WindingOnPlaneSide( side.winding, plane );
|
||||
if ( s == eSideFront || s == eSideCross ) {
|
||||
return false;
|
||||
}
|
||||
if( s == eSideOn && b->sides[ i ].culled && vector3_dot( mapplanes[ side->planenum ].normal(), plane.normal() ) > 0 ) /* don't cull by freshly culled with matching plane */
|
||||
if( s == eSideOn && bside.culled && vector3_dot( mapplanes[ side.planenum ].normal(), plane.normal() ) > 0 ) /* don't cull by freshly culled with matching plane */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* don't cull autosprite or polygonoffset surfaces */
|
||||
if ( side->shaderInfo ) {
|
||||
if ( side->shaderInfo->autosprite || side->shaderInfo->polygonOffset ) {
|
||||
if ( side.shaderInfo->autosprite || side.shaderInfo->polygonOffset ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* inside */
|
||||
side->culled = true;
|
||||
side.culled = true;
|
||||
g_numHiddenFaces++;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1471,11 +1459,7 @@ bool SideInBrush( side_t *side, brush_t *b ){
|
|||
*/
|
||||
|
||||
void CullSides( entity_t *e ){
|
||||
int numPoints;
|
||||
int i, j, k, l, first, second, dir;
|
||||
const winding_t *w1, *w2;
|
||||
brush_t *b1, *b2;
|
||||
side_t *side1, *side2;
|
||||
int k, l, first, second, dir;
|
||||
|
||||
|
||||
/* note it */
|
||||
|
|
@ -1485,18 +1469,18 @@ void CullSides( entity_t *e ){
|
|||
g_numCoinFaces = 0;
|
||||
|
||||
/* brush interator 1 */
|
||||
for ( b1 = e->brushes; b1; b1 = b1->next )
|
||||
for ( brushlist_t::iterator b1 = e->brushes.begin(); b1 != e->brushes.end(); ++b1 )
|
||||
{
|
||||
/* sides check */
|
||||
if ( b1->numsides < 1 ) {
|
||||
if ( b1->sides.empty() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* brush iterator 2 */
|
||||
for ( b2 = b1->next; b2; b2 = b2->next )
|
||||
for ( brushlist_t::iterator b2 = std::next( b1 ); b2 != e->brushes.end(); ++b2 )
|
||||
{
|
||||
/* sides check */
|
||||
if ( b2->numsides < 1 ) {
|
||||
if ( b2->sides.empty() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1511,56 +1495,52 @@ void CullSides( entity_t *e ){
|
|||
}
|
||||
|
||||
/* cull inside sides */
|
||||
for ( i = 0; i < b1->numsides; i++ )
|
||||
SideInBrush( &b1->sides[ i ], b2 );
|
||||
for ( i = 0; i < b2->numsides; i++ )
|
||||
SideInBrush( &b2->sides[ i ], b1 );
|
||||
for ( side_t& side : b1->sides )
|
||||
SideInBrush( side, *b2 );
|
||||
for ( side_t& side : b2->sides )
|
||||
SideInBrush( side, *b1 );
|
||||
|
||||
/* side iterator 1 */
|
||||
for ( i = 0; i < b1->numsides; i++ )
|
||||
for ( side_t& side1 : b1->sides )
|
||||
{
|
||||
/* winding check */
|
||||
side1 = &b1->sides[ i ];
|
||||
w1 = side1->winding;
|
||||
if ( w1 == NULL ) {
|
||||
winding_t& w1 = side1.winding;
|
||||
if ( w1.empty() ) {
|
||||
continue;
|
||||
}
|
||||
numPoints = w1->size();
|
||||
if ( side1->shaderInfo == NULL ) {
|
||||
const int numPoints = w1.size();
|
||||
if ( side1.shaderInfo == NULL ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* side iterator 2 */
|
||||
for ( j = 0; j < b2->numsides; j++ )
|
||||
for ( side_t& side2 : b2->sides )
|
||||
{
|
||||
/* winding check */
|
||||
side2 = &b2->sides[ j ];
|
||||
w2 = side2->winding;
|
||||
if ( w2 == NULL ) {
|
||||
winding_t& w2 = side2.winding;
|
||||
if ( w2.empty() ) {
|
||||
continue;
|
||||
}
|
||||
if ( side2->shaderInfo == NULL ) {
|
||||
if ( side2.shaderInfo == NULL ) {
|
||||
continue;
|
||||
}
|
||||
if ( w1->size() != w2->size() ) {
|
||||
if ( w1.size() != w2.size() ) {
|
||||
continue;
|
||||
}
|
||||
if ( side1->culled && side2->culled ) {
|
||||
if ( side1.culled && side2.culled ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* compare planes */
|
||||
if ( ( side1->planenum & ~0x00000001 ) != ( side2->planenum & ~0x00000001 ) ) {
|
||||
if ( ( side1.planenum & ~0x00000001 ) != ( side2.planenum & ~0x00000001 ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* get autosprite and polygonoffset status */
|
||||
if ( side1->shaderInfo &&
|
||||
( side1->shaderInfo->autosprite || side1->shaderInfo->polygonOffset ) ) {
|
||||
if ( side1.shaderInfo->autosprite || side1.shaderInfo->polygonOffset ) {
|
||||
continue;
|
||||
}
|
||||
if ( side2->shaderInfo &&
|
||||
( side2->shaderInfo->autosprite || side2->shaderInfo->polygonOffset ) ) {
|
||||
if ( side2.shaderInfo->autosprite || side2.shaderInfo->polygonOffset ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1568,7 +1548,7 @@ void CullSides( entity_t *e ){
|
|||
first = -1;
|
||||
for ( k = 0; k < numPoints; k++ )
|
||||
{
|
||||
if ( VectorCompare( ( *w1 )[ 0 ], ( *w2 )[ k ] ) ) {
|
||||
if ( VectorCompare( w1[ 0 ], w2[ k ] ) ) {
|
||||
first = k;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1586,7 +1566,7 @@ void CullSides( entity_t *e ){
|
|||
else{
|
||||
second = 0;
|
||||
}
|
||||
if ( vector3_equal_epsilon( ( *w1 )[ 1 ], ( *w2 )[ second ], CULL_EPSILON ) ) {
|
||||
if ( vector3_equal_epsilon( w1[ 1 ], w2[ second ], CULL_EPSILON ) ) {
|
||||
dir = 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -1597,7 +1577,7 @@ void CullSides( entity_t *e ){
|
|||
else{
|
||||
second = numPoints - 1;
|
||||
}
|
||||
if ( vector3_equal_epsilon( ( *w1 )[ 1 ], ( *w2 )[ second ], CULL_EPSILON ) ) {
|
||||
if ( vector3_equal_epsilon( w1[ 1 ], w2[ second ], CULL_EPSILON ) ) {
|
||||
dir = -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1609,7 +1589,7 @@ void CullSides( entity_t *e ){
|
|||
l = first;
|
||||
for ( k = 0; k < numPoints; k++ )
|
||||
{
|
||||
if ( !vector3_equal_epsilon( ( *w1 )[ k ], ( *w2 )[ l ], CULL_EPSILON ) ) {
|
||||
if ( !vector3_equal_epsilon( w1[ k ], w2[ l ], CULL_EPSILON ) ) {
|
||||
k = 100000;
|
||||
}
|
||||
|
||||
|
|
@ -1626,18 +1606,18 @@ void CullSides( entity_t *e ){
|
|||
}
|
||||
|
||||
/* cull face 1 */
|
||||
if ( !side2->culled && !( side2->compileFlags & C_TRANSLUCENT ) && !( side2->compileFlags & C_NODRAW ) ) {
|
||||
side1->culled = true;
|
||||
if ( !side2.culled && !( side2.compileFlags & C_TRANSLUCENT ) && !( side2.compileFlags & C_NODRAW ) ) {
|
||||
side1.culled = true;
|
||||
g_numCoinFaces++;
|
||||
}
|
||||
|
||||
if ( side1->planenum == side2->planenum && side1->culled ) {
|
||||
if ( side1.planenum == side2.planenum && side1.culled ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* cull face 2 */
|
||||
if ( !side1->culled && !( side1->compileFlags & C_TRANSLUCENT ) && !( side1->compileFlags & C_NODRAW ) ) {
|
||||
side2->culled = true;
|
||||
if ( !side1.culled && !( side1.compileFlags & C_TRANSLUCENT ) && !( side1.compileFlags & C_NODRAW ) ) {
|
||||
side2.culled = true;
|
||||
g_numCoinFaces++;
|
||||
}
|
||||
|
||||
|
|
@ -1665,14 +1645,7 @@ void CullSides( entity_t *e ){
|
|||
to be trimmed off automatically.
|
||||
*/
|
||||
|
||||
void ClipSidesIntoTree( entity_t *e, tree_t *tree ){
|
||||
brush_t *b;
|
||||
int i;
|
||||
winding_t *w;
|
||||
side_t *side, *newSide;
|
||||
shaderInfo_t *si;
|
||||
|
||||
|
||||
void ClipSidesIntoTree( entity_t *e, const tree_t& tree ){
|
||||
/* ydnar: cull brush sides */
|
||||
CullSides( e );
|
||||
|
||||
|
|
@ -1680,30 +1653,25 @@ void ClipSidesIntoTree( entity_t *e, tree_t *tree ){
|
|||
Sys_FPrintf( SYS_VRB, "--- ClipSidesIntoTree ---\n" );
|
||||
|
||||
/* walk the brush list */
|
||||
for ( b = e->brushes; b; b = b->next )
|
||||
for ( brush_t& b : e->brushes )
|
||||
{
|
||||
/* walk the brush sides */
|
||||
for ( i = 0; i < b->numsides; i++ )
|
||||
for ( side_t& side : b.sides )
|
||||
{
|
||||
/* get side */
|
||||
side = &b->sides[ i ];
|
||||
if ( side->winding == NULL ) {
|
||||
if ( side.winding.empty() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* copy the winding */
|
||||
w = CopyWinding( side->winding );
|
||||
side->visibleHull = NULL;
|
||||
ClipSideIntoTree_r( w, side, tree->headnode );
|
||||
side.visibleHull.clear();
|
||||
ClipSideIntoTree_r( side.winding, side, tree.headnode );
|
||||
|
||||
/* anything left? */
|
||||
w = side->visibleHull;
|
||||
if ( w == NULL ) {
|
||||
if ( side.visibleHull.empty() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* shader? */
|
||||
si = side->shaderInfo;
|
||||
const shaderInfo_t *si = side.shaderInfo;
|
||||
if ( si == NULL ) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1715,27 +1683,21 @@ void ClipSidesIntoTree( entity_t *e, tree_t *tree ){
|
|||
}
|
||||
|
||||
/* always use the original winding for autosprites and noclip faces */
|
||||
if ( si->autosprite || si->noClip ) {
|
||||
w = side->winding;
|
||||
}
|
||||
const winding_t& w = ( si->autosprite || si->noClip )? side.winding : side.visibleHull;
|
||||
|
||||
/* save this winding as a visible surface */
|
||||
DrawSurfaceForSide( e, b, side, *w );
|
||||
DrawSurfaceForSide( e, b, side, w );
|
||||
|
||||
/* make a back side for fog */
|
||||
if ( !( si->compileFlags & C_FOG ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( si->compileFlags & C_FOG ) {
|
||||
/* duplicate the up-facing side */
|
||||
w = ReverseWinding( *w );
|
||||
newSide = safe_malloc( sizeof( *side ) );
|
||||
*newSide = *side;
|
||||
newSide->visibleHull = w;
|
||||
newSide->planenum ^= 1;
|
||||
side_t& newSide = *new side_t( side );
|
||||
newSide.visibleHull = ReverseWinding( w );
|
||||
newSide.planenum ^= 1;
|
||||
|
||||
/* save this winding as a visible surface */
|
||||
DrawSurfaceForSide( e, b, newSide, *w );
|
||||
DrawSurfaceForSide( e, b, newSide, newSide.visibleHull ); // references new side by sideref, leak!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1910,14 +1872,11 @@ int FilterPointConvexHullIntoTree_r( Vector3 *points[], const int npoints, mapDr
|
|||
filters a winding from a drawsurface into the tree
|
||||
*/
|
||||
|
||||
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 refs = 0;
|
||||
winding_t *fat, *front, *back;
|
||||
shaderInfo_t *si;
|
||||
|
||||
|
||||
/* get shaderinfo */
|
||||
si = ds->shaderInfo;
|
||||
const shaderInfo_t *si = ds->shaderInfo;
|
||||
|
||||
/* ydnar: is this the head node? */
|
||||
if ( node->parent == NULL && si != NULL && si->minmax.valid() ) {
|
||||
|
|
@ -1929,17 +1888,16 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){
|
|||
|
||||
/* 'fatten' the winding by the shader mins/maxs (parsed from vertexDeform move) */
|
||||
/* note this winding is completely invalid (concave, nonplanar, etc) */
|
||||
fat = AllocWinding( w->size() * 3 + 3 );
|
||||
fat->resize( w->size() * 3 + 3 );
|
||||
for ( size_t i = 0; i < w->size(); i++ )
|
||||
winding_t fat( w.size() * 3 + 3 );
|
||||
for ( size_t i = 0; i < w.size(); i++ )
|
||||
{
|
||||
( *fat )[ i ] = ( *w )[ i ];
|
||||
( *fat )[ i + ( w->size() + 1 ) ] = ( *w )[ i ] + si->minmax.mins;
|
||||
( *fat )[ i + ( w->size() + 1 ) * 2 ] = ( *w )[ i ] + si->minmax.maxs;
|
||||
fat[ i ] = w[ i ];
|
||||
fat[ i + ( w.size() + 1 ) ] = w[ i ] + si->minmax.mins;
|
||||
fat[ i + ( w.size() + 1 ) * 2 ] = w[ i ] + si->minmax.maxs;
|
||||
}
|
||||
( *fat )[ w->size() ] = ( *w )[ 0 ];
|
||||
( *fat )[ w->size() * 2 ] = ( *w )[ 0 ] + si->minmax.mins;
|
||||
( *fat )[ w->size() * 3 ] = ( *w )[ 0 ] + si->minmax.maxs;
|
||||
fat[ w.size() ] = w[ 0 ];
|
||||
fat[ w.size() * 2 ] = w[ 0 ] + si->minmax.mins;
|
||||
fat[ w.size() * 3 ] = w[ 0 ] + si->minmax.maxs;
|
||||
|
||||
/*
|
||||
* note: this winding is STILL not suitable for ClipWindingEpsilon, and
|
||||
|
|
@ -1949,8 +1907,7 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){
|
|||
* it worse
|
||||
*/
|
||||
|
||||
FreeWinding( w );
|
||||
w = fat;
|
||||
w.swap( fat );
|
||||
}
|
||||
|
||||
/* is this a decision node? */
|
||||
|
|
@ -1989,23 +1946,23 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){
|
|||
}
|
||||
|
||||
/* clip the winding by this plane */
|
||||
ClipWindingEpsilonStrict( *w, plane1, ON_EPSILON, front, back ); /* strict; we handle the "winding disappeared" case */
|
||||
auto [front, back] = ClipWindingEpsilonStrict( w, plane1, ON_EPSILON ); /* strict; we handle the "winding disappeared" case */
|
||||
|
||||
/* filter by this plane */
|
||||
refs = 0;
|
||||
if ( front == NULL && back == NULL ) {
|
||||
if ( front.empty() && back.empty() ) {
|
||||
/* same plane, this is an ugly hack */
|
||||
/* but better too many than too few refs */
|
||||
refs += FilterWindingIntoTree_r( CopyWinding( w ), ds, node->children[ 0 ] );
|
||||
refs += FilterWindingIntoTree_r( CopyWinding( w ), ds, node->children[ 1 ] );
|
||||
winding_t wcopy( w );
|
||||
refs += FilterWindingIntoTree_r( wcopy, ds, node->children[ 0 ] );
|
||||
refs += FilterWindingIntoTree_r( w, ds, node->children[ 1 ] );
|
||||
}
|
||||
if ( front != NULL ) {
|
||||
if ( !front.empty() ) {
|
||||
refs += FilterWindingIntoTree_r( front, ds, node->children[ 0 ] );
|
||||
}
|
||||
if ( back != NULL ) {
|
||||
if ( !back.empty() ) {
|
||||
refs += FilterWindingIntoTree_r( back, ds, node->children[ 1 ] );
|
||||
}
|
||||
FreeWinding( w );
|
||||
|
||||
/* return */
|
||||
return refs;
|
||||
|
|
@ -2022,14 +1979,10 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ){
|
|||
filters a planar winding face drawsurface into the bsp tree
|
||||
*/
|
||||
|
||||
int FilterFaceIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
|
||||
winding_t *w;
|
||||
int refs = 0;
|
||||
|
||||
|
||||
int FilterFaceIntoTree( mapDrawSurface_t *ds, tree_t& tree ){
|
||||
/* make a winding and filter it into the tree */
|
||||
w = WindingFromDrawSurf( ds );
|
||||
refs = FilterWindingIntoTree_r( w, ds, tree->headnode );
|
||||
winding_t w = WindingFromDrawSurf( ds );
|
||||
int refs = FilterWindingIntoTree_r( w, ds, tree.headnode );
|
||||
|
||||
/* return */
|
||||
return refs;
|
||||
|
|
@ -2044,7 +1997,7 @@ int FilterFaceIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
|
|||
|
||||
#define FILTER_SUBDIVISION 8
|
||||
|
||||
static int FilterPatchIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
|
||||
static int FilterPatchIntoTree( mapDrawSurface_t *ds, tree_t& tree ){
|
||||
int x, y, refs = 0;
|
||||
|
||||
for ( y = 0; y + 2 < ds->patchHeight; y += 2 )
|
||||
|
|
@ -2060,7 +2013,7 @@ static int FilterPatchIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
|
|||
points[6] = &ds->verts[( y + 2 ) * ds->patchWidth + ( x + 0 )].xyz;
|
||||
points[7] = &ds->verts[( y + 2 ) * ds->patchWidth + ( x + 1 )].xyz;
|
||||
points[8] = &ds->verts[( y + 2 ) * ds->patchWidth + ( x + 2 )].xyz;
|
||||
refs += FilterPointConvexHullIntoTree_r( points, 9, ds, tree->headnode );
|
||||
refs += FilterPointConvexHullIntoTree_r( points, 9, ds, tree.headnode );
|
||||
}
|
||||
|
||||
return refs;
|
||||
|
|
@ -2073,9 +2026,8 @@ static int FilterPatchIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
|
|||
filters a triangle surface (meta, model) into the bsp
|
||||
*/
|
||||
|
||||
static int FilterTrianglesIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
|
||||
static int FilterTrianglesIntoTree( mapDrawSurface_t *ds, tree_t& tree ){
|
||||
int i, refs;
|
||||
winding_t *w;
|
||||
|
||||
|
||||
/* ydnar: gs mods: this was creating bogus triangles before */
|
||||
|
|
@ -2090,16 +2042,16 @@ static int FilterTrianglesIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
|
|||
}
|
||||
|
||||
/* make a triangle winding and filter it into the tree */
|
||||
w = AllocWinding( 3 );
|
||||
w->push_back( ds->verts[ ds->indexes[ i ] ].xyz );
|
||||
w->push_back( ds->verts[ ds->indexes[ i + 1 ] ].xyz );
|
||||
w->push_back( ds->verts[ ds->indexes[ i + 2 ] ].xyz );
|
||||
refs += FilterWindingIntoTree_r( w, ds, tree->headnode );
|
||||
winding_t w{
|
||||
ds->verts[ ds->indexes[ i ] ].xyz,
|
||||
ds->verts[ ds->indexes[ i + 1 ] ].xyz,
|
||||
ds->verts[ ds->indexes[ i + 2 ] ].xyz };
|
||||
refs += FilterWindingIntoTree_r( w, ds, tree.headnode );
|
||||
}
|
||||
|
||||
/* use point filtering as well */
|
||||
for ( i = 0; i < ds->numVerts; i++ )
|
||||
refs += FilterPointIntoTree_r( ds->verts[ i ].xyz, ds, tree->headnode );
|
||||
refs += FilterPointIntoTree_r( ds->verts[ i ].xyz, ds, tree.headnode );
|
||||
|
||||
return refs;
|
||||
}
|
||||
|
|
@ -2111,10 +2063,9 @@ static int FilterTrianglesIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
|
|||
filters a foliage surface (wolf et/splash damage)
|
||||
*/
|
||||
|
||||
static int FilterFoliageIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
|
||||
static int FilterFoliageIntoTree( mapDrawSurface_t *ds, tree_t& tree ){
|
||||
int f, i, refs;
|
||||
bspDrawVert_t *instance;
|
||||
winding_t *w;
|
||||
|
||||
|
||||
/* walk origin list */
|
||||
|
|
@ -2135,17 +2086,17 @@ static int FilterFoliageIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
|
|||
}
|
||||
|
||||
/* make a triangle winding and filter it into the tree */
|
||||
w = AllocWinding( 3 );
|
||||
w->push_back( instance->xyz + ds->verts[ ds->indexes[ i ] ].xyz );
|
||||
w->push_back( instance->xyz + ds->verts[ ds->indexes[ i + 1 ] ].xyz );
|
||||
w->push_back( instance->xyz + ds->verts[ ds->indexes[ i + 2 ] ].xyz );
|
||||
refs += FilterWindingIntoTree_r( w, ds, tree->headnode );
|
||||
winding_t w{
|
||||
instance->xyz + ds->verts[ ds->indexes[ i ] ].xyz,
|
||||
instance->xyz + ds->verts[ ds->indexes[ i + 1 ] ].xyz,
|
||||
instance->xyz + ds->verts[ ds->indexes[ i + 2 ] ].xyz };
|
||||
refs += FilterWindingIntoTree_r( w, ds, tree.headnode );
|
||||
}
|
||||
|
||||
/* use point filtering as well */
|
||||
for ( i = 0; i < ( ds->numVerts - ds->numFoliageInstances ); i++ )
|
||||
{
|
||||
refs += FilterPointIntoTree_r( instance->xyz + ds->verts[ i ].xyz, ds, tree->headnode );
|
||||
refs += FilterPointIntoTree_r( instance->xyz + ds->verts[ i ].xyz, ds, tree.headnode );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2158,8 +2109,8 @@ static int FilterFoliageIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
|
|||
FilterFlareIntoTree()
|
||||
simple point filtering for flare surfaces
|
||||
*/
|
||||
static int FilterFlareSurfIntoTree( mapDrawSurface_t *ds, tree_t *tree ){
|
||||
return FilterPointIntoTree_r( ds->lightmapOrigin, ds, tree->headnode );
|
||||
static int FilterFlareSurfIntoTree( mapDrawSurface_t *ds, tree_t& tree ){
|
||||
return FilterPointIntoTree_r( ds->lightmapOrigin, ds, tree.headnode );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2741,10 +2692,9 @@ static void EmitFaceSurface( mapDrawSurface_t *ds ){
|
|||
generates drawsurfaces for passable portals in the bsp
|
||||
*/
|
||||
|
||||
static void MakeDebugPortalSurfs_r( node_t *node, shaderInfo_t *si ){
|
||||
static void MakeDebugPortalSurfs_r( const node_t *node, shaderInfo_t *si ){
|
||||
int i, k, c, s;
|
||||
portal_t *p;
|
||||
winding_t *w;
|
||||
const portal_t *p;
|
||||
mapDrawSurface_t *ds;
|
||||
bspDrawVert_t *dv;
|
||||
|
||||
|
|
@ -2765,30 +2715,29 @@ static void MakeDebugPortalSurfs_r( node_t *node, shaderInfo_t *si ){
|
|||
for ( c = 0, p = node->portals; p != NULL; c++, p = p->next[ s ] )
|
||||
{
|
||||
/* get winding and side even/odd */
|
||||
w = p->winding;
|
||||
const winding_t& w = p->winding;
|
||||
s = ( p->nodes[ 1 ] == node );
|
||||
|
||||
/* is this a valid portal for this leaf? */
|
||||
if ( w && p->nodes[ 0 ] == node ) {
|
||||
if ( !w.empty() && p->nodes[ 0 ] == node ) {
|
||||
/* is this portal passable? */
|
||||
if ( !PortalPassable( p ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check max points */
|
||||
if ( w->size() > 64 ) {
|
||||
Error( "MakePortalSurfs_r: w->numpoints = %zu", w->size() );
|
||||
if ( w.size() > 64 ) {
|
||||
Error( "MakePortalSurfs_r: w->numpoints = %zu", w.size() );
|
||||
}
|
||||
|
||||
/* allocate a drawsurface */
|
||||
ds = AllocDrawSurface( ESurfaceType::Face );
|
||||
ds->shaderInfo = si;
|
||||
ds->planar = true;
|
||||
ds->sideRef = AllocSideRef( p->side, NULL );
|
||||
ds->planeNum = FindFloatPlane( p->plane.plane, 0, NULL );
|
||||
ds->lightmapVecs[ 2 ] = p->plane.normal();
|
||||
ds->fogNum = -1;
|
||||
ds->numVerts = w->size();
|
||||
ds->numVerts = w.size();
|
||||
ds->verts = safe_calloc( ds->numVerts * sizeof( *ds->verts ) );
|
||||
|
||||
/* walk the winding */
|
||||
|
|
@ -2798,7 +2747,7 @@ static void MakeDebugPortalSurfs_r( node_t *node, shaderInfo_t *si ){
|
|||
dv = ds->verts + i;
|
||||
|
||||
/* set it */
|
||||
dv->xyz = ( *w )[ i ];
|
||||
dv->xyz = w[ i ];
|
||||
dv->normal = p->plane.normal();
|
||||
dv->st = { 0, 0 };
|
||||
for ( k = 0; k < MAX_LIGHTMAPS; k++ )
|
||||
|
|
@ -2818,7 +2767,7 @@ static void MakeDebugPortalSurfs_r( node_t *node, shaderInfo_t *si ){
|
|||
generates drawsurfaces for passable portals in the bsp
|
||||
*/
|
||||
|
||||
void MakeDebugPortalSurfs( tree_t *tree ){
|
||||
void MakeDebugPortalSurfs( const tree_t& tree ){
|
||||
shaderInfo_t *si;
|
||||
|
||||
|
||||
|
|
@ -2829,7 +2778,7 @@ void MakeDebugPortalSurfs( tree_t *tree ){
|
|||
si = ShaderInfoForShader( "debugportals" );
|
||||
|
||||
/* walk the tree */
|
||||
MakeDebugPortalSurfs_r( tree->headnode, si );
|
||||
MakeDebugPortalSurfs_r( tree.headnode, si );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2839,7 +2788,7 @@ void MakeDebugPortalSurfs( tree_t *tree ){
|
|||
generates drawsurfaces for a foghull (this MUST use a sky shader)
|
||||
*/
|
||||
|
||||
void MakeFogHullSurfs( entity_t *e, tree_t *tree, const char *shader ){
|
||||
void MakeFogHullSurfs( entity_t *e, const char *shader ){
|
||||
shaderInfo_t *si;
|
||||
mapDrawSurface_t *ds;
|
||||
int indexes[] =
|
||||
|
|
@ -3231,17 +3180,8 @@ void AddEntitySurfaceModels( entity_t *e ){
|
|||
*/
|
||||
|
||||
static void VolumeColorMods( entity_t *e, mapDrawSurface_t *ds ){
|
||||
int i, j;
|
||||
brush_t *b;
|
||||
|
||||
|
||||
/* early out */
|
||||
if ( e->colorModBrushes == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* iterate brushes */
|
||||
for ( b = e->colorModBrushes; b != NULL; b = b->nextColorModBrush )
|
||||
for ( const brush_t *b : e->colorModBrushes )
|
||||
{
|
||||
/* worldspawn alpha brushes affect all, grouped ones only affect original entity */
|
||||
if ( b->entityNum != 0 && b->entityNum != ds->entityNum ) {
|
||||
|
|
@ -3254,10 +3194,11 @@ static void VolumeColorMods( entity_t *e, mapDrawSurface_t *ds ){
|
|||
}
|
||||
|
||||
/* iterate verts */
|
||||
for ( i = 0; i < ds->numVerts; i++ )
|
||||
for ( int i = 0; i < ds->numVerts; i++ )
|
||||
{
|
||||
/* iterate planes */
|
||||
for ( j = 0; j < b->numsides; j++ )
|
||||
size_t j;
|
||||
for ( j = 0; j < b->sides.size(); j++ )
|
||||
{
|
||||
/* point-plane test */
|
||||
if ( plane3_distance_to_point( mapplanes[ b->sides[ j ].planenum ].plane, ds->verts[ i ].xyz ) > 1.0f ) {
|
||||
|
|
@ -3266,7 +3207,7 @@ static void VolumeColorMods( entity_t *e, mapDrawSurface_t *ds ){
|
|||
}
|
||||
|
||||
/* apply colormods */
|
||||
if ( j == b->numsides ) {
|
||||
if ( j == b->sides.size() ) {
|
||||
ColorMod( b->contentShader->colorMod, 1, &ds->verts[ i ] );
|
||||
}
|
||||
}
|
||||
|
|
@ -3282,7 +3223,7 @@ static void VolumeColorMods( entity_t *e, mapDrawSurface_t *ds ){
|
|||
will have valid final indexes
|
||||
*/
|
||||
|
||||
void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ){
|
||||
void FilterDrawsurfsIntoTree( entity_t *e, tree_t& tree ){
|
||||
int i, j;
|
||||
mapDrawSurface_t *ds;
|
||||
shaderInfo_t *si;
|
||||
|
|
@ -3311,7 +3252,7 @@ void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ){
|
|||
|
||||
/* ydnar: skybox surfaces are special */
|
||||
if ( ds->skybox ) {
|
||||
refs = AddReferenceToTree_r( ds, tree->headnode, true );
|
||||
refs = AddReferenceToTree_r( ds, tree.headnode, true );
|
||||
ds->skybox = false;
|
||||
sb = true;
|
||||
}
|
||||
|
|
@ -3421,7 +3362,7 @@ void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ){
|
|||
/* handle foghull surfaces */
|
||||
case ESurfaceType::Foghull:
|
||||
if ( refs == 0 ) {
|
||||
refs = AddReferenceToTree_r( ds, tree->headnode, false );
|
||||
refs = AddReferenceToTree_r( ds, tree.headnode, false );
|
||||
}
|
||||
if ( refs > 0 ) {
|
||||
EmitTriangleSurface( ds );
|
||||
|
|
|
|||
|
|
@ -91,15 +91,8 @@ void FreeTree_r( node_t *node ){
|
|||
FreeTree_r( node->children[1] );
|
||||
}
|
||||
|
||||
// free bspbrushes
|
||||
FreeBrushList( node->brushlist );
|
||||
|
||||
// free the node
|
||||
if ( node->volume ) {
|
||||
FreeBrush( node->volume );
|
||||
}
|
||||
|
||||
free( node );
|
||||
delete node;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -108,25 +101,24 @@ void FreeTree_r( node_t *node ){
|
|||
FreeTree
|
||||
=============
|
||||
*/
|
||||
void FreeTree( tree_t *tree ){
|
||||
FreeTreePortals_r( tree->headnode );
|
||||
FreeTree_r( tree->headnode );
|
||||
free( tree );
|
||||
void FreeTree( tree_t& tree ){
|
||||
FreeTreePortals_r( tree.headnode );
|
||||
FreeTree_r( tree.headnode );
|
||||
}
|
||||
|
||||
//===============================================================
|
||||
|
||||
void PrintTree_r( node_t *node, int depth ){
|
||||
void PrintTree_r( const node_t *node, int depth ){
|
||||
for ( int i = 0; i < depth; i++ )
|
||||
Sys_Printf( " " );
|
||||
if ( node->planenum == PLANENUM_LEAF ) {
|
||||
if ( !node->brushlist ) {
|
||||
if ( node->brushlist.empty() ) {
|
||||
Sys_Printf( "NULL\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( const brush_t *bb = node->brushlist; bb; bb = bb->next )
|
||||
Sys_Printf( "%d ", bb->original->brushNum );
|
||||
for ( const brush_t& bb : node->brushlist )
|
||||
Sys_Printf( "%d ", bb.original->brushNum );
|
||||
Sys_Printf( "\n" );
|
||||
}
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
emits a bsp shader entry
|
||||
*/
|
||||
|
||||
int EmitShader( const char *shader, int *contentFlags, int *surfaceFlags ){
|
||||
int EmitShader( const char *shader, const int *contentFlags, const int *surfaceFlags ){
|
||||
int i;
|
||||
shaderInfo_t *si;
|
||||
|
||||
|
|
@ -132,7 +132,6 @@ void EmitPlanes( void ){
|
|||
|
||||
void EmitLeaf( node_t *node ){
|
||||
bspLeaf_t *leaf_p;
|
||||
brush_t *b;
|
||||
drawSurfRef_t *dsr;
|
||||
|
||||
|
||||
|
|
@ -153,18 +152,18 @@ void EmitLeaf( node_t *node ){
|
|||
|
||||
/* emit leaf brushes */
|
||||
leaf_p->firstBSPLeafBrush = numBSPLeafBrushes;
|
||||
for ( b = node->brushlist; b; b = b->next )
|
||||
for ( const brush_t& b : node->brushlist )
|
||||
{
|
||||
/* something is corrupting brushes */
|
||||
if ( (size_t) b < 256 ) {
|
||||
Sys_Warning( "Node brush list corrupted (0x%08X)\n", b );
|
||||
break;
|
||||
}
|
||||
// if ( (size_t) b < 256 ) {
|
||||
// Sys_Warning( "Node brush list corrupted (0x%08X)\n", b );
|
||||
// break;
|
||||
// }
|
||||
//% if( b->guard != 0xDEADBEEF )
|
||||
//% Sys_Printf( "Brush %6d: 0x%08X Guard: 0x%08X Next: 0x%08X Original: 0x%08X Sides: %d\n", b->brushNum, b, b, b->next, b->original, b->numsides );
|
||||
|
||||
AUTOEXPAND_BY_REALLOC_BSP( LeafBrushes, 1024 );
|
||||
bspLeafBrushes[ numBSPLeafBrushes ] = b->original->outputNum;
|
||||
bspLeafBrushes[ numBSPLeafBrushes ] = b.original->outputNum;
|
||||
numBSPLeafBrushes++;
|
||||
}
|
||||
|
||||
|
|
@ -247,12 +246,10 @@ int EmitDrawNode_r( node_t *node ){
|
|||
============
|
||||
*/
|
||||
void SetModelNumbers( void ){
|
||||
int models;
|
||||
char value[16];
|
||||
|
||||
models = 1;
|
||||
int models = 1;
|
||||
for ( std::size_t i = 1; i < entities.size(); ++i ) {
|
||||
if ( entities[i].brushes || entities[i].patches ) {
|
||||
if ( !entities[i].brushes.empty() || entities[i].patches ) {
|
||||
char value[16];
|
||||
sprintf( value, "*%i", models );
|
||||
models++;
|
||||
entities[i].setKeyValue( "model", value );
|
||||
|
|
@ -404,9 +401,7 @@ void EndBSPFile( bool do_write ){
|
|||
writes the brush list to the bsp
|
||||
*/
|
||||
|
||||
void EmitBrushes( brush_t *brushes, int *firstBrush, int *numBrushes ){
|
||||
int j;
|
||||
brush_t *b;
|
||||
void EmitBrushes( brushlist_t& brushes, int *firstBrush, int *numBrushes ){
|
||||
bspBrush_t *db;
|
||||
bspBrushSide_t *cp;
|
||||
|
||||
|
|
@ -420,45 +415,45 @@ void EmitBrushes( brush_t *brushes, int *firstBrush, int *numBrushes ){
|
|||
}
|
||||
|
||||
/* walk list of brushes */
|
||||
for ( b = brushes; b != NULL; b = b->next )
|
||||
for ( brush_t& b : brushes )
|
||||
{
|
||||
/* check limits */
|
||||
AUTOEXPAND_BY_REALLOC_BSP( Brushes, 1024 );
|
||||
|
||||
/* get bsp brush */
|
||||
b->outputNum = numBSPBrushes;
|
||||
b.outputNum = numBSPBrushes;
|
||||
db = &bspBrushes[ numBSPBrushes ];
|
||||
numBSPBrushes++;
|
||||
if ( numBrushes != NULL ) {
|
||||
( *numBrushes )++;
|
||||
}
|
||||
|
||||
db->shaderNum = EmitShader( b->contentShader->shader, &b->contentShader->contentFlags, &b->contentShader->surfaceFlags );
|
||||
db->shaderNum = EmitShader( b.contentShader->shader, &b.contentShader->contentFlags, &b.contentShader->surfaceFlags );
|
||||
db->firstSide = numBSPBrushSides;
|
||||
|
||||
/* walk sides */
|
||||
db->numSides = 0;
|
||||
for ( j = 0; j < b->numsides; j++ )
|
||||
for ( side_t& side : b.sides )
|
||||
{
|
||||
/* set output number to bogus initially */
|
||||
b->sides[ j ].outputNum = -1;
|
||||
side.outputNum = -1;
|
||||
|
||||
/* check count */
|
||||
AUTOEXPAND_BY_REALLOC_BSP( BrushSides, 1024 );
|
||||
|
||||
/* emit side */
|
||||
b->sides[ j ].outputNum = numBSPBrushSides;
|
||||
side.outputNum = numBSPBrushSides;
|
||||
cp = &bspBrushSides[ numBSPBrushSides ];
|
||||
db->numSides++;
|
||||
numBSPBrushSides++;
|
||||
cp->planeNum = b->sides[ j ].planenum;
|
||||
cp->planeNum = side.planenum;
|
||||
|
||||
/* emit shader */
|
||||
if ( b->sides[ j ].shaderInfo ) {
|
||||
cp->shaderNum = EmitShader( b->sides[ j ].shaderInfo->shader, &b->sides[ j ].shaderInfo->contentFlags, &b->sides[ j ].shaderInfo->surfaceFlags );
|
||||
if ( side.shaderInfo ) {
|
||||
cp->shaderNum = EmitShader( side.shaderInfo->shader, &side.shaderInfo->contentFlags, &side.shaderInfo->surfaceFlags );
|
||||
}
|
||||
else if( b->sides[ j ].bevel ) { /* emit surfaceFlags for bevels to get correct physics at walkable brush edges and vertices */
|
||||
cp->shaderNum = EmitShader( NULL, NULL, &b->sides[ j ].surfaceFlags );
|
||||
else if( side.bevel ) { /* emit surfaceFlags for bevels to get correct physics at walkable brush edges and vertices */
|
||||
cp->shaderNum = EmitShader( NULL, NULL, &side.surfaceFlags );
|
||||
}
|
||||
else{
|
||||
cp->shaderNum = EmitShader( NULL, NULL, NULL );
|
||||
|
|
@ -507,7 +502,7 @@ void EmitFogs( void ){
|
|||
/* find visible side */
|
||||
for ( j = 0; j < 6; j++ )
|
||||
{
|
||||
if ( mapFogs[ i ].brush->sides[ j ].visibleHull != NULL ) {
|
||||
if ( !mapFogs[ i ].brush->sides[ j ].visibleHull.empty() ) {
|
||||
Sys_Printf( "Fog %d has visible side %d\n", i, j );
|
||||
bspFogs[ i ].visibleSide = j;
|
||||
break;
|
||||
|
|
@ -536,17 +531,17 @@ void BeginModel( void ){
|
|||
const entity_t& e = entities[ mapEntityNum ];
|
||||
|
||||
/* bound the brushes */
|
||||
for ( const brush_t *b = e.brushes; b; b = b->next )
|
||||
for ( const brush_t& b : e.brushes )
|
||||
{
|
||||
/* ignore non-real brushes (origin, etc) */
|
||||
if ( b->numsides == 0 ) {
|
||||
if ( b.sides.empty() ) {
|
||||
continue;
|
||||
}
|
||||
minmax.extend( b->minmax );
|
||||
minmax.extend( b.minmax );
|
||||
|
||||
/* ydnar: lightgrid bounds */
|
||||
if ( b->compileFlags & C_LIGHTGRID ) {
|
||||
lgMinmax.extend( b->minmax );
|
||||
if ( b.compileFlags & C_LIGHTGRID ) {
|
||||
lgMinmax.extend( b.minmax );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user