mirror of
https://github.com/Garux/netradiant-custom.git
synced 2026-09-28 00:00:03 +02:00
refactor model autoclip
This commit is contained in:
@@ -333,10 +333,10 @@ static brush_t BrushFromBounds( const Vector3& mins, const Vector3& maxs ){
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
{
|
||||
float dist = maxs[i];
|
||||
b.sides[i].planenum = FindFloatPlane( g_vector3_axes[i], dist, 1, &maxs );
|
||||
b.sides[i].planenum = FindFloatPlane( g_vector3_axes[i], dist, Span( &maxs, 1 ) );
|
||||
|
||||
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, Span( &mins, 1 ) );
|
||||
}
|
||||
|
||||
CreateBrushWindings( b );
|
||||
|
||||
@@ -61,7 +61,7 @@ static void SelectSplitPlaneNum( const node_t *node, const facelist_t& list, int
|
||||
}
|
||||
const float dist = blockSize[ i ] * ( floor( node->minmax.mins[ i ] / blockSize[ i ] ) + 1 );
|
||||
if ( node->minmax.maxs[ i ] > dist ) {
|
||||
*splitPlaneNum = FindFloatPlane( g_vector3_axes[i], dist, 0, nullptr );
|
||||
*splitPlaneNum = FindFloatPlane( g_vector3_axes[i], dist, {} );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+26
-38
@@ -299,16 +299,16 @@ static void SnapPlane( Plane3f& plane ){
|
||||
SnapPlaneImproved()
|
||||
snaps a plane to normal/distance epsilons, improved code
|
||||
*/
|
||||
static void SnapPlaneImproved( Plane3f& plane, int numPoints, const Vector3 *points ){
|
||||
void SnapPlaneImproved( Plane3f& plane, const Span<const Vector3>& points ){
|
||||
if ( SnapNormal( plane.normal() ) ) {
|
||||
if ( numPoints > 0 ) {
|
||||
if ( !points.empty() ) {
|
||||
// Adjust the dist so that the provided points don't drift away.
|
||||
DoubleVector3 center( 0 );
|
||||
for ( const Vector3& point : Span( points, numPoints ) )
|
||||
for ( const Vector3& point : points )
|
||||
{
|
||||
center += point;
|
||||
}
|
||||
center /= numPoints;
|
||||
center /= points.size();
|
||||
plane.dist() = vector3_dot( plane.normal(), center );
|
||||
}
|
||||
}
|
||||
@@ -331,14 +331,14 @@ static void SnapPlaneImproved( Plane3f& plane, int numPoints, const Vector3 *poi
|
||||
must be within an epsilon distance of the plane
|
||||
*/
|
||||
|
||||
int FindFloatPlane( const Plane3f& inplane, int numPoints, const Vector3 *points ) // NOTE: this has a side effect on the normal. Good or bad?
|
||||
int FindFloatPlane( const Plane3f& inplane, const Span<const Vector3>& points ) // NOTE: this has a side effect on the normal. Good or bad?
|
||||
|
||||
#ifdef USE_HASHING
|
||||
|
||||
{
|
||||
Plane3f plane( inplane );
|
||||
#if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX
|
||||
SnapPlaneImproved( plane, numPoints, points );
|
||||
SnapPlaneImproved( plane, points );
|
||||
#else
|
||||
SnapPlane( plane );
|
||||
#endif
|
||||
@@ -362,24 +362,17 @@ int FindFloatPlane( const Plane3f& inplane, int numPoints, const Vector3 *points
|
||||
//% return p - mapplanes;
|
||||
|
||||
/* ydnar: test supplied points against this plane */
|
||||
int j;
|
||||
for ( j = 0; j < numPoints; ++j )
|
||||
{
|
||||
if( std::ranges::all_of( points, [&]( const Vector3& point ){ // true for empty
|
||||
// NOTE: When dist approaches 2^16, the resolution of 32 bit floating
|
||||
// point number is greatly decreased. The distanceEpsilon cannot be
|
||||
// very small when world coordinates extend to 2^16. Making the
|
||||
// dot product here in 64 bit land will not really help the situation
|
||||
// because the error will already be carried in dist.
|
||||
const double d = std::fabs( plane3_distance_to_point( p.plane, points[ j ] ) );
|
||||
if ( d != 0 && d >= distanceEpsilon ) {
|
||||
break; // Point is too far from plane.
|
||||
}
|
||||
}
|
||||
|
||||
/* found a matching plane */
|
||||
if ( j >= numPoints ) {
|
||||
return pidx;
|
||||
}
|
||||
const double d = std::fabs( plane3_distance_to_point( p.plane, point ) );
|
||||
//% if( d > 0.2 ) Sys_Warning( "plane3_distance_to_point( p.plane, point ) %f\n", d );
|
||||
return d == 0 || d < distanceEpsilon; // Point is not too far from plane.
|
||||
} ) )
|
||||
return pidx; /* found a matching plane */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -390,16 +383,16 @@ int FindFloatPlane( const Plane3f& inplane, int numPoints, const Vector3 *points
|
||||
#else
|
||||
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
plane_t *p;
|
||||
Plane3f plane( innormal, dist );
|
||||
Plane3f plane( inplane );
|
||||
|
||||
#if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX
|
||||
SnapPlaneImproved( plane, numPoints, points );
|
||||
SnapPlaneImproved( plane, points );
|
||||
#else
|
||||
SnapPlane( plane );
|
||||
#endif
|
||||
for ( i = 0, p = mapplanes; i < nummapplanes; ++i, ++p )
|
||||
for ( i = 0, p = mapplanes.data(); i < mapplanes.size(); ++i, ++p )
|
||||
{
|
||||
if ( !PlaneEqual( *p, plane ) ) {
|
||||
continue;
|
||||
@@ -409,17 +402,11 @@ int FindFloatPlane( const Plane3f& inplane, int numPoints, const Vector3 *points
|
||||
//% return i;
|
||||
|
||||
/* ydnar: test supplied points against this plane */
|
||||
for ( j = 0; j < numPoints; ++j )
|
||||
{
|
||||
if ( std::fabs( plane3_distance_to_point( p->plane, points[ j ] ) ) > distanceEpsilon ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( std::ranges::all_of( points, [&]( const Vector3& point ){ // true for empty
|
||||
return std::fabs( plane3_distance_to_point( p->plane, point ) ) <= distanceEpsilon;
|
||||
} ) )
|
||||
return i; /* found a matching plane */
|
||||
|
||||
/* found a matching plane */
|
||||
if ( j >= numPoints ) {
|
||||
return i;
|
||||
}
|
||||
// TODO: Note that the non-USE_HASHING code does not compute epsilons
|
||||
// for the provided points. It should do that. I think this code
|
||||
// is unmaintained because nobody sets USE_HASHING to off.
|
||||
@@ -445,11 +432,12 @@ inline int MapPlaneFromPoints( DoubleVector3 p[3] ){
|
||||
// if the plane is 2^16 units away from the origin (the "epsilon" approaches
|
||||
// 0.01 in that case).
|
||||
const Vector3 points[3] = { p[0], p[1], p[2] };
|
||||
return FindFloatPlane( Plane3f( plane ), 3, points );
|
||||
return FindFloatPlane( Plane3f( plane ), points );
|
||||
#else
|
||||
Plane3f plane;
|
||||
PlaneFromPoints( plane, p );
|
||||
return FindFloatPlane( plane, 3, p );
|
||||
const Vector3 points[3] = { p[0], p[1], p[2] };
|
||||
return FindFloatPlane( plane, points );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -627,7 +615,7 @@ void AddBrushBevels(){
|
||||
}
|
||||
}
|
||||
|
||||
s.planenum = FindFloatPlane( plane, 0, nullptr );
|
||||
s.planenum = FindFloatPlane( plane, {} );
|
||||
s.contentFlags = sides[ 0 ].contentFlags;
|
||||
/* handle bevel surfaceflags */
|
||||
for ( const side_t& side : sides ) {
|
||||
@@ -739,7 +727,7 @@ void AddBrushBevels(){
|
||||
}
|
||||
side_t& s2 = sides.emplace_back();
|
||||
|
||||
s2.planenum = FindFloatPlane( plane, 1, &sides[i].winding[ j ] );
|
||||
s2.planenum = FindFloatPlane( plane, Span( &sides[i].winding[ j ], 1 ) );
|
||||
s2.contentFlags = sides[0].contentFlags;
|
||||
s2.surfaceFlags = ( sides[i].surfaceFlags & surfaceFlagsMask ); /* handle bevel surfaceflags */
|
||||
s2.bevel = true;
|
||||
@@ -1229,7 +1217,7 @@ static void AdjustBrushesForOrigin( entity_t& ent ){
|
||||
const float newdist = -plane3_distance_to_point( mapplanes[ side.planenum ].plane, ent.originbrush_origin );
|
||||
|
||||
/* find a new plane */
|
||||
side.planenum = FindFloatPlane( mapplanes[ side.planenum ].normal(), newdist, 0, nullptr );
|
||||
side.planenum = FindFloatPlane( mapplanes[ side.planenum ].normal(), newdist, {} );
|
||||
side.plane.dist() = -plane3_distance_to_point( side.plane, ent.originbrush_origin );
|
||||
}
|
||||
|
||||
|
||||
+173
-333
@@ -370,52 +370,81 @@ enum EModelFlags{
|
||||
eClipFlags = eClipModel | eExtrudeFaceNormals | eExtrudeTerrain | eExtrudeVertexNormals | ePyramidaClip | eExtrudeDownwards | eExtrudeUpwards | eMaxExtrude | eAxialBackplane,
|
||||
};
|
||||
|
||||
inline void nonax_clip_dbg( const Plane3f (&p)[3] ){
|
||||
#if 0
|
||||
for ( int j = 0; j < 3; ++j ){
|
||||
for ( int k = 0; k < 3; ++k ){
|
||||
const Vector3& n = p[j].normal();
|
||||
if ( std::fabs( n[k] ) < 0.00025f && n[k] != 0 ){
|
||||
Sys_Printf( "nonax nrm %6.17f %6.17f %6.17f\n", n[0], n[1], n[2] );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline size_t normal_make_axial( Vector3& normal ){
|
||||
const size_t i = vector3_max_abs_component_index( normal );
|
||||
normal = normal[i] >= 0? g_vector3_axes[i] : -g_vector3_axes[i];
|
||||
return i;
|
||||
}
|
||||
|
||||
template<size_t N> // N = 4 or 5
|
||||
static void make_brush_sides( const Plane3f plane, const Plane3f (&p)[3], const Plane3f& reverse, Vector3 (&points)[4], shaderInfo_t& si ){
|
||||
/* set up brush sides */
|
||||
buildBrush.sides.clear(); // clear, so resize() will value-initialize elements
|
||||
buildBrush.sides.resize( N );
|
||||
struct ClipSides
|
||||
{
|
||||
Plane3f fplane; // front plane
|
||||
winding_t fw; // front winding
|
||||
Plane3f bplane{ 0, 0, 0, 0 }; // back plane, present if != 0
|
||||
winding_t bw; // back winding
|
||||
std::vector<Plane3f> splanes; // side planes, using fw[i], fw[i + 1] points, size = fw.size
|
||||
|
||||
if( debugClip ){
|
||||
buildBrush.sides[ 0 ].shaderInfo = &ShaderInfoForShader( "debugclip2" );
|
||||
for ( size_t i = 1; i < N; ++i )
|
||||
buildBrush.sides[i].shaderInfo = &ShaderInfoForShader( "debugclip" );
|
||||
}
|
||||
else{
|
||||
buildBrush.sides[0].shaderInfo = &si;
|
||||
buildBrush.sides[0].surfaceFlags = si.surfaceFlags;
|
||||
for ( size_t i = 1; i < N; ++i )
|
||||
buildBrush.sides[i].shaderInfo = nullptr; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
/* construct front and allocates sides, requires fw */
|
||||
bool construct(){
|
||||
if( !PlaneFromPoints( fplane, fw.data() ) )
|
||||
return false;
|
||||
|
||||
// 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)
|
||||
// also broken drawsurfs in case of normal brushes
|
||||
// ? worth to snap nearly axial edges (or on nearly axial plane) beforehand or SnapPlaneImproved is nuff good for sides
|
||||
const Plane3f pln = fplane;
|
||||
SnapPlaneImproved( fplane, fw );
|
||||
if( pln.normal() != fplane.normal() || pln.dist() != fplane.dist() ){
|
||||
for( Vector3& v : fw ){
|
||||
v = plane3_project_point( fplane, v );
|
||||
}
|
||||
}
|
||||
|
||||
splanes.resize( fw.size() );
|
||||
|
||||
/* sanity check */
|
||||
if ( triangle_min_angle_squared_sin( fw[0], fw[1], fw[2] ) < 1e-8 ) // degenerate triangle
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
points[3] = points[0]; // for cyclic usage
|
||||
void add_back_plane( float clipDepth, const Vector3& bestNormal ){
|
||||
bplane = plane3_flipped( fplane );
|
||||
bplane.dist() += vector3_dot( bestNormal, fplane.normal() ) * clipDepth;
|
||||
bw = fw;
|
||||
for( Vector3& v : bw )
|
||||
v -= bestNormal * clipDepth;
|
||||
}
|
||||
|
||||
void make_brush_sides( shaderInfo_t& si ) const {
|
||||
const bool doBack = bplane.normal() != g_vector3_identity;
|
||||
/* set up brush sides */
|
||||
buildBrush.sides.clear(); // clear, so resize() will value-initialize elements
|
||||
buildBrush.sides.resize( splanes.size() + 1 + doBack );
|
||||
|
||||
if( debugClip ){
|
||||
buildBrush.sides[0].shaderInfo = &ShaderInfoForShader( "debugclip2" );
|
||||
for ( size_t i = 1; i < buildBrush.sides.size(); ++i )
|
||||
buildBrush.sides[i].shaderInfo = &ShaderInfoForShader( "debugclip" );
|
||||
}
|
||||
else{
|
||||
buildBrush.sides[0].shaderInfo = &si;
|
||||
buildBrush.sides[0].surfaceFlags = si.surfaceFlags;
|
||||
for ( size_t i = 1; i < buildBrush.sides.size(); ++i )
|
||||
buildBrush.sides[i].shaderInfo = nullptr; // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
|
||||
}
|
||||
|
||||
buildBrush.sides[0].planenum = FindFloatPlane( fplane, fw );
|
||||
for( size_t i = 0; i < splanes.size(); ++i ){
|
||||
buildBrush.sides[i + 1].planenum = FindFloatPlane( splanes[i], std::array{ fw[i], fw[winding_next( fw, i )] } );
|
||||
}
|
||||
if( doBack )
|
||||
buildBrush.sides.back().planenum = FindFloatPlane( bplane, bw );
|
||||
}
|
||||
};
|
||||
|
||||
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])
|
||||
if constexpr( N == 5 )
|
||||
buildBrush.sides[4].planenum = FindFloatPlane( reverse, 0, nullptr );
|
||||
}
|
||||
|
||||
static void ClipModel( int spawnFlags, float clipDepth, shaderInfo_t& si, const mapDrawSurface_t& ds, const char *modelName, entity_t& entity ){
|
||||
const int spf = ( spawnFlags & ( eClipFlags & ~eClipModel ) );
|
||||
@@ -442,18 +471,14 @@ static void ClipModel( int spawnFlags, float clipDepth, shaderInfo_t& si, const
|
||||
|| spf == ( eExtrudeDownwards | eExtrudeUpwards | eAxialBackplane )
|
||||
|| spf == ( eExtrudeUpwards | eMaxExtrude )
|
||||
|| spf == ( eExtrudeUpwards | eAxialBackplane ) ){
|
||||
int j, k;
|
||||
//int ok=0, notok=0;
|
||||
float limDepth = 0;
|
||||
if ( clipDepth < 0 ){
|
||||
limDepth = -clipDepth;
|
||||
clipDepth = 2.0;
|
||||
clipDepth = 2.f;
|
||||
}
|
||||
Vector3 points[ 4 ];
|
||||
Plane3f plane, reverse, p[3];
|
||||
MinMax minmax;
|
||||
Vector3 avgDirection( 0 );
|
||||
int axis;
|
||||
size_t axis;
|
||||
|
||||
/* temp hack */
|
||||
if ( !si.clipModel && !( si.compileFlags & C_SOLID ) ) {
|
||||
@@ -467,18 +492,17 @@ static void ClipModel( int spawnFlags, float clipDepth, shaderInfo_t& si, const
|
||||
|
||||
if ( ( spf & eMaxExtrude ) || ( spf & eExtrudeTerrain ) ){
|
||||
|
||||
for ( auto i = ds.indexes.cbegin(); i != ds.indexes.cend(); i += 3 ){
|
||||
for ( j = 0; j < 3; ++j ){
|
||||
points[j] = ds.verts[ *( i + j ) ].xyz;
|
||||
}
|
||||
for ( auto idx = ds.indexes.cbegin(); idx != ds.indexes.cend(); idx += 3 ){
|
||||
const Vector3 points[3]{ ds.verts[*( idx + 0 )].xyz,
|
||||
ds.verts[*( idx + 1 )].xyz,
|
||||
ds.verts[*( idx + 2 )].xyz };
|
||||
Plane3f plane;
|
||||
if ( PlaneFromPoints( plane, points ) ){
|
||||
if ( spf & eExtrudeTerrain )
|
||||
avgDirection += plane.normal(); //calculate average mesh facing direction
|
||||
avgDirection += plane.normal(); // calculate average mesh facing direction
|
||||
|
||||
//get min/max
|
||||
for ( j = 0; j < 3; ++j ){
|
||||
minmax.extend( points[j] );
|
||||
}
|
||||
for ( const auto& p : points ) // get min/max
|
||||
minmax.extend( p );
|
||||
}
|
||||
}
|
||||
//unify avg direction
|
||||
@@ -498,143 +522,63 @@ static void ClipModel( int spawnFlags, float clipDepth, shaderInfo_t& si, const
|
||||
buildBrush.detail = true;
|
||||
|
||||
/* walk triangle list */
|
||||
for ( auto i = ds.indexes.cbegin(); i != ds.indexes.cend(); i += 3 ){
|
||||
for ( auto idx = ds.indexes.cbegin(); idx != ds.indexes.cend(); idx += 3 ){
|
||||
ClipSides cs;
|
||||
/* make points */
|
||||
for ( j = 0; j < 3; ++j ){
|
||||
for ( int i = 0; i < 3; ++i ){
|
||||
/* copy xyz */
|
||||
points[j] = ds.verts[ *( i + j ) ].xyz;
|
||||
cs.fw.push_back( ds.verts[*( idx + i )].xyz );
|
||||
}
|
||||
|
||||
/* make plane for triangle */
|
||||
if ( PlaneFromPoints( plane, points ) ) {
|
||||
//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)
|
||||
//also broken drawsurfs in case of normal brushes
|
||||
bool snpd = false;
|
||||
for ( j = 0; j < 3; ++j )
|
||||
{
|
||||
if ( std::fabs( plane.normal()[j] ) < 0.00025f && std::fabs( plane.normal()[( j + 1) % 3] ) < 0.00025f
|
||||
&& ( plane.normal()[j] != 0 || plane.normal()[( j + 1 ) % 3] != 0 ) ){
|
||||
const Vector3 cnt = ( points[0] + points[1] + points[2] ) / 3.0;
|
||||
points[0][( j + 2 ) % 3] = points[1][( j + 2 ) % 3] = points[2][( j + 2 ) % 3] = cnt[( j + 2 ) % 3];
|
||||
snpd = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//snap pairs of points to prevent bad side planes
|
||||
for ( j = 0; j < 3; ++j )
|
||||
{
|
||||
const Vector3 nrm = VectorNormalized( points[j] - points[( j + 1 ) % 3] );
|
||||
for ( k = 0; k < 3; ++k )
|
||||
{
|
||||
if ( nrm[k] != 0 && std::fabs( nrm[k] ) < 0.00025f ){
|
||||
//Sys_Printf( "b4(%6.6f %6.6f %6.6f)(%6.6f %6.6f %6.6f)\n", points[j][0], points[j][1], points[j][2], points[(j+1)%3][0], points[(j+1)%3][1], points[(j+1)%3][2] );
|
||||
points[j][k] = points[( j + 1 ) % 3][k] = ( points[j][k] + points[( j + 1 ) % 3][k] ) / 2.0;
|
||||
//Sys_Printf( "sn(%6.6f %6.6f %6.6f)(%6.6f %6.6f %6.6f)\n", points[j][0], points[j][1], points[j][2], points[(j+1)%3][0], points[(j+1)%3][1], points[(j+1)%3][2] );
|
||||
snpd = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( snpd ) {
|
||||
PlaneFromPoints( plane, points );
|
||||
snpd = false;
|
||||
}
|
||||
|
||||
//vector-is-close-to-be-on-axis check again, happens after previous code sometimes
|
||||
for ( j = 0; j < 3; ++j )
|
||||
{
|
||||
if ( std::fabs( plane.normal()[j] ) < 0.00025f && std::fabs( plane.normal()[( j + 1 ) % 3] ) < 0.00025f
|
||||
&& ( plane.normal()[j] != 0 || plane.normal()[( j + 1 ) % 3] != 0 ) ){
|
||||
const Vector3 cnt = ( points[0] + points[1] + points[2] ) / 3.0;
|
||||
points[0][( j + 2 ) % 3] = points[1][( j + 2 ) % 3] = points[2][( j + 2 ) % 3] = cnt[( j + 2 ) % 3];
|
||||
PlaneFromPoints( plane, points );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//snap single snappable normal components
|
||||
for ( j = 0; j < 3; ++j )
|
||||
{
|
||||
if ( plane.normal()[j] != 0 && std::fabs( plane.normal()[j] ) < 0.00005f ){
|
||||
plane.normal()[j] = 0;
|
||||
snpd = true;
|
||||
}
|
||||
}
|
||||
|
||||
//adjust plane dist
|
||||
if ( snpd ) {
|
||||
const Vector3 cnt = ( points[0] + points[1] + points[2] ) / 3.0;
|
||||
VectorNormalize( plane.normal() );
|
||||
plane.dist() = vector3_dot( plane.normal(), cnt );
|
||||
|
||||
//project points to resulting plane to keep intersections precision
|
||||
for ( j = 0; j < 3; ++j )
|
||||
{
|
||||
//Sys_Printf( "b4 %i (%6.7f %6.7f %6.7f)\n", j, points[j][0], points[j][1], points[j][2] );
|
||||
points[j] = plane3_project_point( plane, points[j] );
|
||||
//Sys_Printf( "sn %i (%6.7f %6.7f %6.7f)\n", j, points[j][0], points[j][1], points[j][2] );
|
||||
}
|
||||
//Sys_Printf( "sn pln (%6.7f %6.7f %6.7f %6.7f)\n", plane.a, plane.b, plane.c, plane.d );
|
||||
//PlaneFromPoints( plane, points );
|
||||
//Sys_Printf( "pts pln (%6.7f %6.7f %6.7f %6.7f)\n", plane.a, plane.b, plane.c, plane.d );
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
if ( triangle_min_angle_squared_sin( points[0], points[1], points[2] ) < 1e-8 ) {
|
||||
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: points on line\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], modelName );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( cs.construct() ) {
|
||||
|
||||
if ( spf == ( ePyramidaClip | eAxialBackplane ) ){ // pyramid with 3 of 4 sides axial (->small bsp)
|
||||
|
||||
for ( j = 0; j < 3; ++j )
|
||||
if ( std::fabs( plane.normal()[j] ) < 0.05f && std::fabs( plane.normal()[( j + 1 ) % 3] ) < 0.05f ) //no way, close to lay on two axes
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
if ( std::fabs( cs.fplane.normal()[i] ) < 0.05f && std::fabs( cs.fplane.normal()[( i + 1 ) % 3] ) < 0.05f ) //no way, close to lay on two axes
|
||||
goto default_CLIPMODEL;
|
||||
|
||||
// best axial normal
|
||||
Vector3 bestNormal = plane.normal();
|
||||
Vector3 bestNormal = cs.fplane.normal();
|
||||
axis = normal_make_axial( bestNormal );
|
||||
|
||||
float mindist = 999999;
|
||||
|
||||
for ( j = 0; j < 3; ++j ){ // planes
|
||||
for ( size_t i = 0; i < cs.fw.size(); ++i ){ // planes
|
||||
float bestdist = 999999, bestangle = 1;
|
||||
|
||||
for ( k = 0; k < 3; ++k ){ // axes
|
||||
Vector3 nrm = points[( j + 1 ) % 3] - points[j];
|
||||
if ( k == axis ){
|
||||
reverse.normal() = vector3_cross( bestNormal, nrm );
|
||||
for ( size_t j = 0; j < 3; ++j ){ // axes
|
||||
Plane3f pln;
|
||||
Vector3 nrm = cs.fw[winding_next( cs.fw, i )] - cs.fw[i];
|
||||
if ( j == axis ){
|
||||
pln.normal() = VectorNormalized( vector3_cross( bestNormal, nrm ) );
|
||||
}
|
||||
else{
|
||||
Vector3 vnrm( 0 );
|
||||
if ( ( k + 1 ) % 3 == axis ){
|
||||
if ( nrm[( k + 2 ) % 3] == 0 )
|
||||
if ( ( j + 1 ) % 3 == axis ){
|
||||
if ( nrm[( j + 2 ) % 3] == 0 )
|
||||
continue;
|
||||
vnrm[( k + 2 ) % 3] = nrm[( k + 2 ) % 3];
|
||||
vnrm[( j + 2 ) % 3] = nrm[( j + 2 ) % 3];
|
||||
}
|
||||
else{
|
||||
if ( nrm[( k + 1 ) % 3] == 0 )
|
||||
if ( nrm[( j + 1 ) % 3] == 0 )
|
||||
continue;
|
||||
vnrm[( k + 1 ) % 3] = nrm[( k + 1 ) % 3];
|
||||
vnrm[( j + 1 ) % 3] = nrm[( j + 1 ) % 3];
|
||||
}
|
||||
const Vector3 enrm = vector3_cross( bestNormal, vnrm );
|
||||
reverse.normal() = vector3_cross( enrm, nrm );
|
||||
pln.normal() = VectorNormalized( vector3_cross( enrm, nrm ) );
|
||||
}
|
||||
VectorNormalize( reverse.normal() );
|
||||
reverse.dist() = vector3_dot( points[ j ], reverse.normal() );
|
||||
pln.dist() = vector3_dot( cs.fw[i], pln.normal() );
|
||||
//check facing, thickness
|
||||
const float currdist = reverse.dist() - vector3_dot( reverse.normal(), points[( j + 2 ) % 3] );
|
||||
const float currangle = vector3_dot( reverse.normal(), plane.normal() );
|
||||
const float currdist = -plane3_distance_to_point( pln, cs.fw[( i + 2 ) % cs.fw.size()] );
|
||||
const float currangle = vector3_dot( pln.normal(), cs.fplane.normal() );
|
||||
if ( ( ( currdist > 0.1 ) && ( currdist < bestdist ) && ( currangle < 0 ) ) ||
|
||||
( ( currangle >= 0 ) && ( currangle <= bestangle ) ) ){
|
||||
bestangle = currangle;
|
||||
if ( currangle < 0 )
|
||||
bestdist = currdist;
|
||||
p[j] = reverse;
|
||||
cs.splanes[i] = pln;
|
||||
}
|
||||
}
|
||||
if ( bestdist == 999999 && bestangle == 1 ){
|
||||
@@ -646,12 +590,9 @@ static void ClipModel( int spawnFlags, float clipDepth, shaderInfo_t& si, const
|
||||
if ( ( limDepth != 0 ) && ( mindist > limDepth ) )
|
||||
goto default_CLIPMODEL;
|
||||
|
||||
nonax_clip_dbg( p );
|
||||
|
||||
make_brush_sides<4>( plane, p, reverse, points, si );
|
||||
cs.make_brush_sides( si );
|
||||
}
|
||||
|
||||
|
||||
else if ( spf == eExtrudeTerrain
|
||||
|| spf == eExtrudeDownwards
|
||||
|| spf == eExtrudeUpwards
|
||||
@@ -674,7 +615,7 @@ static void ClipModel( int spawnFlags, float clipDepth, shaderInfo_t& si, const
|
||||
else{
|
||||
axis = 2;
|
||||
if ( ( spf & eExtrudeDownwards ) && ( spf & eExtrudeUpwards ) ){
|
||||
bestNormal = plane.normal()[2] >= 0? g_vector3_axis_z : -g_vector3_axis_z;
|
||||
bestNormal = cs.fplane.normal().z() >= 0? g_vector3_axis_z : -g_vector3_axis_z;
|
||||
}
|
||||
else if ( spf & eExtrudeDownwards ){
|
||||
bestNormal = g_vector3_axis_z;
|
||||
@@ -683,134 +624,105 @@ static void ClipModel( int spawnFlags, float clipDepth, shaderInfo_t& si, const
|
||||
bestNormal = -g_vector3_axis_z;
|
||||
}
|
||||
else{ // best axial normal
|
||||
bestNormal = plane.normal();
|
||||
bestNormal = cs.fplane.normal();
|
||||
axis = normal_make_axial( bestNormal );
|
||||
}
|
||||
}
|
||||
|
||||
if ( vector3_dot( plane.normal(), bestNormal ) < 0.05 ){
|
||||
if ( vector3_dot( cs.fplane.normal(), bestNormal ) < 0.05 ){
|
||||
goto default_CLIPMODEL;
|
||||
}
|
||||
|
||||
|
||||
/* make side planes */
|
||||
for ( j = 0; j < 3; ++j )
|
||||
for ( size_t i = 0; i < cs.fw.size(); ++i )
|
||||
{
|
||||
p[j].normal() = VectorNormalized( vector3_cross( bestNormal, points[( j + 1 ) % 3] - points[j] ) );
|
||||
p[j].dist() = vector3_dot( points[j], p[j].normal() );
|
||||
cs.splanes[i].normal() = VectorNormalized( vector3_cross( bestNormal, cs.fw[winding_next( cs.fw, i )] - cs.fw[i] ) );
|
||||
cs.splanes[i].dist() = vector3_dot( cs.fw[i], cs.splanes[i].normal() );
|
||||
}
|
||||
|
||||
/* make back plane */
|
||||
if ( spf & eMaxExtrude ){ //max extrude
|
||||
reverse.normal() = -bestNormal;
|
||||
if ( bestNormal[axis] > 0 ){
|
||||
reverse.dist() = -minmax.mins[axis] + clipDepth;
|
||||
}
|
||||
else{
|
||||
reverse.dist() = minmax.maxs[axis] + clipDepth;
|
||||
}
|
||||
cs.bplane.normal() = -bestNormal;
|
||||
if ( bestNormal[axis] > 0 )
|
||||
cs.bplane.dist() = -minmax.mins[axis] + clipDepth;
|
||||
else
|
||||
cs.bplane.dist() = minmax.maxs[axis] + clipDepth;
|
||||
}
|
||||
else if ( spf & eAxialBackplane ){ //axial backplane
|
||||
reverse.normal() = -bestNormal;
|
||||
reverse.dist() = points[0][axis];
|
||||
cs.bplane.normal() = -bestNormal;
|
||||
cs.bplane.dist() = cs.fw[0][axis];
|
||||
if ( bestNormal[axis] > 0 ){
|
||||
for ( j = 1; j < 3; ++j ){
|
||||
value_minimize( reverse.dist(), points[j][axis] );
|
||||
for ( size_t i = 1; i < cs.fw.size(); ++i ){
|
||||
value_minimize( cs.bplane.dist(), cs.fw[i][axis] );
|
||||
}
|
||||
reverse.dist() = -reverse.dist() + clipDepth;
|
||||
cs.bplane.dist() = -cs.bplane.dist() + clipDepth;
|
||||
}
|
||||
else{
|
||||
for ( j = 1; j < 3; ++j ){
|
||||
value_maximize( reverse.dist(), points[j][axis] );
|
||||
for ( size_t i = 1; i < cs.fw.size(); ++i ){
|
||||
value_maximize( cs.bplane.dist(), cs.fw[i][axis] );
|
||||
}
|
||||
reverse.dist() += clipDepth;
|
||||
cs.bplane.dist() += clipDepth;
|
||||
}
|
||||
if ( limDepth != 0 ){
|
||||
Vector3 cnt = points[0];
|
||||
Vector3 cnt = cs.fw[0];
|
||||
if ( bestNormal[axis] > 0 ){
|
||||
for ( j = 1; j < 3; ++j ){
|
||||
if ( points[j][axis] > cnt[axis] ){
|
||||
cnt = points[j];
|
||||
}
|
||||
}
|
||||
for ( size_t i = 1; i < cs.fw.size(); ++i )
|
||||
if ( cs.fw[i][axis] > cnt[axis] )
|
||||
cnt = cs.fw[i];
|
||||
}
|
||||
else {
|
||||
for ( j = 1; j < 3; ++j ){
|
||||
if ( points[j][axis] < cnt[axis] ){
|
||||
cnt = points[j];
|
||||
}
|
||||
}
|
||||
for ( size_t i = 1; i < cs.fw.size(); ++i )
|
||||
if ( cs.fw[i][axis] < cnt[axis] )
|
||||
cnt = cs.fw[i];
|
||||
}
|
||||
cnt = plane3_project_point( reverse, cnt );
|
||||
if ( -plane3_distance_to_point( plane, cnt ) > limDepth ){
|
||||
reverse = plane3_flipped( plane );
|
||||
reverse.dist() += clipDepth;
|
||||
cnt = plane3_project_point( cs.bplane, cnt );
|
||||
if ( -plane3_distance_to_point( cs.fplane, cnt ) > limDepth ){ //normal backplane
|
||||
cs.add_back_plane( clipDepth, cs.fplane.normal() );
|
||||
}
|
||||
}
|
||||
}
|
||||
else{ //normal backplane
|
||||
reverse = plane3_flipped( plane );
|
||||
reverse.dist() += clipDepth;
|
||||
cs.add_back_plane( clipDepth, cs.fplane.normal() );
|
||||
}
|
||||
|
||||
nonax_clip_dbg( p );
|
||||
|
||||
make_brush_sides<5>( plane, p, reverse, points, si );
|
||||
cs.make_brush_sides( si );
|
||||
}
|
||||
|
||||
|
||||
else if ( spf == ( eExtrudeFaceNormals | ePyramidaClip ) ){ // extrude 45
|
||||
//45 degrees normals for side planes
|
||||
for ( j = 0; j < 3; ++j )
|
||||
/* 45 degrees normals for side planes */
|
||||
for ( size_t i = 0; i < cs.fw.size(); ++i )
|
||||
{
|
||||
const Vector3 nrm = points[( j + 1 ) % 3] - points[ j ];
|
||||
Vector3 enrm = VectorNormalized( vector3_cross( plane.normal(), nrm ) );
|
||||
enrm += plane.normal();
|
||||
VectorNormalize( enrm );
|
||||
const Vector3 enrm = VectorNormalized( vector3_cross( cs.fplane.normal(), cs.fw[winding_next( cs.fw, i )] - cs.fw[i] ) );
|
||||
/* make side planes */
|
||||
p[j].normal() = VectorNormalized( vector3_cross( enrm, nrm ) );
|
||||
p[j].dist() = vector3_dot( points[j], p[j].normal() );
|
||||
//snap nearly axial side planes
|
||||
snpd = false;
|
||||
for ( k = 0; k < 3; ++k )
|
||||
{
|
||||
if ( std::fabs( p[j].normal()[k] ) < 0.00025f && p[j].normal()[k] != 0 ){
|
||||
p[j].normal()[k] = 0;
|
||||
snpd = true;
|
||||
}
|
||||
}
|
||||
if ( snpd ){
|
||||
VectorNormalize( p[j].normal() );
|
||||
p[j].dist() = vector3_dot( ( points[j] + points[( j + 1 ) % 3] ) / 2.0, p[j].normal() );
|
||||
}
|
||||
cs.splanes[i].normal() = VectorNormalized( enrm - cs.fplane.normal() );
|
||||
cs.splanes[i].dist() = vector3_dot( cs.fw[i], cs.splanes[i].normal() );
|
||||
}
|
||||
|
||||
/* make back plane */
|
||||
reverse = plane3_flipped( plane );
|
||||
reverse.dist() += clipDepth;
|
||||
cs.add_back_plane( clipDepth, cs.fplane.normal() );
|
||||
|
||||
make_brush_sides<5>( plane, p, reverse, points, si );
|
||||
cs.make_brush_sides( si );
|
||||
}
|
||||
|
||||
|
||||
else if ( spf == eExtrudeVertexNormals
|
||||
|| spf == ( eExtrudeVertexNormals | ePyramidaClip ) ){ // vertex normals + don't check for sides, sticking outwards
|
||||
Vector3 Vnorm[3], Enorm[3];
|
||||
/* get vertex normals */
|
||||
for ( j = 0; j < 3; ++j ){
|
||||
for ( int i = 0; i < 3; ++i ){
|
||||
/* copy normal */
|
||||
Vnorm[j] = ds.verts[ *( i + j ) ].normal;
|
||||
Vnorm[i] = ds.verts[*( idx + i )].normal;
|
||||
}
|
||||
|
||||
//avg normals for side planes
|
||||
for ( j = 0; j < 3; ++j )
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
{
|
||||
Enorm[ j ] = VectorNormalized( Vnorm[ j ] + Vnorm[( j + 1 ) % 3] );
|
||||
Enorm[i] = VectorNormalized( Vnorm[i] + Vnorm[( i + 1 ) % 3] );
|
||||
//check fuer bad ones
|
||||
const Vector3 nrm = VectorNormalized( vector3_cross( plane.normal(), points[( j + 1 ) % 3] - points[ j ] ) );
|
||||
const Vector3 nrm = VectorNormalized( vector3_cross( cs.fplane.normal(), cs.fw[( i + 1 ) % 3] - cs.fw[i] ) );
|
||||
//check for negative or outside direction
|
||||
if ( vector3_dot( Enorm[j], plane.normal() ) > 0.1 ){
|
||||
if ( ( vector3_dot( Enorm[j], nrm ) > -0.2 ) || ( spf & ePyramidaClip ) ){
|
||||
if ( vector3_dot( Enorm[i], cs.fplane.normal() ) > 0.1 ){
|
||||
if ( ( vector3_dot( Enorm[i], nrm ) > -0.2 ) || ( spf & ePyramidaClip ) ){
|
||||
//ok++;
|
||||
continue;
|
||||
}
|
||||
@@ -818,141 +730,68 @@ static void ClipModel( int spawnFlags, float clipDepth, shaderInfo_t& si, const
|
||||
//notok++;
|
||||
//Sys_Printf( "faulty Enormal %i/%i\n", notok, ok );
|
||||
//use 45 normal
|
||||
Enorm[ j ] = plane.normal() + nrm;
|
||||
VectorNormalize( Enorm[ j ] );
|
||||
Enorm[i] = VectorNormalized( cs.fplane.normal() + nrm );
|
||||
}
|
||||
|
||||
/* make side planes */
|
||||
for ( j = 0; j < 3; ++j )
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
{
|
||||
p[j].normal() = VectorNormalized( vector3_cross( Enorm[j], points[( j + 1 ) % 3] - points[j] ) );
|
||||
p[j].dist() = vector3_dot( points[j], p[j].normal() );
|
||||
//snap nearly axial side planes
|
||||
snpd = false;
|
||||
for ( k = 0; k < 3; ++k )
|
||||
{
|
||||
if ( std::fabs( p[j].normal()[k] ) < 0.00025f && p[j].normal()[k] != 0 ){
|
||||
//Sys_Printf( "init plane %6.8f %6.8f %6.8f %6.8f\n", p[j].a, p[j].b, p[j].c, p[j].d );
|
||||
p[j].normal()[k] = 0;
|
||||
snpd = true;
|
||||
}
|
||||
}
|
||||
if ( snpd ){
|
||||
VectorNormalize( p[j].normal() );
|
||||
//Sys_Printf( "nrm plane %6.8f %6.8f %6.8f %6.8f\n", p[j].a, p[j].b, p[j].c, p[j].d );
|
||||
p[j].dist() = vector3_dot( ( points[j] + points[( j + 1 ) % 3] ) / 2.0, p[j].normal() );
|
||||
//Sys_Printf( "dst plane %6.8f %6.8f %6.8f %6.8f\n", p[j].a, p[j].b, p[j].c, p[j].d );
|
||||
}
|
||||
cs.splanes[i].normal() = VectorNormalized( vector3_cross( Enorm[i], cs.fw[( i + 1 ) % 3] - cs.fw[i] ) );
|
||||
cs.splanes[i].dist() = vector3_dot( cs.fw[i], cs.splanes[i].normal() );
|
||||
}
|
||||
|
||||
/* make back plane */
|
||||
reverse = plane3_flipped( plane );
|
||||
reverse.dist() += clipDepth;
|
||||
cs.add_back_plane( clipDepth, cs.fplane.normal() );
|
||||
|
||||
make_brush_sides<5>( plane, p, reverse, points, si );
|
||||
cs.make_brush_sides( si );
|
||||
}
|
||||
|
||||
|
||||
else if ( spf == eExtrudeFaceNormals ){
|
||||
|
||||
/* make side planes */
|
||||
for ( j = 0; j < 3; ++j )
|
||||
for ( size_t i = 0; i < cs.fw.size(); ++i )
|
||||
{
|
||||
p[j].normal() = VectorNormalized( vector3_cross( plane.normal(), points[( j + 1 ) % 3] - points[j] ) );
|
||||
p[j].dist() = vector3_dot( points[j], p[j].normal() );
|
||||
//snap nearly axial side planes
|
||||
snpd = false;
|
||||
for ( k = 0; k < 3; ++k )
|
||||
{
|
||||
if ( std::fabs( p[j].normal()[k] ) < 0.00025f && p[j].normal()[k] != 0 ){
|
||||
//Sys_Printf( "init plane %6.8f %6.8f %6.8f %6.8f\n", p[j].a, p[j].b, p[j].c, p[j].d );
|
||||
p[j].normal()[k] = 0;
|
||||
snpd = true;
|
||||
}
|
||||
}
|
||||
if ( snpd ){
|
||||
VectorNormalize( p[j].normal() );
|
||||
//Sys_Printf( "nrm plane %6.8f %6.8f %6.8f %6.8f\n", p[j].a, p[j].b, p[j].c, p[j].d );
|
||||
const Vector3 cnt = ( points[j] + points[( j + 1 ) % 3] ) / 2.0;
|
||||
p[j].dist() = vector3_dot( cnt, p[j].normal() );
|
||||
//Sys_Printf( "dst plane %6.8f %6.8f %6.8f %6.8f\n", p[j].a, p[j].b, p[j].c, p[j].d );
|
||||
}
|
||||
cs.splanes[i].normal() = VectorNormalized( vector3_cross( cs.fplane.normal(), cs.fw[winding_next( cs.fw, i )] - cs.fw[i] ) );
|
||||
cs.splanes[i].dist() = vector3_dot( cs.fw[i], cs.splanes[i].normal() );
|
||||
}
|
||||
|
||||
/* make back plane */
|
||||
reverse = plane3_flipped( plane );
|
||||
reverse.dist() += clipDepth;
|
||||
cs.add_back_plane( clipDepth, cs.fplane.normal() );
|
||||
|
||||
nonax_clip_dbg( p );
|
||||
|
||||
make_brush_sides<5>( plane, p, reverse, points, si );
|
||||
cs.make_brush_sides( si );
|
||||
}
|
||||
|
||||
|
||||
else if ( spf == ePyramidaClip ){
|
||||
|
||||
/* calculate center */
|
||||
Vector3 cnt = ( points[0] + points[1] + points[2] ) / 3.0;
|
||||
|
||||
Vector3 cnt = ( cs.fw[0] + cs.fw[1] + cs.fw[2] ) / 3.0;
|
||||
/* make back pyramid point */
|
||||
cnt -= plane.normal() * clipDepth;
|
||||
cnt -= cs.fplane.normal() * clipDepth; // might want to shift this, if produces sus sides, since extreme angle with front
|
||||
|
||||
/* make 3 more planes */
|
||||
if( PlaneFromPoints( p[0], points[1], points[0], cnt ) &&
|
||||
PlaneFromPoints( p[1], points[2], points[1], cnt ) &&
|
||||
PlaneFromPoints( p[2], points[0], points[2], cnt ) ) {
|
||||
|
||||
//check for dangerous planes
|
||||
while( ( ( p[0].a != 0 || p[0].b != 0 ) && std::fabs( p[0].a ) < 0.00025f && std::fabs( p[0].b ) < 0.00025f ) ||
|
||||
( ( p[0].a != 0 || p[0].c != 0 ) && std::fabs( p[0].a ) < 0.00025f && std::fabs( p[0].c ) < 0.00025f ) ||
|
||||
( ( p[0].c != 0 || p[0].b != 0 ) && std::fabs( p[0].c ) < 0.00025f && std::fabs( p[0].b ) < 0.00025f ) ||
|
||||
( ( p[1].a != 0 || p[1].b != 0 ) && std::fabs( p[1].a ) < 0.00025f && std::fabs( p[1].b ) < 0.00025f ) ||
|
||||
( ( p[1].a != 0 || p[1].c != 0 ) && std::fabs( p[1].a ) < 0.00025f && std::fabs( p[1].c ) < 0.00025f ) ||
|
||||
( ( p[1].c != 0 || p[1].b != 0 ) && std::fabs( p[1].c ) < 0.00025f && std::fabs( p[1].b ) < 0.00025f ) ||
|
||||
( ( p[2].a != 0 || p[2].b != 0 ) && std::fabs( p[2].a ) < 0.00025f && std::fabs( p[2].b ) < 0.00025f ) ||
|
||||
( ( p[2].a != 0 || p[2].c != 0 ) && std::fabs( p[2].a ) < 0.00025f && std::fabs( p[2].c ) < 0.00025f ) ||
|
||||
( ( p[2].c != 0 || p[2].b != 0 ) && std::fabs( p[2].c ) < 0.00025f && std::fabs( p[2].b ) < 0.00025f ) ) {
|
||||
cnt -= plane.normal() * 0.1f;
|
||||
// Sys_Printf( "shifting pyramid point\n" );
|
||||
PlaneFromPoints( p[0], points[1], points[0], cnt );
|
||||
PlaneFromPoints( p[1], points[2], points[1], cnt );
|
||||
PlaneFromPoints( p[2], points[0], points[2], cnt );
|
||||
}
|
||||
|
||||
nonax_clip_dbg( p );
|
||||
|
||||
make_brush_sides<4>( plane, p, reverse, points, si );
|
||||
}
|
||||
else
|
||||
for ( size_t i = 0; i < cs.fw.size(); ++i )
|
||||
{
|
||||
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], modelName );
|
||||
continue;
|
||||
PlaneFromPoints( cs.splanes[i], cs.fw[winding_next( cs.fw, i )], cs.fw[i], cnt );
|
||||
}
|
||||
|
||||
cs.make_brush_sides( si );
|
||||
}
|
||||
|
||||
|
||||
else if ( ( si.clipModel && spf == 0 ) || ( spawnFlags & eClipFlags ) == eClipModel ){ //default CLIPMODEL
|
||||
|
||||
default_CLIPMODEL:
|
||||
// axial normal
|
||||
Vector3 bestNormal = plane.normal();
|
||||
Vector3 bestNormal = cs.fplane.normal();
|
||||
normal_make_axial( bestNormal );
|
||||
|
||||
/* make side planes */
|
||||
for ( j = 0; j < 3; ++j )
|
||||
for ( size_t i = 0; i < cs.fw.size(); ++i )
|
||||
{
|
||||
p[j].normal() = VectorNormalized( vector3_cross( bestNormal, points[( j + 1 ) % 3] - points[j] ) );
|
||||
p[j].dist() = vector3_dot( points[j], p[j].normal() );
|
||||
cs.splanes[i].normal() = VectorNormalized( vector3_cross( bestNormal, cs.fw[winding_next( cs.fw, i )] - cs.fw[i] ) );
|
||||
cs.splanes[i].dist() = vector3_dot( cs.fw[i], cs.splanes[i].normal() );
|
||||
}
|
||||
|
||||
/* make back plane */
|
||||
reverse = plane3_flipped( plane );
|
||||
reverse.dist() += vector3_dot( bestNormal, plane.normal() ) * clipDepth;
|
||||
cs.add_back_plane( clipDepth, bestNormal );
|
||||
|
||||
nonax_clip_dbg( p );
|
||||
|
||||
make_brush_sides<5>( plane, p, reverse, points, si );
|
||||
cs.make_brush_sides( si );
|
||||
}
|
||||
|
||||
|
||||
@@ -963,12 +802,13 @@ default_CLIPMODEL:
|
||||
brush_t& newBrush = entity.brushes.emplace_front( buildBrush );
|
||||
newBrush.original = &newBrush;
|
||||
entity.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], modelName );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
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",
|
||||
cs.fw[0][0], cs.fw[0][1], cs.fw[0][2],
|
||||
cs.fw[1][0], cs.fw[1][1], cs.fw[1][2],
|
||||
cs.fw[2][0], cs.fw[2][1], cs.fw[2][2], modelName );
|
||||
}
|
||||
// normalEpsilon = normalEpsilon_save;
|
||||
}
|
||||
|
||||
@@ -1569,9 +1569,10 @@ public:
|
||||
|
||||
/* map.c */
|
||||
void LoadMapFile( const char *filename, bool onlyLights, bool noCollapseGroups );
|
||||
int FindFloatPlane( const Plane3f& plane, int numPoints, const Vector3 *points );
|
||||
inline int FindFloatPlane( const Vector3& normal, float dist, int numPoints, const Vector3 *points ){
|
||||
return FindFloatPlane( Plane3f( normal, dist ), numPoints, points );
|
||||
void SnapPlaneImproved( Plane3f& plane, const Span<const Vector3>& points );
|
||||
int FindFloatPlane( const Plane3f& plane, const Span<const Vector3>& points );
|
||||
inline int FindFloatPlane( const Vector3& normal, float dist, const Span<const Vector3>& points ){
|
||||
return FindFloatPlane( Plane3f( normal, dist ), points );
|
||||
}
|
||||
bool PlaneEqual( const plane_t& p, const Plane3f& plane );
|
||||
void AddBrushBevels();
|
||||
|
||||
@@ -398,7 +398,7 @@ void ClassifySurface( mapDrawSurface_t& ds ){
|
||||
/* find map plane if necessary */
|
||||
if ( ds.planar ) {
|
||||
if ( ds.planeNum < 0 ) {
|
||||
ds.planeNum = FindFloatPlane( plane, 1, &ds.verts[ 0 ].xyz );
|
||||
ds.planeNum = FindFloatPlane( plane, Span( &ds.verts[ 0 ].xyz, 1 ) );
|
||||
}
|
||||
ds.lightmapVecs[ 2 ] = plane.normal();
|
||||
}
|
||||
@@ -873,7 +873,7 @@ mapDrawSurface_t *DrawSurfaceForMesh( const entity_t& e, parseMesh_t& p, mesh_t
|
||||
/* add a map plane */
|
||||
if ( planar ) {
|
||||
/* make a map plane */
|
||||
ds.planeNum = FindFloatPlane( plane, 1, &mesh->verts[ 0 ].xyz );
|
||||
ds.planeNum = FindFloatPlane( plane, Span( &mesh->verts[ 0 ].xyz, 1 ) );
|
||||
ds.lightmapVecs[ 2 ] = plane.normal();
|
||||
|
||||
/* push this normal to all verts (ydnar 2003-02-14: bad idea, small patches get screwed up) */
|
||||
@@ -2524,7 +2524,7 @@ static void MakeDebugPortalSurfs_r( const node_t *node, shaderInfo_t& si ){
|
||||
mapDrawSurface_t& ds = AllocDrawSurface( ESurfaceType::Face );
|
||||
ds.shaderInfo = &si;
|
||||
ds.planar = true;
|
||||
ds.planeNum = FindFloatPlane( p->plane.plane, 0, nullptr );
|
||||
ds.planeNum = FindFloatPlane( p->plane.plane, {} );
|
||||
ds.lightmapVecs[ 2 ] = p->plane.normal();
|
||||
ds.fogNum = FOG_INVALID;
|
||||
ds.verts.resize( w.size(), c_bspDrawVert_t0 );
|
||||
|
||||
Reference in New Issue
Block a user