]> de.git.xonotic.org Git - xonotic/netradiant.git/commitdiff
Merge commit 'e876e8ef487eeb9123f4906373622ffe3b6ea9d4' into master-merge
authorThomas Debesse <dev@illwieckz.net>
Mon, 20 Jun 2022 02:26:13 +0000 (04:26 +0200)
committerThomas Debesse <dev@illwieckz.net>
Mon, 20 Jun 2022 02:26:13 +0000 (04:26 +0200)
Makefile
radiant/csg.cpp
tools/quake3/q3map2/bsp.c
tools/quake3/q3map2/map.c
tools/quake3/q3map2/model.c
tools/quake3/q3map2/q3map2.h
tools/quake3/q3map2/surface.c
tools/quake3/q3map2/surface_foliage.c

index 82653f830236eae69fa45afa5dd729b04bcc9cce..ef66076f5a13dd13713ab779d7c5746724968567 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ MAKEFILE_CONF      ?= Makefile.conf
 # user customizable stuf
 # you may override this in Makefile.conf or the environment
 BUILD              ?= debug
-# or: release, or: extradebug, or: profile
+# or: release, or: extradebug, or: profile, or: debug
 OS                 ?= $(shell uname)
 # or: Linux, Win32, Darwin
 LDFLAGS            ?=
index f28bdc98d202d0465f8bac6654f4e05b2abbfe4b..2a59d2fec6785eb8cdb96527e3ada8be4b8c3e7b 100644 (file)
 #include "brushmanip.h"
 #include "brushnode.h"
 #include "grid.h"
+/*
+void Face_makeBrush( Face& face, const Brush& brush, brush_vector_t& out, float offset ){
+       if ( face.contributes() ) {
+               out.push_back( new Brush( brush ) );
+               Face* newFace = out.back()->addFace( face );
+               if ( newFace != 0 ) {
+                       newFace->flipWinding();
+                       newFace->getPlane().offset( offset );
+                       newFace->planeChanged();
+               }
+       }
+}
+*/
 
 void Face_makeBrush( Face& face, const Brush& brush, brush_vector_t& out, float offset ){
        if ( face.contributes() ) {
                out.push_back( new Brush( brush ) );
+               //face.getPlane().offset( -offset );
+               //face.planeChanged();
                std::shared_ptr<Face> newFace = out.back()->addFace( face );
                if ( newFace != 0 ) {
                        newFace->flipWinding();
@@ -420,51 +435,51 @@ void post( const scene::Path& path, scene::Instance& instance ) const {
                return;
        }
 
-       Brush* brush = Node_getBrush( path.top() );
+               Brush* brush = Node_getBrush( path.top() );
        if ( brush == nullptr || !Instance_getSelectable( instance )->isSelected() ) {
                return;
        }
 
-       Plane3 plane( plane3_for_points( m_p0, m_p1, m_p2 ) );
+                       Plane3 plane( plane3_for_points( m_p0, m_p1, m_p2 ) );
        if ( !plane3_valid( plane ) ) {
                return;
        }
 
-       brushsplit_t split = Brush_classifyPlane( *brush, m_split == eFront ? plane3_flipped( plane ) : plane );
-       if ( split.counts[ePlaneBack] && split.counts[ePlaneFront] ) {
-               // the plane intersects this brush
-               if ( m_split == eFrontAndBack ) {
-                       NodeSmartReference node( ( new BrushNode() )->node() );
-                       Brush* fragment = Node_getBrush( node );
-                       fragment->copy( *brush );
+                               brushsplit_t split = Brush_classifyPlane( *brush, m_split == eFront ? plane3_flipped( plane ) : plane );
+                               if ( split.counts[ePlaneBack] && split.counts[ePlaneFront] ) {
+                                       // the plane intersects this brush
+                                       if ( m_split == eFrontAndBack ) {
+                                               NodeSmartReference node( ( new BrushNode() )->node() );
+                                               Brush* fragment = Node_getBrush( node );
+                                               fragment->copy( *brush );
                        std::shared_ptr<Face> newFace =
                                fragment->addPlane( m_p0, m_p1, m_p2, m_shader, m_projection );
-                       if ( newFace != 0 && m_split != eFront ) {
-                               newFace->flipWinding();
-                       }
-                       fragment->removeEmptyFaces();
-                       ASSERT_MESSAGE( !fragment->empty(), "brush left with no faces after split" );
+                                               if ( newFace != 0 && m_split != eFront ) {
+                                                       newFace->flipWinding();
+                                               }
+                                               fragment->removeEmptyFaces();
+                                               ASSERT_MESSAGE( !fragment->empty(), "brush left with no faces after split" );
 
-                       Node_getTraversable( path.parent() )->insert( node );
-                       {
-                               scene::Path fragmentPath = path;
-                               fragmentPath.top() = makeReference( node.get() );
-                               selectPath( fragmentPath, true );
-                       }
-               }
+                                               Node_getTraversable( path.parent() )->insert( node );
+                                               {
+                                                       scene::Path fragmentPath = path;
+                                                       fragmentPath.top() = makeReference( node.get() );
+                                                       selectPath( fragmentPath, true );
+                                               }
+                                       }
 
                std::shared_ptr<Face> newFace = brush->addPlane( m_p0, m_p1, m_p2, m_shader, m_projection );
-               if ( newFace != 0 && m_split == eFront ) {
-                       newFace->flipWinding();
-               }
-               brush->removeEmptyFaces();
-               ASSERT_MESSAGE( !brush->empty(), "brush left with no faces after split" );
-       }
-       else
-       // the plane does not intersect this brush
-       if ( m_split != eFrontAndBack && split.counts[ePlaneBack] != 0 ) {
-               // the brush is "behind" the plane
-               Path_deleteTop( path );
+                                       if ( newFace != 0 && m_split == eFront ) {
+                                               newFace->flipWinding();
+                                       }
+                                       brush->removeEmptyFaces();
+                                       ASSERT_MESSAGE( !brush->empty(), "brush left with no faces after split" );
+                               }
+                               else
+                               // the plane does not intersect this brush
+                               if ( m_split != eFrontAndBack && split.counts[ePlaneBack] != 0 ) {
+                                       // the brush is "behind" the plane
+                                       Path_deleteTop( path );
        }
 }
 };
index 0f62ba14bf5e14124db5312ae6197c5a414ce171..168246266b6cb91497fb39d4c82298a183b7b3bf 100644 (file)
@@ -991,9 +991,10 @@ int BSPMain( int argc, char **argv ){
                        Sys_Printf( "Debug model clip enabled\n" );
                        debugClip = qtrue;
                }
-               else if ( !strcmp( argv[ i ], "-snapmodelclip" ) ) {
-                       Sys_Printf( "Snapping model clip enabled\n" );
-                       snapModelClip = qtrue;
+               else if ( !strcmp( argv[ i ],  "-clipdepth" ) ) {
+                       clipDepthGlobal = atof( argv[ i + 1 ] );
+                       i++;
+                       Sys_Printf( "Model autoclip thickness set to %.3f\n", clipDepthGlobal );
                }
                else if ( !strcmp( argv[ i ], "-sRGBtex" ) ) {
                        texturesRGB = qtrue;
index 08d0a56899bf74c98c7319115220a353696b7c7f..fabbcc8331485c85dd9ba85caa6742f6181b69c6 100644 (file)
@@ -69,7 +69,7 @@ qboolean PlaneEqual( plane_t *p, vec3_t normal, vec_t dist ){
 
        /* compare */
        // We check equality of each component since we're using '<', not '<='
-       // (the epsilons may be zero).  We want to use '<' intead of '<=' to be
+       // (the epsilons may be zero).  We want to use '<' instead of '<=' to be
        // consistent with the true meaning of "epsilon", and also because other
        // parts of the code uses this inequality.
        if ( ( p->dist == dist || fabs( p->dist - dist ) < de ) &&
@@ -164,6 +164,44 @@ qboolean SnapNormal( vec3_t normal ){
        // normalized).  The original SnapNormal() didn't snap such vectors - it
        // only snapped vectors that were near a perfect axis.
 
+       //adjusting vectors, that were near a perfect axis, with bigger epsilon
+       //they cause precision errors
+
+       /*
+       if ( ( normal[0] != 0.0 || normal[1] != 0.0 ) && fabs(normal[0]) < 0.00025 && fabs(normal[1]) < 0.00025){
+               normal[0] = normal[1] = 0.0;
+               adjusted = qtrue;
+       }
+       else if ( ( normal[0] != 0.0 || normal[2] != 0.0 ) && fabs(normal[0]) < 0.00025 && fabs(normal[2]) < 0.00025){
+               normal[0] = normal[2] = 0.0;
+               adjusted = qtrue;
+       }
+       else if ( ( normal[2] != 0.0 || normal[1] != 0.0 ) && fabs(normal[2]) < 0.00025 && fabs(normal[1]) < 0.00025){
+               normal[2] = normal[1] = 0.0;
+               adjusted = qtrue;
+       }
+       */
+
+       /*
+       for ( i=0; i<30; i++ )
+       {
+               double x, y, z, length;
+               x=(double) 1.0;
+               y=(double) ( 0.00001 * i );
+               z=(double) 0.0;
+
+               Sys_Printf("(%6.18f %6.18f %6.18f)inNormal\n", x,y,z );
+
+               length = sqrt( ( x * x ) + ( y * y ) + ( z * z ) );
+               Sys_Printf("(%6.18f)length\n", length);
+               x = (vec_t) ( x / length );
+               y = (vec_t) ( y / length );
+               z = (vec_t) ( z / length );
+               Sys_Printf("(%6.18f %6.18f %6.18f)outNormal\n\n", x,y,z );
+       }
+       Error("vectorNormalize test completed");
+       */
+
        for ( i = 0; i < 3; i++ )
        {
                if ( normal[i] != 0.0 && -normalEpsilon < normal[i] && normal[i] < normalEpsilon ) {
@@ -326,12 +364,7 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points )
 
        VectorCopy( innormal, normal );
 #if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX
-       if ( !doingModelClip ) {
-               SnapPlaneImproved( normal, &dist, numPoints, (const vec3_t *) points );
-       }
-       if ( doingModelClip && snapModelClip ) {
-               SnapPlane( normal, &dist );
-       }
+       SnapPlaneImproved( normal, &dist, numPoints, (const vec3_t *) points );
 #else
        SnapPlane( normal, &dist );
 #endif
index 8f70094a89ba1f6bef39a15a63e4ed8357b2dc83..27edf7e4637851b8f8c3fd7a3b682fb04b74d870 100644 (file)
@@ -210,8 +210,8 @@ picoModel_t *LoadModel( const char *name, int frame ){
    adds a picomodel into the bsp
  */
 
-void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap_t *remap, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle ){
-       int i, j, s, numSurfaces;
+void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap_t *remap, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth ){
+       int i, j, s, k, numSurfaces;
        m4x4_t identity, nTransform;
        picoModel_t         *model;
        picoShader_t        *shader;
@@ -226,12 +226,18 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
        picoIndex_t         *indexes;
        remap_t             *rm, *glob;
        skinfile_t          *sf, *sf2;
-       double normalEpsilon_save;
-       double distanceEpsilon_save;
        char skinfilename[ MAX_QPATH ];
        char                *skinfilecontent;
        int skinfilesize;
        char                *skinfileptr, *skinfilenextptr;
+       int ok=0, notok=0, spf = ( spawnFlags & 8088 );
+       float limDepth=0;
+
+
+       if ( clipDepth < 0 ){
+               limDepth = -clipDepth;
+               clipDepth = 2.0;
+       }
 
 
        /* get model */
@@ -418,15 +424,7 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
                if ( ( si != NULL && si->forceMeta ) || ( spawnFlags & 4 ) ) { /* 3rd bit */
                        ds->type = SURFACE_FORCED_META;
                }
-/*             else
-                       {
-                               //fix not requested lightmapping of models :E
-                               // else force vertexlit
-                               //      ApplySurfaceParm( "pointlight", &si->contentFlags, &si->surfaceFlags, &si->compileFlags );
-                               //   si->compileFlags |= C_VERTEXLIT;
-                               //ds->type == SURFACE_TRIANGLES;
-                       }
-*/
+
                /* fix the surface's normals (jal: conditioned by shader info) */
                if ( !( spawnFlags & 64 ) && ( shadeAngle == 0.0f || ds->type != SURFACE_FORCED_META ) ) {
                        PicoFixSurfaceNormals( surface );
@@ -522,23 +520,99 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
                ds->celShader = celShader;
 
                /* ydnar: giant hack land: generate clipping brushes for model triangles */
-               if ( si->clipModel || ( spawnFlags & 2 ) ) { /* 2nd bit */
-                       vec3_t points[ 4 ], backs[ 3 ];
-                       vec4_t plane, reverse, pa, pb, pc;
-
+               if ( ( si->clipModel && !( spf ) ) ||   //default CLIPMODEL
+                       ( ( spawnFlags & 8090 ) == 2 ) ||       //default CLIPMODEL
+                       ( spf == 8 ) ||         //EXTRUDE_FACE_NORMALS
+                       ( spf == 16 )   ||      //EXTRUDE_TERRAIN
+                       ( spf == 128 )  ||      //EXTRUDE_VERTEX_NORMALS
+                       ( spf == 256 )  ||      //PYRAMIDAL_CLIP
+                       ( spf == 512 )  ||      //EXTRUDE_DOWNWARDS
+                       ( spf == 1024 ) ||      //EXTRUDE_UPWARDS
+                       ( spf == 4096 ) ||      //default CLIPMODEL + AXIAL_BACKPLANE
+                       ( spf == 264 )  ||      //EXTRUDE_FACE_NORMALS+PYRAMIDAL_CLIP (extrude 45)
+                       ( spf == 2064 ) ||      //EXTRUDE_TERRAIN+MAX_EXTRUDE
+                       ( spf == 4112 ) ||      //EXTRUDE_TERRAIN+AXIAL_BACKPLANE
+                       ( spf == 384 )  ||      //EXTRUDE_VERTEX_NORMALS + PYRAMIDAL_CLIP - vertex normals + don't check for sides, sticking outwards
+                       ( spf == 4352 ) ||      //PYRAMIDAL_CLIP+AXIAL_BACKPLANE
+                       ( spf == 1536 ) ||      //EXTRUDE_DOWNWARDS+EXTRUDE_UPWARDS
+                       ( spf == 2560 ) ||      //EXTRUDE_DOWNWARDS+MAX_EXTRUDE
+                       ( spf == 4608 ) ||      //EXTRUDE_DOWNWARDS+AXIAL_BACKPLANE
+                       ( spf == 3584 ) ||      //EXTRUDE_DOWNWARDS+EXTRUDE_UPWARDS+MAX_EXTRUDE
+                       ( spf == 5632 ) ||      //EXTRUDE_DOWNWARDS+EXTRUDE_UPWARDS+AXIAL_BACKPLANE
+                       ( spf == 3072 ) ||      //EXTRUDE_UPWARDS+MAX_EXTRUDE
+                       ( spf == 5120 ) ){      //EXTRUDE_UPWARDS+AXIAL_BACKPLANE
+                       vec3_t points[ 4 ], backs[ 3 ], cnt, bestNormal, nrm, Vnorm[3], Enorm[3];
+                       vec4_t plane, reverse, p[3];
+                       double normalEpsilon_save;
+                       qboolean snpd;
+                       vec3_t min = { 999999, 999999, 999999 }, max = { -999999, -999999, -999999 };
+                       vec3_t avgDirection = { 0, 0, 0 };
+                       int axis;
+                       #define nonax_clip_dbg 1
 
                        /* temp hack */
                        if ( !si->clipModel && !( si->compileFlags & C_SOLID ) ) {
                                continue;
                        }
 
+                       //wont snap these in normal way, or will explode
+                       normalEpsilon_save = normalEpsilon;
+                       //normalEpsilon = 0.000001;
+
+
+                       //MAX_EXTRUDE or EXTRUDE_TERRAIN
+                       if ( ( spawnFlags & 2048 ) || ( spawnFlags & 16 ) ){
+
+                               for ( i = 0; i < ds->numIndexes; i += 3 )
+                               {
+                                       for ( j = 0; j < 3; j++ )
+                                       {
+                                               dv = &ds->verts[ ds->indexes[ i + j ] ];
+                                               VectorCopy( dv->xyz, points[ j ] );
+                                       }
+                                       if ( PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] ) ){
+                                               if ( spawnFlags & 16 ) VectorAdd( avgDirection, plane, avgDirection );  //calculate average mesh facing direction
+
+                                               //get min/max
+                                               for ( k = 2; k > -1; k-- ){
+                                                       if ( plane[k] > 0 ){
+                                                               for ( j = 0; j < 3; j++ ){ if ( points[j][k] < min[k] ) min[k] = points[j][k]; }
+                                                       }
+                                                       else if ( plane[k] < 0 ){
+                                                               for ( j = 0; j < 3; j++ ){ if ( points[j][k] > max[k] ) max[k] = points[j][k]; }
+                                                       }
+                                                       //if EXTRUDE_DOWNWARDS or EXTRUDE_UPWARDS
+                                                       if ( ( spawnFlags & 512 ) || ( spawnFlags & 1024 ) ){
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                               //unify avg direction
+                               if ( spawnFlags & 16 ){
+                                       for ( j = 0; j < 3; j++ ){
+                                               if ( fabs(avgDirection[j]) > fabs(avgDirection[(j+1)%3]) ){
+                                                       avgDirection[(j+1)%3] = 0.0;
+                                                       axis = j;
+                                               }
+                                               else {
+                                                       avgDirection[j] = 0.0;
+                                               }
+                                       }
+                                       if ( VectorNormalize( avgDirection, avgDirection ) == 0 ){
+                                               axis = 2;
+                                               VectorSet( avgDirection, 0, 0, 1 );
+                                       }
+                               }
+                       }
+
                        /* walk triangle list */
                        for ( i = 0; i < ds->numIndexes; i += 3 )
                        {
                                /* overflow hack */
                                AUTOEXPAND_BY_REALLOC( mapplanes, ( nummapplanes + 64 ) << 1, allocatedmapplanes, 1024 );
 
-                               /* make points and back points */
+                               /* make points */
                                for ( j = 0; j < 3; j++ )
                                {
                                        /* get vertex */
@@ -548,105 +622,667 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
                                        VectorCopy( dv->xyz, points[ j ] );
                                }
 
-                               VectorCopy( points[0], points[3] ); // for cyclic usage
-
                                /* make plane for triangle */
-                               // div0: add some extra spawnflags:
-                               //   0: snap normals to axial planes for extrusion
-                               //   8: extrude with the original normals
-                               //  16: extrude only with up/down normals (ideal for terrain)
-                               //  24: extrude by distance zero (may need engine changes)
                                if ( PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] ) ) {
-                                       vec3_t bestNormal;
-                                       float backPlaneDistance = 2;
 
-                                       if ( spawnFlags & 8 ) { // use a DOWN normal
-                                               if ( spawnFlags & 16 ) {
-                                                       // 24: normal as is, and zero width (broken)
-                                                       VectorCopy( plane, bestNormal );
+                                       /* 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 = qtrue;
+
+                                       //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
+                                       snpd = qfalse;
+                                       for ( j=0; j<3; j++ )
+                                       {
+                                               if ( fabs(plane[j]) < 0.00025 && fabs(plane[(j+1)%3]) < 0.00025 && ( plane[j] != 0.0 || plane[(j+1)%3] != 0.0 ) ){
+                                                       VectorAdd( points[ 0 ], points[ 1 ], cnt );
+                                                       VectorAdd( cnt, points[ 2 ], cnt );
+                                                       VectorScale( cnt, 0.3333333333333f, cnt );
+                                                       points[0][(j+2)%3]=points[1][(j+2)%3]=points[2][(j+2)%3]=cnt[(j+2)%3];
+                                                       snpd = qtrue;
+                                                       break;
                                                }
-                                               else
+                                       }
+
+                                       //snap pairs of points to prevent bad side planes
+                                       for ( j=0; j<3; j++ )
+                                       {
+                                               VectorSubtract( points[j], points[(j+1)%3], nrm );
+                                               VectorNormalize( nrm, nrm );
+                                               for ( k=0; k<3; k++ )
                                                {
-                                                       // 8: normal as is
-                                                       VectorCopy( plane, bestNormal );
+                                                       if ( nrm[k] != 0.0 && fabs(nrm[k]) < 0.00025 ){
+                                                               //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 = qtrue;
+                                                       }
                                                }
                                        }
-                                       else
+
+                                       if ( snpd ) {
+                                               PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] );
+                                               snpd = qfalse;
+                                       }
+
+                                       //vector-is-close-to-be-on-axis check again, happens after previous code sometimes
+                                       for ( j=0; j<3; j++ )
                                        {
-                                               if ( spawnFlags & 16 ) {
-                                                       // 16: UP/DOWN normal
-                                                       VectorSet( bestNormal, 0, 0, ( plane[2] >= 0 ? 1 : -1 ) );
+                                               if ( fabs(plane[j]) < 0.00025 && fabs(plane[(j+1)%3]) < 0.00025 && ( plane[j] != 0.0 || plane[(j+1)%3] != 0.0 ) ){
+                                                       VectorAdd( points[ 0 ], points[ 1 ], cnt );
+                                                       VectorAdd( cnt, points[ 2 ], cnt );
+                                                       VectorScale( cnt, 0.3333333333333f, cnt );
+                                                       points[0][(j+2)%3]=points[1][(j+2)%3]=points[2][(j+2)%3]=cnt[(j+2)%3];
+                                                       PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] );
+                                                       break;
                                                }
-                                               else
+                                       }
+
+                                       //snap single snappable normal components
+                                       for ( j=0; j<3; j++ )
+                                       {
+                                               if ( plane[j] != 0.0 && fabs(plane[j]) < 0.00005 ){
+                                                       plane[j]=0.0;
+                                                       snpd = qtrue;
+                                               }
+                                       }
+
+                                       //adjust plane dist
+                                       if ( snpd ) {
+                                               VectorAdd( points[ 0 ], points[ 1 ], cnt );
+                                               VectorAdd( cnt, points[ 2 ], cnt );
+                                               VectorScale( cnt, 0.3333333333333f, cnt );
+                                               VectorNormalize( plane, plane );
+                                               plane[3] = DotProduct( plane, 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] );
+                                                       VectorMA( points[j], plane[3] - DotProduct( plane, points[j]), 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[0], plane[1], plane[2], plane[3] );
+                                               //PlaneFromPoints( plane, points[ 0 ], points[ 1 ], points[ 2 ] );
+                                               //Sys_Printf( "pts pln (%6.7f %6.7f %6.7f %6.7f)\n", plane[0], plane[1], plane[2], plane[3] );
+                                       }
+
+
+                                       if ( spf == 4352 ){     //PYRAMIDAL_CLIP+AXIAL_BACKPLANE
+
+                                               for ( j=0; j<3; j++ )
                                                {
-                                                       // 0: axial normal
-                                                       if ( fabs( plane[0] ) > fabs( plane[1] ) ) { // x>y
-                                                               if ( fabs( plane[1] ) > fabs( plane[2] ) ) { // x>y, y>z
-                                                                       VectorSet( bestNormal, ( plane[0] >= 0 ? 1 : -1 ), 0, 0 );
+                                                       if ( fabs(plane[j]) < 0.05 && fabs(plane[(j+1)%3]) < 0.05 ){ //no way, close to lay on two axises
+                                                               goto default_CLIPMODEL;
+                                                       }
+                                               }
+
+                                               // best axial normal
+                                               VectorCopy( plane, bestNormal );
+                                               for ( j = 0; j < 3; j++ ){
+                                                       if ( fabs(bestNormal[j]) > fabs(bestNormal[(j+1)%3]) ){
+                                                               bestNormal[(j+1)%3] = 0.0;
+                                                               axis = j;
+                                                       }
+                                                       else {
+                                                               bestNormal[j] = 0.0;
+                                                       }
+                                               }
+                                               VectorNormalize( bestNormal, bestNormal );
+
+
+                                               float bestdist, currdist, bestangle, currangle, mindist = 999999;
+
+                                               for ( j = 0; j < 3; j++ ){//planes
+                                                       bestdist = 999999;
+                                                       bestangle = 1;
+                                                       for ( k = 0; k < 3; k++ ){//axises
+                                                               VectorSubtract( points[ (j+1)%3 ], points[ j ], nrm );
+                                                               if ( k == axis ){
+                                                                       CrossProduct( bestNormal, nrm, reverse );
                                                                }
-                                                               else // x>y, z>=y
-                                                               if ( fabs( plane[0] ) > fabs( plane[2] ) ) { // x>z, z>=y
-                                                                       VectorSet( bestNormal, ( plane[0] >= 0 ? 1 : -1 ), 0, 0 );
+                                                               else{
+                                                                       VectorClear( Vnorm[0] );
+                                                                       if ( (k+1)%3 == axis ){
+                                                                               if ( nrm[ (k+2)%3 ] == 0 ) continue;
+                                                                               Vnorm[0][ (k+2)%3 ] = nrm[ (k+2)%3 ];
+                                                                       }
+                                                                       else{
+                                                                               if ( nrm[ (k+1)%3 ] == 0 ) continue;
+                                                                               Vnorm[0][ (k+1)%3 ] = nrm[ (k+1)%3 ];
+                                                                       }
+                                                                       CrossProduct( bestNormal, Vnorm[0], Enorm[0] );
+                                                                       CrossProduct( Enorm[0], nrm, reverse );
                                                                }
-                                                               else{    // z>=x, x>y
-                                                                       VectorSet( bestNormal, 0, 0, ( plane[2] >= 0 ? 1 : -1 ) );
+                                                               VectorNormalize( reverse, reverse );
+                                                               reverse[3] = DotProduct( points[ j ], reverse );
+                                                               //check facing, thickness
+                                                               currdist = reverse[3] - DotProduct( reverse, points[ (j+2)%3 ] );
+                                                               currangle = DotProduct( reverse, plane );
+                                                               if ( ( ( currdist > 0.1 ) && ( currdist < bestdist ) && ( currangle < 0 ) ) ||
+                                                                       ( ( currangle >= 0 ) && ( currangle <= bestangle ) ) ){
+                                                                       bestangle = currangle;
+                                                                       if ( currangle < 0 ) bestdist = currdist;
+                                                                       VectorCopy( reverse, p[j] );
+                                                                       p[j][3] = reverse[3];
+                                                               }
+                                                       }
+                                                       //if ( bestdist == 999999 && bestangle == 1 ) Sys_Printf("default_CLIPMODEL\n");
+                                                       if ( bestdist == 999999 && bestangle == 1 ) goto default_CLIPMODEL;
+                                                       if ( bestdist < mindist ) mindist = bestdist;
+                                               }
+                                               if ( (limDepth != 0.0) && (mindist > limDepth) ) goto default_CLIPMODEL;
+
+
+#if nonax_clip_dbg
+                                               for ( j = 0; j < 3; j++ )
+                                               {
+                                                       for ( k = 0; k < 3; k++ )
+                                                       {
+                                                               if ( fabs(p[j][k]) < 0.00025 && p[j][k] != 0.0 ){
+                                                                       Sys_Printf( "nonax nrm %6.17f %6.17f %6.17f\n", p[j][0], p[j][1], p[j][2] );
                                                                }
                                                        }
-                                                       else // y>=x
-                                                       if ( fabs( plane[1] ) > fabs( plane[2] ) ) { // y>z, y>=x
-                                                               VectorSet( bestNormal, 0, ( plane[1] >= 0 ? 1 : -1 ), 0 );
+                                               }
+#endif
+                                               /* set up brush sides */
+                                               buildBrush->numsides = 4;
+                                               buildBrush->sides[ 0 ].shaderInfo = si;
+                                               for ( j = 1; j < buildBrush->numsides; j++ ) {
+                                                       if ( 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
                                                        }
-                                                       else{    // z>=y, y>=x
+                                               }
+                                               VectorCopy( points[0], points[3] ); // for cyclic usage
+
+                                               buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
+                                               buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
+                                               buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
+                                               buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
+                                       }
+
+
+                                       else if ( ( spf == 16 ) ||      //EXTRUDE_TERRAIN
+                                               ( spf == 512 ) ||       //EXTRUDE_DOWNWARDS
+                                               ( spf == 1024 ) ||      //EXTRUDE_UPWARDS
+                                               ( spf == 4096 ) ||      //default CLIPMODEL + AXIAL_BACKPLANE
+                                               ( spf == 2064 ) ||      //EXTRUDE_TERRAIN+MAX_EXTRUDE
+                                               ( spf == 4112 ) ||      //EXTRUDE_TERRAIN+AXIAL_BACKPLANE
+                                               ( spf == 1536 ) ||      //EXTRUDE_DOWNWARDS+EXTRUDE_UPWARDS
+                                               ( spf == 2560 ) ||      //EXTRUDE_DOWNWARDS+MAX_EXTRUDE
+                                               ( spf == 4608 ) ||      //EXTRUDE_DOWNWARDS+AXIAL_BACKPLANE
+                                               ( spf == 3584 ) ||      //EXTRUDE_DOWNWARDS+EXTRUDE_UPWARDS+MAX_EXTRUDE
+                                               ( spf == 5632 ) ||      //EXTRUDE_DOWNWARDS+EXTRUDE_UPWARDS+AXIAL_BACKPLANE
+                                               ( spf == 3072 ) ||      //EXTRUDE_UPWARDS+MAX_EXTRUDE
+                                               ( spf == 5120 ) ){      //EXTRUDE_UPWARDS+AXIAL_BACKPLANE
+
+                                               if ( spawnFlags & 16 ){ //autodirection
+                                                       VectorCopy( avgDirection, bestNormal );
+                                               }
+                                               else{
+                                                       axis = 2;
+                                                       if ( ( spawnFlags & 1536 ) == 1536 ){ //up+down
                                                                VectorSet( bestNormal, 0, 0, ( plane[2] >= 0 ? 1 : -1 ) );
                                                        }
+                                                       else if ( spawnFlags & 512 ){ //down
+                                                               VectorSet( bestNormal, 0, 0, 1 );
+
+                                                       }
+                                                       else if ( spawnFlags & 1024 ){ //up
+                                                               VectorSet( bestNormal, 0, 0, -1 );
+                                                       }
+                                                       else{ // best axial normal
+                                                               VectorCopy( plane, bestNormal );
+                                                               for ( j = 0; j < 3; j++ ){
+                                                                       if ( fabs(bestNormal[j]) > fabs(bestNormal[(j+1)%3]) ){
+                                                                               bestNormal[(j+1)%3] = 0.0;
+                                                                               axis = j;
+                                                                       }
+                                                                       else {
+                                                                               bestNormal[j] = 0.0;
+                                                                       }
+                                                               }
+                                                               VectorNormalize( bestNormal, bestNormal );
+                                                       }
+                                               }
+
+                                               if ( DotProduct( plane, bestNormal ) < 0.05 ){
+                                                       goto default_CLIPMODEL;
+                                               }
+
+
+                                               /* make side planes */
+                                               for ( j = 0; j < 3; j++ )
+                                               {
+                                                       VectorSubtract( points[(j+1)%3], points[ j ], nrm );
+                                                       CrossProduct( bestNormal, nrm, p[ j ] );
+                                                       VectorNormalize( p[ j ], p[ j ] );
+                                                       p[j][3] = DotProduct( points[j], p[j] );
+                                               }
+
+                                               /* make back plane */
+                                               if ( spawnFlags & 2048 ){ //max extrude
+                                                       VectorScale( bestNormal, -1.0f, reverse );
+                                                       if ( bestNormal[axis] > 0 ){
+                                                               reverse[3] = -min[axis] + clipDepth;
+                                                       }
+                                                       else{
+                                                               reverse[3] = max[axis] + clipDepth;
+                                                       }
+                                               }
+                                               else if ( spawnFlags & 4096 ){ //axial backplane
+                                                       VectorScale( bestNormal, -1.0f, reverse );
+                                                       reverse[3] = points[0][axis];
+                                                       if ( bestNormal[axis] > 0 ){
+                                                               for ( j = 1; j < 3; j++ ){
+                                                                       if ( points[j][axis] < reverse[3] ){
+                                                                               reverse[3] = points[j][axis];
+                                                                       }
+                                                               }
+                                                               reverse[3] = -reverse[3] + clipDepth;
+                                                       }
+                                                       else{
+                                                               for ( j = 1; j < 3; j++ ){
+                                                                       if ( points[j][axis] > reverse[3] ){
+                                                                               reverse[3] = points[j][axis];
+                                                                       }
+                                                               }
+                                                               reverse[3] += clipDepth;
+                                                       }
+                                                       if (limDepth != 0.0){
+                                                               VectorCopy( points[0], cnt );
+                                                               if ( bestNormal[axis] > 0 ){
+                                                                       for ( j = 1; j < 3; j++ ){
+                                                                               if ( points[j][axis] > cnt[axis] ){
+                                                                                       VectorCopy( points[j], cnt );
+                                                                               }
+                                                                       }
+                                                               }
+                                                               else {
+                                                                       for ( j = 1; j < 3; j++ ){
+                                                                               if ( points[j][axis] < cnt[axis] ){
+                                                                                       VectorCopy( points[j], cnt );
+                                                                               }
+                                                                       }
+                                                               }
+                                                               VectorMA( cnt, reverse[3] - DotProduct( reverse, cnt ), reverse, cnt );
+                                                               if ( ( plane[3] - DotProduct( plane, cnt ) ) > limDepth ){
+                                                                       VectorScale( plane, -1.0f, reverse );
+                                                                       reverse[ 3 ] = -plane[ 3 ];
+                                                                       reverse[3] += clipDepth;
+                                                               }
+                                                       }
+                                               }
+                                               else{   //normal backplane
+                                                       VectorScale( plane, -1.0f, reverse );
+                                                       reverse[ 3 ] = -plane[ 3 ];
+                                                       reverse[3] += clipDepth;
+                                               }
+#if nonax_clip_dbg
+                                               for ( j = 0; j < 3; j++ )
+                                               {
+                                                       for ( k = 0; k < 3; k++ )
+                                                       {
+                                                               if ( fabs(p[j][k]) < 0.00025 && p[j][k] != 0.0 ){
+                                                                       Sys_Printf( "nonax nrm %6.17f %6.17f %6.17f\n", p[j][0], p[j][1], p[j][2] );
+                                                               }
+                                                       }
                                                }
+#endif
+                                               /* set up brush sides */
+                                               buildBrush->numsides = 5;
+                                               buildBrush->sides[ 0 ].shaderInfo = si;
+                                               for ( j = 1; j < buildBrush->numsides; j++ ) {
+                                                       if ( 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
+                                                       }
+                                               }
+                                               VectorCopy( points[0], points[3] ); // for cyclic usage
+
+                                               buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
+                                               buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
+                                               buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
+                                               buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
+                                               buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL );
                                        }
 
-                                       /* build a brush */
-                                       buildBrush = AllocBrush( 48 );
-                                       buildBrush->entityNum = mapEntityNum;
-                                       buildBrush->original = buildBrush;
-                                       buildBrush->contentShader = si;
-                                       buildBrush->compileFlags = si->compileFlags;
-                                       buildBrush->contentFlags = si->contentFlags;
-                                       normalEpsilon_save = normalEpsilon;
-                                       distanceEpsilon_save = distanceEpsilon;
-                                       if ( si->compileFlags & C_STRUCTURAL ) { // allow forced structural brushes here
-                                               buildBrush->detail = qfalse;
 
-                                               // only allow EXACT matches when snapping for these (this is mostly for caulk brushes inside a model)
-                                               if ( normalEpsilon > 0 ) {
-                                                       normalEpsilon = 0;
+                                       else if ( spf == 264 ){ //EXTRUDE_FACE_NORMALS+PYRAMIDAL_CLIP (extrude 45)
+
+                                               //45 degrees normals for side planes
+                                               for ( j = 0; j < 3; j++ )
+                                               {
+                                                       VectorSubtract( points[(j+1)%3], points[ j ], nrm );
+                                                       CrossProduct( plane, nrm, Enorm[ j ] );
+                                                       VectorNormalize( Enorm[ j ], Enorm[ j ] );
+                                                       VectorAdd( plane, Enorm[ j ], Enorm[ j ] );
+                                                       VectorNormalize( Enorm[ j ], Enorm[ j ] );
+                                                       /* make side planes */
+                                                       CrossProduct( Enorm[ j ], nrm, p[ j ] );
+                                                       VectorNormalize( p[ j ], p[ j ] );
+                                                       p[j][3] = DotProduct( points[j], p[j] );
+                                                       //snap nearly axial side planes
+                                                       snpd = qfalse;
+                                                       for ( k = 0; k < 3; k++ )
+                                                       {
+                                                               if ( fabs(p[j][k]) < 0.00025 && p[j][k] != 0.0 ){
+                                                                       p[j][k] = 0.0;
+                                                                       snpd = qtrue;
+                                                               }
+                                                       }
+                                                       if ( snpd ){
+                                                               VectorNormalize( p[j], p[j] );
+                                                               VectorAdd( points[j], points[(j+1)%3], cnt );
+                                                               VectorScale( cnt, 0.5f, cnt );
+                                                               p[j][3] = DotProduct( cnt, p[j] );
+                                                       }
                                                }
-                                               if ( distanceEpsilon > 0 ) {
-                                                       distanceEpsilon = 0;
+
+                                               /* make back plane */
+                                               VectorScale( plane, -1.0f, reverse );
+                                               reverse[ 3 ] = -plane[ 3 ];
+                                               reverse[3] += clipDepth;
+
+                                               /* set up brush sides */
+                                               buildBrush->numsides = 5;
+                                               buildBrush->sides[ 0 ].shaderInfo = si;
+                                               for ( j = 1; j < buildBrush->numsides; j++ ) {
+                                                       if ( 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
+                                                       }
                                                }
+                                               VectorCopy( points[0], points[3] ); // for cyclic usage
+
+                                               buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
+                                               buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
+                                               buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
+                                               buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
+                                               buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL );
                                        }
-                                       else{
-                                               buildBrush->detail = qtrue;
+
+
+                                       else if ( ( spf == 128 ) ||     //EXTRUDE_VERTEX_NORMALS
+                                               ( spf == 384 ) ){               //EXTRUDE_VERTEX_NORMALS + PYRAMIDAL_CLIP - vertex normals + don't check for sides, sticking outwards
+                                               /* get vertex normals */
+                                               for ( j = 0; j < 3; j++ )
+                                               {
+                                                       /* get vertex */
+                                                       dv = &ds->verts[ ds->indexes[ i + j ] ];
+                                                       /* copy normal */
+                                                       VectorCopy( dv->normal, Vnorm[ j ] );
+                                               }
+
+                                               //avg normals for side planes
+                                               for ( j = 0; j < 3; j++ )
+                                               {
+                                                       VectorAdd( Vnorm[ j ], Vnorm[ (j+1)%3 ], Enorm[ j ] );
+                                                       VectorNormalize( Enorm[ j ], Enorm[ j ] );
+                                                       //check fuer bad ones
+                                                       VectorSubtract( points[(j+1)%3], points[ j ], cnt );
+                                                       CrossProduct( plane, cnt, nrm );
+                                                       VectorNormalize( nrm, nrm );
+                                                       //check for negative or outside direction
+                                                       if ( DotProduct( Enorm[ j ], plane ) > 0.1 ){
+                                                               if ( ( DotProduct( Enorm[ j ], nrm ) > -0.2 ) || ( spawnFlags & 256 ) ){
+                                                                       //ok++;
+                                                                       continue;
+                                                               }
+                                                       }
+                                                       //notok++;
+                                                       //Sys_Printf( "faulty Enormal %i/%i\n", notok, ok );
+                                                       //use 45 normal
+                                                       VectorAdd( plane, nrm, Enorm[ j ] );
+                                                       VectorNormalize( Enorm[ j ], Enorm[ j ] );
+                                               }
+
+                                               /* make side planes */
+                                               for ( j = 0; j < 3; j++ )
+                                               {
+                                                       VectorSubtract( points[(j+1)%3], points[ j ], nrm );
+                                                       CrossProduct( Enorm[ j ], nrm, p[ j ] );
+                                                       VectorNormalize( p[ j ], p[ j ] );
+                                                       p[j][3] = DotProduct( points[j], p[j] );
+                                                       //snap nearly axial side planes
+                                                       snpd = qfalse;
+                                                       for ( k = 0; k < 3; k++ )
+                                                       {
+                                                               if ( fabs(p[j][k]) < 0.00025 && p[j][k] != 0.0 ){
+                                                                       //Sys_Printf( "init plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]);
+                                                                       p[j][k] = 0.0;
+                                                                       snpd = qtrue;
+                                                               }
+                                                       }
+                                                       if ( snpd ){
+                                                               VectorNormalize( p[j], p[j] );
+                                                               //Sys_Printf( "nrm plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]);
+                                                               VectorAdd( points[j], points[(j+1)%3], cnt );
+                                                               VectorScale( cnt, 0.5f, cnt );
+                                                               p[j][3] = DotProduct( cnt, p[j] );
+                                                               //Sys_Printf( "dst plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]);
+                                                       }
+                                               }
+
+                                               /* make back plane */
+                                               VectorScale( plane, -1.0f, reverse );
+                                               reverse[ 3 ] = -plane[ 3 ];
+                                               reverse[3] += clipDepth;
+
+                                               /* set up brush sides */
+                                               buildBrush->numsides = 5;
+                                               buildBrush->sides[ 0 ].shaderInfo = si;
+                                               for ( j = 1; j < buildBrush->numsides; j++ ) {
+                                                       if ( 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
+                                                       }
+                                               }
+                                               VectorCopy( points[0], points[3] ); // for cyclic usage
+
+                                               buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
+                                               buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
+                                               buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
+                                               buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
+                                               buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL );
                                        }
 
-                                       /* regenerate back points */
-                                       for ( j = 0; j < 3; j++ )
-                                       {
-                                               /* get vertex */
-                                               dv = &ds->verts[ ds->indexes[ i + j ] ];
 
-                                               // shift by some units
-                                               VectorMA( dv->xyz, -64.0f, bestNormal, backs[j] ); // 64 prevents roundoff errors a bit
+                                       else if ( spf == 8 ){   //EXTRUDE_FACE_NORMALS
+
+                                               /* make side planes */
+                                               for ( j = 0; j < 3; j++ )
+                                               {
+                                                       VectorSubtract( points[(j+1)%3], points[ j ], nrm );
+                                                       CrossProduct( plane, nrm, p[ j ] );
+                                                       VectorNormalize( p[ j ], p[ j ] );
+                                                       p[j][3] = DotProduct( points[j], p[j] );
+                                                       //snap nearly axial side planes
+                                                       snpd = qfalse;
+                                                       for ( k = 0; k < 3; k++ )
+                                                       {
+                                                               if ( fabs(p[j][k]) < 0.00025 && p[j][k] != 0.0 ){
+                                                                       //Sys_Printf( "init plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]);
+                                                                       p[j][k] = 0.0;
+                                                                       snpd = qtrue;
+                                                               }
+                                                       }
+                                                       if ( snpd ){
+                                                               VectorNormalize( p[j], p[j] );
+                                                               //Sys_Printf( "nrm plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]);
+                                                               VectorAdd( points[j], points[(j+1)%3], cnt );
+                                                               VectorScale( cnt, 0.5f, cnt );
+                                                               p[j][3] = DotProduct( cnt, p[j] );
+                                                               //Sys_Printf( "dst plane %6.8f %6.8f %6.8f %6.8f\n", p[j][0], p[j][1], p[j][2], p[j][3]);
+                                                       }
+                                               }
+
+                                               /* make back plane */
+                                               VectorScale( plane, -1.0f, reverse );
+                                               reverse[ 3 ] = -plane[ 3 ];
+                                               reverse[3] += clipDepth;
+#if nonax_clip_dbg
+                                               for ( j = 0; j < 3; j++ )
+                                               {
+                                                       for ( k = 0; k < 3; k++ )
+                                                       {
+                                                               if ( fabs(p[j][k]) < 0.00005 && p[j][k] != 0.0 ){
+                                                                       Sys_Printf( "nonax nrm %6.17f %6.17f %6.17f\n", p[j][0], p[j][1], p[j][2] );
+                                                                       Sys_Printf( "frm src nrm %6.17f %6.17f %6.17f\n", plane[0], plane[1], plane[2]);
+                                                               }
+                                                       }
+                                               }
+#endif
+                                               /* set up brush sides */
+                                               buildBrush->numsides = 5;
+                                               buildBrush->sides[ 0 ].shaderInfo = si;
+                                               for ( j = 1; j < buildBrush->numsides; j++ ) {
+                                                       if ( 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
+                                                       }
+                                               }
+                                               VectorCopy( points[0], points[3] ); // for cyclic usage
+
+                                               buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
+                                               buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
+                                               buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
+                                               buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
+                                               buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL );
                                        }
 
-                                       /* make back plane */
-                                       VectorScale( plane, -1.0f, reverse );
-                                       reverse[ 3 ] = -plane[ 3 ];
-                                       if ( ( spawnFlags & 24 ) != 24 ) {
-                                               reverse[3] += DotProduct( bestNormal, plane ) * backPlaneDistance;
+
+                                       else if ( spf == 256 ){ //PYRAMIDAL_CLIP
+
+                                               /* calculate center */
+                                               VectorAdd( points[ 0 ], points[ 1 ], cnt );
+                                               VectorAdd( cnt, points[ 2 ], cnt );
+                                               VectorScale( cnt, 0.3333333333333f, cnt );
+
+                                               /* make back pyramid point */
+                                               VectorMA( cnt, -clipDepth, plane, cnt );
+
+                                               /* make 3 more planes */
+                                               if( PlaneFromPoints( p[0], points[ 2 ], points[ 1 ], cnt ) &&
+                                                       PlaneFromPoints( p[1], points[ 1 ], points[ 0 ], cnt ) &&
+                                                       PlaneFromPoints( p[2], points[ 0 ], points[ 2 ], cnt ) ) {
+
+                                                       //check for dangerous planes
+                                                       while( (( p[0][0] != 0.0 || p[0][1] != 0.0 ) && fabs(p[0][0]) < 0.00025 && fabs(p[0][1]) < 0.00025) ||
+                                                               (( p[0][0] != 0.0 || p[0][2] != 0.0 ) && fabs(p[0][0]) < 0.00025 && fabs(p[0][2]) < 0.00025) ||
+                                                               (( p[0][2] != 0.0 || p[0][1] != 0.0 ) && fabs(p[0][2]) < 0.00025 && fabs(p[0][1]) < 0.00025) ||
+                                                               (( p[1][0] != 0.0 || p[1][1] != 0.0 ) && fabs(p[1][0]) < 0.00025 && fabs(p[1][1]) < 0.00025) ||
+                                                               (( p[1][0] != 0.0 || p[1][2] != 0.0 ) && fabs(p[1][0]) < 0.00025 && fabs(p[1][2]) < 0.00025) ||
+                                                               (( p[1][2] != 0.0 || p[1][1] != 0.0 ) && fabs(p[1][2]) < 0.00025 && fabs(p[1][1]) < 0.00025) ||
+                                                               (( p[2][0] != 0.0 || p[2][1] != 0.0 ) && fabs(p[2][0]) < 0.00025 && fabs(p[2][1]) < 0.00025) ||
+                                                               (( p[2][0] != 0.0 || p[2][2] != 0.0 ) && fabs(p[2][0]) < 0.00025 && fabs(p[2][2]) < 0.00025) ||
+                                                               (( p[2][2] != 0.0 || p[2][1] != 0.0 ) && fabs(p[2][2]) < 0.00025 && fabs(p[2][1]) < 0.00025) ) {
+                                                               VectorMA( cnt, -0.1f, plane, cnt );
+                                                               //      Sys_Printf( "shifting pyramid point\n" );
+                                                               PlaneFromPoints( p[0], points[ 2 ], points[ 1 ], cnt );
+                                                               PlaneFromPoints( p[1], points[ 1 ], points[ 0 ], cnt );
+                                                               PlaneFromPoints( p[2], points[ 0 ], points[ 2 ], cnt );
+                                                       }
+#if nonax_clip_dbg
+                                                       for ( j = 0; j < 3; j++ )
+                                                       {
+                                                               for ( k = 0; k < 3; k++ )
+                                                               {
+                                                                       if ( fabs(p[j][k]) < 0.00005 && p[j][k] != 0.0 ){
+                                                                               Sys_Printf( "nonax nrm %6.17f %6.17f %6.17f\n (%6.8f %6.8f %6.8f)\n (%6.8f %6.8f %6.8f)\n (%6.8f %6.8f %6.8f)\n", p[j][0], p[j][1], p[j][2], points[j][0], points[j][1], points[j][2], points[(j+1)%3][0], points[(j+1)%3][1], points[(j+1)%3][2], cnt[0], cnt[1], cnt[2] );
+                                                                       }
+                                                               }
+                                                       }
+#endif
+                                                       /* set up brush sides */
+                                                       buildBrush->numsides = 4;
+                                                       buildBrush->sides[ 0 ].shaderInfo = si;
+                                                       for ( j = 1; j < buildBrush->numsides; j++ ) {
+                                                               if ( 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
+                                                               }
+                                                       }
+                                                       VectorCopy( points[0], points[3] ); // for cyclic usage
+
+                                                       buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
+                                                       buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 1 ] ); // p[0] contains points[1] and points[2]
+                                                       buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 0 ] ); // p[1] contains points[0] and points[1]
+                                                       buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
+                                               }
+                                               else
+                                               {
+                                                       Sys_Printf( "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;
+                                               }
                                        }
-                                       // that's at least sqrt(1/3) backPlaneDistance, unless in DOWN mode; in DOWN mode, we are screwed anyway if we encounter a plane that's perpendicular to the xy plane)
 
-                                       if ( PlaneFromPoints( pa, points[ 2 ], points[ 1 ], backs[ 1 ] ) &&
-                                                PlaneFromPoints( pb, points[ 1 ], points[ 0 ], backs[ 0 ] ) &&
-                                                PlaneFromPoints( pc, points[ 0 ], points[ 2 ], backs[ 2 ] ) ) {
+
+                                       else if ( ( si->clipModel && !( spf ) ) || ( ( spawnFlags & 8090 ) == 2 ) ){    //default CLIPMODEL
+
+                                               default_CLIPMODEL:
+                                               // axial normal
+                                               VectorCopy( plane, bestNormal );
+                                               for ( j = 0; j < 3; j++ ){
+                                                       if ( fabs(bestNormal[j]) > fabs(bestNormal[(j+1)%3]) ){
+                                                               bestNormal[(j+1)%3] = 0.0;
+                                                       }
+                                                       else {
+                                                               bestNormal[j] = 0.0;
+                                                       }
+                                               }
+                                               VectorNormalize( bestNormal, bestNormal );
+
+                                               /* make side planes */
+                                               for ( j = 0; j < 3; j++ )
+                                               {
+                                                       VectorSubtract( points[(j+1)%3], points[ j ], nrm );
+                                                       CrossProduct( bestNormal, nrm, p[ j ] );
+                                                       VectorNormalize( p[ j ], p[ j ] );
+                                                       p[j][3] = DotProduct( points[j], p[j] );
+                                               }
+
+                                               /* make back plane */
+                                               VectorScale( plane, -1.0f, reverse );
+                                               reverse[ 3 ] = -plane[ 3 ];
+                                               reverse[3] += DotProduct( bestNormal, plane ) * clipDepth;
+#if nonax_clip_dbg
+                                               for ( j = 0; j < 3; j++ )
+                                               {
+                                                       for ( k = 0; k < 3; k++ )
+                                                       {
+                                                               if ( fabs(p[j][k]) < 0.00025 && p[j][k] != 0.0 ){
+                                                                       Sys_Printf( "nonax nrm %6.17f %6.17f %6.17f\n", p[j][0], p[j][1], p[j][2] );
+                                                               }
+                                                       }
+                                               }
+#endif
                                                /* set up brush sides */
                                                buildBrush->numsides = 5;
                                                buildBrush->sides[ 0 ].shaderInfo = si;
@@ -659,21 +1295,15 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
                                                                buildBrush->sides[ j ].shaderInfo = NULL;  // don't emit these faces as draw surfaces, should make smaller BSPs; hope this works
                                                        }
                                                }
+                                               VectorCopy( points[0], points[3] ); // for cyclic usage
 
                                                buildBrush->sides[ 0 ].planenum = FindFloatPlane( plane, plane[ 3 ], 3, points );
-                                               buildBrush->sides[ 1 ].planenum = FindFloatPlane( pa, pa[ 3 ], 2, &points[ 1 ] ); // pa contains points[1] and points[2]
-                                               buildBrush->sides[ 2 ].planenum = FindFloatPlane( pb, pb[ 3 ], 2, &points[ 0 ] ); // pb contains points[0] and points[1]
-                                               buildBrush->sides[ 3 ].planenum = FindFloatPlane( pc, pc[ 3 ], 2, &points[ 2 ] ); // pc contains points[2] and points[0] (copied to points[3]
-                                               buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 3, backs );
-                                       }
-                                       else
-                                       {
-                                               free( buildBrush );
-                                               continue;
+                                               buildBrush->sides[ 1 ].planenum = FindFloatPlane( p[0], p[0][ 3 ], 2, &points[ 0 ] ); // p[0] contains points[0] and points[1]
+                                               buildBrush->sides[ 2 ].planenum = FindFloatPlane( p[1], p[1][ 3 ], 2, &points[ 1 ] ); // p[1] contains points[1] and points[2]
+                                               buildBrush->sides[ 3 ].planenum = FindFloatPlane( p[2], p[2][ 3 ], 2, &points[ 2 ] ); // p[2] contains points[2] and points[0] (copied to points[3]
+                                               buildBrush->sides[ 4 ].planenum = FindFloatPlane( reverse, reverse[ 3 ], 0, NULL );
                                        }
 
-                                       normalEpsilon = normalEpsilon_save;
-                                       distanceEpsilon = distanceEpsilon_save;
 
                                        /* add to entity */
                                        if ( CreateBrushWindings( buildBrush ) ) {
@@ -684,10 +1314,15 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
                                                entities[ mapEntityNum ].numBrushes++;
                                        }
                                        else{
+                                               Sys_Printf( "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 );
                                        }
                                }
                        }
+                       normalEpsilon = normalEpsilon_save;
+               }
+               else if ( spawnFlags & 8090 ){
+                       Sys_Printf( "WARNING: nonexistent clipping mode selected\n" );
                }
        }
 }
@@ -706,7 +1341,7 @@ void AddTriangleModels( entity_t *e ){
        const char      *target, *model, *value;
        char shader[ MAX_QPATH ];
        shaderInfo_t    *celShader;
-       float temp, baseLightmapScale, lightmapScale;
+       float temp, baseLightmapScale, lightmapScale, clipDepth;
        float shadeAngle;
        int lightmapSampleSize;
        vec3_t origin, scale, angles;
@@ -719,7 +1354,6 @@ void AddTriangleModels( entity_t *e ){
        /* note it */
        Sys_FPrintf( SYS_VRB, "--- AddTriangleModels ---\n" );
 
-       doingModelClip = qtrue;
 
        /* get current brush entity targetname */
        if ( e == entities ) {
@@ -957,8 +1591,15 @@ void AddTriangleModels( entity_t *e ){
                        skin = IntForKey( e2, "skin" );
                }
 
+               clipDepth = clipDepthGlobal;
+               if ( strcmp( "", ValueForKey( e2, "_clipdepth" ) ) ) {
+                       clipDepth = FloatForKey( e2, "_clipdepth" );
+                       Sys_Printf( "misc_model has autoclip depth of %.3f\n", clipDepth );
+               }
+
+
                /* insert the model */
-               InsertModel( model, skin, frame, transform, remap, celShader, mapEntityNum, castShadows, recvShadows, spawnFlags, lightmapScale, lightmapSampleSize, shadeAngle );
+               InsertModel( model, skin, frame, transform, remap, celShader, mapEntityNum, castShadows, recvShadows, spawnFlags, lightmapScale, lightmapSampleSize, shadeAngle, clipDepth );
 
                /* free shader remappings */
                while ( remap != NULL )
@@ -969,5 +1610,4 @@ void AddTriangleModels( entity_t *e ){
                }
        }
 
-       doingModelClip = qfalse;
 }
index 509cb9270ec810ab8a91cda1ce01e665a180d806..a26aa71696dad29860a6fe42174d4ddd35c75f88 100644 (file)
@@ -1715,7 +1715,7 @@ void                        PicoPrintFunc( int level, const char *str );
 void                        PicoLoadFileFunc( const char *name, byte **buffer, int *bufSize );
 picoModel_t                 *FindModel( const char *name, int frame );
 picoModel_t                 *LoadModel( const char *name, int frame );
-void                        InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap_t *remap, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle );
+void                        InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap_t *remap, shaderInfo_t *celShader, int eNum, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth );
 void                        AddTriangleModels( entity_t *e );
 
 
@@ -2058,8 +2058,6 @@ Q_EXTERN float jitters[ MAX_JITTERS ];
 
 /*can't code*/
 Q_EXTERN qboolean doingBSP Q_ASSIGN( qfalse );
-Q_EXTERN qboolean doingModelClip Q_ASSIGN( qfalse );
-Q_EXTERN qboolean snapModelClip Q_ASSIGN( qfalse );
 
 /* commandline arguments */
 Q_EXTERN qboolean nocmdline Q_ASSIGN( qfalse );
@@ -2101,6 +2099,7 @@ Q_EXTERN qboolean debugSurfaces Q_ASSIGN( qfalse );
 Q_EXTERN qboolean debugInset Q_ASSIGN( qfalse );
 Q_EXTERN qboolean debugPortals Q_ASSIGN( qfalse );
 Q_EXTERN qboolean debugClip Q_ASSIGN( qfalse );                        /* debug model autoclipping */
+Q_EXTERN float clipDepthGlobal Q_ASSIGN( 2.0f );
 Q_EXTERN qboolean lightmapTriangleCheck Q_ASSIGN( qfalse );
 Q_EXTERN qboolean lightmapExtraVisClusterNudge Q_ASSIGN( qfalse );
 Q_EXTERN qboolean lightmapFill Q_ASSIGN( qfalse );
index 5324ec2dfa6ca99f2360424c43f01bca16e63930..1f2fa613838d9ed18502723fa7355a39707940b4 100644 (file)
@@ -3287,7 +3287,7 @@ int AddSurfaceModelsToTriangle_r( mapDrawSurface_t *ds, surfaceModel_t *model, b
                        }
 
                        /* insert the model */
-                       InsertModel( (char *) model->model, 0, 0, transform, NULL, ds->celShader, ds->entityNum, ds->castShadows, ds->recvShadows, 0, ds->lightmapScale, 0, 0 );
+                       InsertModel( (char *) model->model, 0, 0, transform, NULL, ds->celShader, ds->entityNum, ds->castShadows, ds->recvShadows, 0, ds->lightmapScale, 0, 0, clipDepthGlobal );
 
                        /* return to sender */
                        return 1;
index da8e71f7b3454c4c7d59223711706edb535c7c51..263e03bfe19e5cb5741428f40866bc8f1b537b7d 100644 (file)
@@ -281,7 +281,7 @@ void Foliage( mapDrawSurface_t *src ){
                m4x4_scale_for_vec3( transform, scale );
 
                /* add the model to the bsp */
-               InsertModel( foliage->model, 0, 0, transform, NULL, NULL, src->entityNum, src->castShadows, src->recvShadows, 0, src->lightmapScale, 0, 0 );
+               InsertModel( foliage->model, 0, 0, transform, NULL, NULL, src->entityNum, src->castShadows, src->recvShadows, 0, src->lightmapScale, 0, 0, clipDepthGlobal );
 
                /* walk each new surface */
                for ( i = oldNumMapDrawSurfs; i < numMapDrawSurfs; i++ )