]> de.git.xonotic.org Git - xonotic/netradiant.git/commitdiff
Merge remote-tracking branch 'origin/divVerent/weird-shift-a'
authorRudolf Polzer <divverent@alientrap.org>
Mon, 14 Feb 2011 18:42:28 +0000 (19:42 +0100)
committerRudolf Polzer <divverent@alientrap.org>
Mon, 14 Feb 2011 18:42:28 +0000 (19:42 +0100)
62 files changed:
Makefile
docs/index.html
libs/mathlib.h
libs/mathlib/mathlib.c
radiant/console.cpp
radiant/main.cpp
radiant/map.cpp
radiant/xywindow.cpp
regression_tests/q3map2/base_winding/README.txt [new file with mode: 0644]
regression_tests/q3map2/base_winding/base_winding_logging.patch [new file with mode: 0644]
regression_tests/q3map2/base_winding/maps/base_winding.map [new file with mode: 0644]
regression_tests/q3map2/coarse_snap_normal/README.txt [new file with mode: 0644]
regression_tests/q3map2/coarse_snap_normal/maps/coarse_snap_normal.map [new file with mode: 0644]
regression_tests/q3map2/decal_misalignment/README.txt [new file with mode: 0644]
regression_tests/q3map2/decal_misalignment/maps/decal_misalignment.map [new file with mode: 0644]
regression_tests/q3map2/decal_misalignment/scripts/radiant_regression_tests.shader [new file with mode: 0644]
regression_tests/q3map2/degenerate_winding/README.txt [new file with mode: 0644]
regression_tests/q3map2/degenerate_winding/maps/degenerate_winding.map [new file with mode: 0644]
regression_tests/q3map2/degenerate_winding2/README.txt [new file with mode: 0644]
regression_tests/q3map2/degenerate_winding2/maps/degenerate_winding2.map [new file with mode: 0644]
regression_tests/q3map2/degenerate_winding3/README.txt [new file with mode: 0644]
regression_tests/q3map2/degenerate_winding3/maps/degenerate_winding3.map [new file with mode: 0644]
regression_tests/q3map2/disappearing_sliver/README.txt [new file with mode: 0644]
regression_tests/q3map2/disappearing_sliver/maps/disappearing_sliver.map [new file with mode: 0644]
regression_tests/q3map2/disappearing_sliver/winding_logging.patch [new file with mode: 0644]
regression_tests/q3map2/disappearing_sliver2/README.txt [new file with mode: 0644]
regression_tests/q3map2/disappearing_sliver2/maps/disappearing_sliver2.map [new file with mode: 0644]
regression_tests/q3map2/disappearing_sliver3/NOTES.txt [new file with mode: 0644]
regression_tests/q3map2/disappearing_sliver3/README.txt [new file with mode: 0644]
regression_tests/q3map2/disappearing_sliver3/maps/disappearing_sliver3.map [new file with mode: 0644]
regression_tests/q3map2/duplicate_plane/README.txt [new file with mode: 0644]
regression_tests/q3map2/duplicate_plane/maps/duplicate_plane.map [new file with mode: 0644]
regression_tests/q3map2/model_clipping_45_degrees/README.txt [new file with mode: 0644]
regression_tests/q3map2/model_clipping_45_degrees/maps/model_clipping_45_degrees.map [new file with mode: 0644]
regression_tests/q3map2/model_clipping_45_degrees/models/mapobjects/wedges/wedge_45.ase [new file with mode: 0644]
regression_tests/q3map2/model_clipping_45_degrees/models/mapobjects/wedges/wedge_shallow.ase [new file with mode: 0644]
regression_tests/q3map2/model_clipping_45_degrees/models/mapobjects/wedges/wedge_steep.ase [new file with mode: 0644]
regression_tests/q3map2/model_clipping_45_degrees/scripts/radiant_regression_tests.shader [new file with mode: 0644]
regression_tests/q3map2/piercing_triangle/README.txt [new file with mode: 0644]
regression_tests/q3map2/piercing_triangle/maps/piercing_triangle.map [new file with mode: 0644]
regression_tests/q3map2/plane_aliasing/README.txt [new file with mode: 0644]
regression_tests/q3map2/plane_aliasing/maps/plane_aliasing.map [new file with mode: 0644]
regression_tests/q3map2/segmentation_fault/README.txt [new file with mode: 0644]
regression_tests/q3map2/segmentation_fault/maps/segmentation_fault.map [new file with mode: 0644]
regression_tests/q3map2/snap_plane/README.txt [new file with mode: 0644]
regression_tests/q3map2/snap_plane/maps/snap_plane.map [new file with mode: 0644]
regression_tests/q3map2/sparkly_seam/README.txt [new file with mode: 0644]
regression_tests/q3map2/sparkly_seam/maps/sparkly_seam.map [new file with mode: 0644]
tools/quake3/common/polylib.c
tools/quake3/common/polylib.h
tools/quake3/q3map2/brush.c
tools/quake3/q3map2/convert_ase.c
tools/quake3/q3map2/convert_obj.c [new file with mode: 0644]
tools/quake3/q3map2/game_etut.h
tools/quake3/q3map2/game_reaction.h [new file with mode: 0644]
tools/quake3/q3map2/light.c
tools/quake3/q3map2/main.c
tools/quake3/q3map2/map.c
tools/quake3/q3map2/model.c
tools/quake3/q3map2/path_init.c
tools/quake3/q3map2/portals.c
tools/quake3/q3map2/q3map2.h

index cd0c002ac944c4e276afe1bb6ee99232bc7ffd1e..b0a1d4a27f13939635580c63a1b06c4ba21f821f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -343,7 +343,17 @@ endif
 
 .PHONY: binaries
 binaries: \
-       $(INSTALLDIR)/heretic2/h2data.$(EXE) \
+       binaries-tools \
+       binaries-radiant \
+
+.PHONY: binaries-radiant-all
+binaries-radiant: \
+       binaries-radiant-modules \
+       binaries-radiant-plugins \
+       binaries-radiant-core \
+
+.PHONY: binaries-radiant-modules
+binaries-radiant-modules: \
        $(INSTALLDIR)/modules/archivepak.$(DLL) \
        $(INSTALLDIR)/modules/archivewad.$(DLL) \
        $(INSTALLDIR)/modules/archivezip.$(DLL) \
@@ -358,17 +368,56 @@ binaries: \
        $(INSTALLDIR)/modules/model.$(DLL) \
        $(INSTALLDIR)/modules/shaders.$(DLL) \
        $(INSTALLDIR)/modules/vfspk3.$(DLL) \
+
+.PHONY: binaries-radiant-plugins
+binaries-radiant-plugins: \
        $(INSTALLDIR)/plugins/bobtoolz.$(DLL) \
        $(INSTALLDIR)/plugins/brushexport.$(DLL) \
        $(INSTALLDIR)/plugins/prtview.$(DLL) \
        $(INSTALLDIR)/plugins/shaderplug.$(DLL) \
        $(INSTALLDIR)/plugins/sunplug.$(DLL) \
        $(INSTALLDIR)/plugins/ufoaiplug.$(DLL) \
+
+.PHONY: binaries-radiant
+binaries-radiant-core: \
+       $(INSTALLDIR)/radiant.$(EXE) \
+
+.PHONY: binaries-tools
+binaries-tools: \
+       binaries-tools-quake2 \
+       binaries-tools-quake3 \
+
+.PHONY: binaries-tools-quake2
+binaries-tools-quake2: \
+       binaries-q2map \
+       binaries-qdata3 \
+       binaries-h2data \
+
+.PHONY: binaries-q2map
+binaries-q2map: \
        $(INSTALLDIR)/q2map.$(EXE) \
+
+.PHONY: binaries-qdata3
+binaries-qdata3: \
+       $(INSTALLDIR)/qdata3.$(EXE) \
+
+.PHONY: binaries-h2data
+binaries-h2data: \
+       $(INSTALLDIR)/heretic2/h2data.$(EXE)
+
+.PHONY: binaries-tools-quake3
+binaries-tools-quake3: \
+       binaries-q3data \
+       binaries-q3map2 \
+
+.PHONY: binaries-q3data
+binaries-q3data: \
        $(INSTALLDIR)/q3data.$(EXE) \
+
+.PHONY: binaries-q3map2
+binaries-q3map2: \
        $(INSTALLDIR)/q3map2.$(EXE) \
-       $(INSTALLDIR)/qdata3.$(EXE) \
-       $(INSTALLDIR)/radiant.$(EXE) \
+
 
 .PHONY: clean
 clean:
@@ -425,6 +474,7 @@ $(INSTALLDIR)/q3map2.$(EXE): \
        tools/quake3/q3map2/bspfile_rbsp.o \
        tools/quake3/q3map2/bsp.o \
        tools/quake3/q3map2/convert_ase.o \
+       tools/quake3/q3map2/convert_obj.o \
        tools/quake3/q3map2/convert_map.o \
        tools/quake3/q3map2/decals.o \
        tools/quake3/q3map2/facebsp.o \
index 45a168ecec5e0c30458f7d8c1bb9c0c0482e7308..68811708f1101fb3ab436ebd50eebd988f263885 100644 (file)
@@ -11,6 +11,6 @@
   </style>
 </head>
 <body>
-<p class="p1">put here links</p>
+<p class="p1"><a href="http://dev.xonotic.org/projects/xonotic/wiki/Mapping">Xonotic Mapping Wiki</A></p>
 </body>
 </html>
index d206d3306ea8fb65654714981f7008cdad244458..382933d7afce201d4aa125ef183b061353eb893e 100644 (file)
@@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 // mathlib.h
 #include <math.h>
+#include <float.h>
 
 #ifdef __cplusplus
 
@@ -40,6 +41,12 @@ typedef vec_t vec3_t[3];
 typedef vec_t vec5_t[5];
 typedef vec_t vec4_t[4];
 
+// Smallest positive value for vec_t such that 1.0 + VEC_SMALLEST_EPSILON_AROUND_ONE != 1.0.
+// In the case of 32 bit floats (which is almost certainly the case), it's 0.00000011921.
+// Don't forget that your epsilons should depend on the possible range of values,
+// because for example adding VEC_SMALLEST_EPSILON_AROUND_ONE to 1024.0 will have no effect.
+#define VEC_SMALLEST_EPSILON_AROUND_ONE FLT_EPSILON
+
 #define        SIDE_FRONT              0
 #define        SIDE_ON                 2
 #define        SIDE_BACK               1
@@ -83,11 +90,17 @@ extern const vec3_t g_vec3_axis_z;
 
 qboolean VectorCompare (const vec3_t v1, const vec3_t v2);
 
+qboolean VectorIsOnAxis(vec3_t v);
+qboolean VectorIsOnAxialPlane(vec3_t v);
+
 vec_t VectorLength(const vec3_t v);
 
 void VectorMA( const vec3_t va, vec_t scale, const vec3_t vb, vec3_t vc );
 
 void _CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross);
+// I need this define in order to test some of the regression tests from time to time.
+// This define affect the precision of VectorNormalize() function only.
+#define MATHLIB_VECTOR_NORMALIZE_PRECISION_FIX 1
 vec_t VectorNormalize (const vec3_t in, vec3_t out);
 vec_t ColorNormalize( const vec3_t in, vec3_t out );
 void VectorInverse (vec3_t v);
@@ -419,6 +432,50 @@ vec_t ray_intersect_plane(const ray_t* ray, const vec3_t normal, vec_t dist);
 int plane_intersect_planes(const vec4_t plane1, const vec4_t plane2, const vec4_t plane3, vec3_t intersection);
 
 
+
+////////////////////////////////////////////////////////////////////////////////
+// Below is double-precision math stuff.  This was initially needed by the new
+// "base winding" code in q3map2 brush processing in order to fix the famous
+// "disappearing triangles" issue.  These definitions can be used wherever extra
+// precision is needed.
+////////////////////////////////////////////////////////////////////////////////
+
+typedef double vec_accu_t;
+typedef vec_accu_t vec3_accu_t[3];
+
+// Smallest positive value for vec_accu_t such that 1.0 + VEC_ACCU_SMALLEST_EPSILON_AROUND_ONE != 1.0.
+// In the case of 64 bit doubles (which is almost certainly the case), it's 0.00000000000000022204.
+// Don't forget that your epsilons should depend on the possible range of values,
+// because for example adding VEC_ACCU_SMALLEST_EPSILON_AROUND_ONE to 1024.0 will have no effect.
+#define VEC_ACCU_SMALLEST_EPSILON_AROUND_ONE DBL_EPSILON
+
+vec_accu_t VectorLengthAccu(const vec3_accu_t v);
+
+// I have a feeling it may be safer to break these #define functions out into actual functions
+// in order to avoid accidental loss of precision.  For example, say you call
+// VectorScaleAccu(vec3_t, vec_t, vec3_accu_t).  The scale would take place in 32 bit land
+// and the result would be cast to 64 bit, which would cause total loss of precision when
+// scaling by a large factor.
+//#define DotProductAccu(x, y) ((x)[0] * (y)[0] + (x)[1] * (y)[1] + (x)[2] * (y)[2])
+//#define VectorSubtractAccu(a, b, c) ((c)[0] = (a)[0] - (b)[0], (c)[1] = (a)[1] - (b)[1], (c)[2] = (a)[2] - (b)[2])
+//#define VectorAddAccu(a, b, c) ((c)[0] = (a)[0] + (b)[0], (c)[1] = (a)[1] + (b)[1], (c)[2] = (a)[2] + (b)[2])
+//#define VectorCopyAccu(a, b) ((b)[0] = (a)[0], (b)[1] = (a)[1], (b)[2] = (a)[2])
+//#define VectorScaleAccu(a, b, c) ((c)[0] = (b) * (a)[0], (c)[1] = (b) * (a)[1], (c)[2] = (b) * (a)[2])
+//#define CrossProductAccu(a, b, c) ((c)[0] = (a)[1] * (b)[2] - (a)[2] * (b)[1], (c)[1] = (a)[2] * (b)[0] - (a)[0] * (b)[2], (c)[2] = (a)[0] * (b)[1] - (a)[1] * (b)[0])
+//#define Q_rintAccu(in) ((vec_accu_t) floor(in + 0.5))
+
+vec_accu_t DotProductAccu(const vec3_accu_t a, const vec3_accu_t b);
+void VectorSubtractAccu(const vec3_accu_t a, const vec3_accu_t b, vec3_accu_t out);
+void VectorAddAccu(const vec3_accu_t a, const vec3_accu_t b, vec3_accu_t out);
+void VectorCopyAccu(const vec3_accu_t in, vec3_accu_t out);
+void VectorScaleAccu(const vec3_accu_t in, vec_accu_t scaleFactor, vec3_accu_t out);
+void CrossProductAccu(const vec3_accu_t a, const vec3_accu_t b, vec3_accu_t out);
+vec_accu_t Q_rintAccu(vec_accu_t val);
+
+void VectorCopyAccuToRegular(const vec3_accu_t in, vec3_t out);
+void VectorCopyRegularToAccu(const vec3_t in, vec3_accu_t out);
+vec_accu_t VectorNormalizeAccu(const vec3_accu_t in, vec3_accu_t out);
+
 #ifdef __cplusplus
 }
 #endif
index c549cb101896144354968170ca690120b8672c09..98fb972a28aa9aa5eedf4fa2542fdbc0d3eadec4 100644 (file)
@@ -30,6 +30,54 @@ const vec3_t g_vec3_axis_x = { 1, 0, 0, };
 const vec3_t g_vec3_axis_y = { 0, 1, 0, };
 const vec3_t g_vec3_axis_z = { 0, 0, 1, };
 
+/*
+================
+VectorIsOnAxis
+================
+*/
+qboolean VectorIsOnAxis(vec3_t v)
+{
+       int     i, zeroComponentCount;
+
+       zeroComponentCount = 0;
+       for (i = 0; i < 3; i++)
+       {
+               if (v[i] == 0.0)
+               {
+                       zeroComponentCount++;
+               }
+       }
+
+       if (zeroComponentCount > 1)
+       {
+               // The zero vector will be on axis.
+               return qtrue;
+       }
+
+       return qfalse;
+}
+
+/*
+================
+VectorIsOnAxialPlane
+================
+*/
+qboolean VectorIsOnAxialPlane(vec3_t v)
+{
+       int     i;
+
+       for (i = 0; i < 3; i++)
+       {
+               if (v[i] == 0.0)
+               {
+                       // The zero vector will be on axial plane.
+                       return qtrue;
+               }
+       }
+
+       return qfalse;
+}
+
 /*
 ================
 MakeNormalVectors
@@ -119,6 +167,35 @@ void _VectorCopy (vec3_t in, vec3_t out)
 }
 
 vec_t VectorNormalize( const vec3_t in, vec3_t out ) {
+
+#if MATHLIB_VECTOR_NORMALIZE_PRECISION_FIX
+
+       // The sqrt() function takes double as an input and returns double as an
+       // output according the the man pages on Debian and on FreeBSD.  Therefore,
+       // I don't see a reason why using a double outright (instead of using the
+       // vec_accu_t alias for example) could possibly be frowned upon.
+
+       double  x, y, z, length;
+
+       x = (double) in[0];
+       y = (double) in[1];
+       z = (double) in[2];
+
+       length = sqrt((x * x) + (y * y) + (z * z));
+       if (length == 0)
+       {
+               VectorClear (out);
+               return 0;
+       }
+
+       out[0] = (vec_t) (x / length);
+       out[1] = (vec_t) (y / length);
+       out[2] = (vec_t) (z / length);
+
+       return (vec_t) length;
+
+#else
+
        vec_t   length, ilength;
 
        length = (vec_t)sqrt (in[0]*in[0] + in[1]*in[1] + in[2]*in[2]);
@@ -134,6 +211,9 @@ vec_t VectorNormalize( const vec3_t in, vec3_t out ) {
        out[2] = in[2]*ilength;
 
        return length;
+
+#endif
+
 }
 
 vec_t ColorNormalize( const vec3_t in, vec3_t out ) {
@@ -584,3 +664,155 @@ void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point,
                dst[i] = rot[i][0] * point[0] + rot[i][1] * point[1] + rot[i][2] * point[2];
        }
 }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Below is double-precision math stuff.  This was initially needed by the new
+// "base winding" code in q3map2 brush processing in order to fix the famous
+// "disappearing triangles" issue.  These definitions can be used wherever extra
+// precision is needed.
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+=================
+VectorLengthAccu
+=================
+*/
+vec_accu_t VectorLengthAccu(const vec3_accu_t v)
+{
+       return (vec_accu_t) sqrt((v[0] * v[0]) + (v[1] * v[1]) + (v[2] * v[2]));
+}
+
+/*
+=================
+DotProductAccu
+=================
+*/
+vec_accu_t DotProductAccu(const vec3_accu_t a, const vec3_accu_t b)
+{
+       return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]);
+}
+
+/*
+=================
+VectorSubtractAccu
+=================
+*/
+void VectorSubtractAccu(const vec3_accu_t a, const vec3_accu_t b, vec3_accu_t out)
+{
+       out[0] = a[0] - b[0];
+       out[1] = a[1] - b[1];
+       out[2] = a[2] - b[2];
+}
+
+/*
+=================
+VectorAddAccu
+=================
+*/
+void VectorAddAccu(const vec3_accu_t a, const vec3_accu_t b, vec3_accu_t out)
+{
+       out[0] = a[0] + b[0];
+       out[1] = a[1] + b[1];
+       out[2] = a[2] + b[2];
+}
+
+/*
+=================
+VectorCopyAccu
+=================
+*/
+void VectorCopyAccu(const vec3_accu_t in, vec3_accu_t out)
+{
+       out[0] = in[0];
+       out[1] = in[1];
+       out[2] = in[2];
+}
+
+/*
+=================
+VectorScaleAccu
+=================
+*/
+void VectorScaleAccu(const vec3_accu_t in, vec_accu_t scaleFactor, vec3_accu_t out)
+{
+       out[0] = in[0] * scaleFactor;
+       out[1] = in[1] * scaleFactor;
+       out[2] = in[2] * scaleFactor;
+}
+
+/*
+=================
+CrossProductAccu
+=================
+*/
+void CrossProductAccu(const vec3_accu_t a, const vec3_accu_t b, vec3_accu_t out)
+{
+       out[0] = (a[1] * b[2]) - (a[2] * b[1]);
+       out[1] = (a[2] * b[0]) - (a[0] * b[2]);
+       out[2] = (a[0] * b[1]) - (a[1] * b[0]);
+}
+
+/*
+=================
+Q_rintAccu
+=================
+*/
+vec_accu_t Q_rintAccu(vec_accu_t val)
+{
+       return (vec_accu_t) floor(val + 0.5);
+}
+
+/*
+=================
+VectorCopyAccuToRegular
+=================
+*/
+void VectorCopyAccuToRegular(const vec3_accu_t in, vec3_t out)
+{
+       out[0] = (vec_t) in[0];
+       out[1] = (vec_t) in[1];
+       out[2] = (vec_t) in[2];
+}
+
+/*
+=================
+VectorCopyRegularToAccu
+=================
+*/
+void VectorCopyRegularToAccu(const vec3_t in, vec3_accu_t out)
+{
+       out[0] = (vec_accu_t) in[0];
+       out[1] = (vec_accu_t) in[1];
+       out[2] = (vec_accu_t) in[2];
+}
+
+/*
+=================
+VectorNormalizeAccu
+=================
+*/
+vec_accu_t VectorNormalizeAccu(const vec3_accu_t in, vec3_accu_t out)
+{
+       // The sqrt() function takes double as an input and returns double as an
+       // output according the the man pages on Debian and on FreeBSD.  Therefore,
+       // I don't see a reason why using a double outright (instead of using the
+       // vec_accu_t alias for example) could possibly be frowned upon.
+
+       vec_accu_t      length;
+
+       length = (vec_accu_t) sqrt((in[0] * in[0]) + (in[1] * in[1]) + (in[2] * in[2]));
+       if (length == 0)
+       {
+               VectorClear(out);
+               return 0;
+       }
+
+       out[0] = in[0] / length;
+       out[1] = in[1] / length;
+       out[2] = in[2] / length;
+
+       return length;
+}
+
+
index db7997e18be53d14319a47664486f41a0fa9a650..cff963f21b5c778f0f5acbaf28e2e039540c46d1 100644 (file)
@@ -189,11 +189,10 @@ std::size_t Sys_Print(int level, const char* buf, std::size_t length)
 
       const GdkColor yellow = { 0, 0xb0ff, 0xb0ff, 0x0000 };
       const GdkColor red = { 0, 0xffff, 0x0000, 0x0000 };
-      const GdkColor black = { 0, 0x0000, 0x0000, 0x0000 };
 
       static GtkTextTag* error_tag = gtk_text_buffer_create_tag (buffer, "red_foreground", "foreground-gdk", &red, 0);
       static GtkTextTag* warning_tag = gtk_text_buffer_create_tag (buffer, "yellow_foreground", "foreground-gdk", &yellow, 0);
-      static GtkTextTag* standard_tag = gtk_text_buffer_create_tag (buffer, "black_foreground", "foreground-gdk", &black, 0);
+      static GtkTextTag* standard_tag = gtk_text_buffer_create_tag (buffer, "black_foreground", 0);
       GtkTextTag* tag;
       switch (level)
       {
index 15baa3c048323a3fbee78992a77bb543d96138d1..a7c224266ab10592d9fd4d5407f3dff82046808c 100644 (file)
@@ -567,9 +567,9 @@ int main (int argc, char* argv[])
   lib = LoadLibrary("dwmapi.dll");
   if(lib != 0)
   {
-         void (WINAPI *DwmEnableComposition) (bool bEnable) = (void (WINAPI *) (bool bEnable)) GetProcAddress(lib, "DwmEnableComposition");
-         if(DwmEnableComposition)
-                 DwmEnableComposition(FALSE);
+         void (WINAPI *qDwmEnableComposition) (bool bEnable) = (void (WINAPI *) (bool bEnable)) GetProcAddress(lib, "DwmEnableComposition");
+         if(qDwmEnableComposition)
+                 qDwmEnableComposition(FALSE);
          FreeLibrary(lib);
   }
 #endif
index 7b8c570de4d5f54610ee5cfa7d6a24c9e6203fc5..572459907e56867d1e820a877da5c78dc226f7eb 100644 (file)
@@ -1643,6 +1643,13 @@ bool Map_ImportFile(const char* filename)
     goto tryDecompile;
 
   {
+    const MapFormat* format = NULL;
+    const char* moduleName = findModuleName(&GlobalFiletypes(), MapFormat::Name(), path_get_extension(filename));
+    if(string_not_empty(moduleName))
+      format = ReferenceAPI_getMapModules().findModule(moduleName);
+
+    if(format)
+      format->wrongFormat = false;
     Resource* resource = GlobalReferenceCache().capture(filename);
     resource->refresh(); // avoid loading old version if map has changed on disk since last import
     if(!resource->load())
@@ -1650,6 +1657,12 @@ bool Map_ImportFile(const char* filename)
       GlobalReferenceCache().release(filename);
       goto tryDecompile;
     }
+    if(format)
+      if(format->wrongFormat)
+      {
+        GlobalReferenceCache().release(filename);
+        goto tryDecompile;
+      }
     NodeSmartReference clone(NewMapRoot(""));
     Node_getTraversable(*resource->getNode())->traverse(CloneAll(clone));
     Map_gatherNamespaced(clone);
@@ -1681,7 +1694,7 @@ tryDecompile:
     output.push_string(gamename_get());
     output.push_string(" -convert -format ");
     output.push_string(Brush::m_type == eBrushTypeQuake3BP ? "map_bp" : "map");
-    output.push_string(" \"");
+    output.push_string(" -readmap \"");
     output.push_string(filename);
     output.push_string("\"");
 
index ff7852e72ad58bdb027faeb9f6acd3038431e15b..7352b38665e9cccb8c8f51aab7570fa4fe8ced6b 100644 (file)
@@ -2965,9 +2965,9 @@ void XYWindow_Construct()
   GlobalCommands_insert("NextView", FreeCaller<XY_Next>(), Accelerator(GDK_Tab, (GdkModifierType)GDK_CONTROL_MASK));
   GlobalCommands_insert("ZoomIn", FreeCaller<XY_ZoomIn>(), Accelerator(GDK_Delete));
   GlobalCommands_insert("ZoomOut", FreeCaller<XY_ZoomOut>(), Accelerator(GDK_Insert));
-  GlobalCommands_insert("ViewTop", FreeCaller<XY_Top>());
-  GlobalCommands_insert("ViewSide", FreeCaller<XY_Side>());
-  GlobalCommands_insert("ViewFront", FreeCaller<XY_Front>());
+  GlobalCommands_insert("ViewTop", FreeCaller<XY_Top>(), Accelerator(GDK_KP_Home));
+  GlobalCommands_insert("ViewSide", FreeCaller<XY_Side>(), Accelerator(GDK_KP_Page_Down));
+  GlobalCommands_insert("ViewFront", FreeCaller<XY_Front>(), Accelerator(GDK_KP_End));
   GlobalCommands_insert("Zoom100", FreeCaller<XY_Zoom100>());
   GlobalCommands_insert("CenterXYView", FreeCaller<XY_Focus>(), Accelerator(GDK_Tab, (GdkModifierType)(GDK_SHIFT_MASK|GDK_CONTROL_MASK)));
 
diff --git a/regression_tests/q3map2/base_winding/README.txt b/regression_tests/q3map2/base_winding/README.txt
new file mode 100644 (file)
index 0000000..599ec3d
--- /dev/null
@@ -0,0 +1,8 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+The provided map, maps/base_winding.map, serves as an example map to test
+changes to BaseWindingForPlane().  This map has planes at many different
+angles.  Use the patch base_winding_logging.patch to log the computed
+base windings, in order to compare before and after when making changes to
+BaseWindingForPlane().
diff --git a/regression_tests/q3map2/base_winding/base_winding_logging.patch b/regression_tests/q3map2/base_winding/base_winding_logging.patch
new file mode 100644 (file)
index 0000000..20fbaee
--- /dev/null
@@ -0,0 +1,27 @@
+Index: tools/quake3/q3map2/brush.c
+===================================================================
+--- tools/quake3/q3map2/brush.c        (revision 369)
++++ tools/quake3/q3map2/brush.c        (working copy)
+@@ -357,6 +357,8 @@
+       side_t          *side;
+       plane_t         *plane;
+       
++      static  int     brushord = -1;
++      brushord++;
+       
+       /* walk the list of brush sides */
+       for( i = 0; i < brush->numsides; i++ )
+@@ -367,6 +369,13 @@
+               
+               /* make huge winding */
+               w = BaseWindingForPlane( plane->normal, plane->dist );
++              Sys_Printf(">>> BaseWindingForPlane() for brush %i, side %i is as follows:\n", brushord, i);
++              for (j = 0; j < w->numpoints; j++) {
++                      Sys_Printf(">>> (%.1f %.1f %.1f) [rounded to nearest integer coordinates]\n",
++                                      Q_rint(w->p[j][0]),
++                                      Q_rint(w->p[j][1]),
++                                      Q_rint(w->p[j][2]));
++              }
+               
+               /* walk the list of brush sides */
+               for( j = 0; j < brush->numsides && w != NULL; j++ )
diff --git a/regression_tests/q3map2/base_winding/maps/base_winding.map b/regression_tests/q3map2/base_winding/maps/base_winding.map
new file mode 100644 (file)
index 0000000..237278a
--- /dev/null
@@ -0,0 +1,1284 @@
+{
+"classname" "worldspawn"
+{
+( 768 256 0 ) ( 768 115 -256 ) ( 768 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 256 0 ) ( 768 256 0 ) ( 512 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 -256 ) ( 768 115 -256 ) ( 443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 512 0 0 ) ( 768 0 0 ) ( 428 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 512 0 0 ) ( 428 115 -256 ) ( 443 256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 128 -443 ) ( 768 0 -443 ) ( 768 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 -443 ) ( 768 128 -443 ) ( 428 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 -443 ) ( 768 0 -443 ) ( 222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 -256 ) ( 768 115 -256 ) ( 256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 -256 ) ( 256 0 -443 ) ( 222 128 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 128 -768 ) ( 768 0 -768 ) ( 768 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 -443 ) ( 768 128 -443 ) ( 256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 -768 ) ( 768 128 -768 ) ( 222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 -768 ) ( 768 0 -768 ) ( 222 128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 -443 ) ( 768 0 -443 ) ( 256 0 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 -443 ) ( 256 0 -768 ) ( 222 128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 222 128 -768 ) ( 0 0 -768 ) ( 256 0 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 -443 ) ( 222 128 -768 ) ( 256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 -512 ) ( 0 0 -768 ) ( 222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 -443 ) ( 256 0 -768 ) ( 0 0 -512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 -443 ) ( 0 0 -512 ) ( 222 128 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 314 -256 ) ( 768 115 -256 ) ( 768 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 -256 ) ( 768 314 -256 ) ( 443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 -256 ) ( 768 115 -256 ) ( 314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 256 0 ) ( 768 256 0 ) ( 428 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 256 0 ) ( 428 115 -256 ) ( 314 314 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 314 -256 ) ( 768 128 -443 ) ( 768 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 -256 ) ( 768 314 -256 ) ( 428 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 -443 ) ( 768 128 -443 ) ( 314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 -256 ) ( 768 115 -256 ) ( 222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 -256 ) ( 222 128 -443 ) ( 314 314 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 443 0 ) ( 768 314 -256 ) ( 768 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 443 0 ) ( 768 443 0 ) ( 443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 -256 ) ( 768 314 -256 ) ( 256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 256 0 ) ( 768 256 0 ) ( 314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 256 0 ) ( 314 314 -256 ) ( 256 443 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 222 -443 ) ( 768 128 -443 ) ( 768 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -443 ) ( 768 222 -443 ) ( 314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 -443 ) ( 768 128 -443 ) ( 128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 -256 ) ( 768 314 -256 ) ( 222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 -256 ) ( 222 128 -443 ) ( 128 222 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 222 -768 ) ( 768 128 -768 ) ( 768 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -443 ) ( 768 222 -443 ) ( 222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -768 ) ( 768 222 -768 ) ( 128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 -768 ) ( 768 128 -768 ) ( 128 222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 -443 ) ( 768 128 -443 ) ( 222 128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 -443 ) ( 222 128 -768 ) ( 128 222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 128 222 -768 ) ( 0 0 -768 ) ( 222 128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -443 ) ( 128 222 -768 ) ( 222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 -512 ) ( 0 0 -768 ) ( 128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 -443 ) ( 222 128 -768 ) ( 0 0 -512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 -443 ) ( 0 0 -512 ) ( 128 222 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 115 768 -256 ) ( 314 768 -256 ) ( 256 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 -256 ) ( 115 768 -256 ) ( 256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 -256 ) ( 314 768 -256 ) ( 115 428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 443 0 ) ( 256 768 0 ) ( 314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 443 0 ) ( 314 314 -256 ) ( 115 428 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 768 -256 ) ( 768 768 0 ) ( 256 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 -256 ) ( 314 768 -256 ) ( 256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 314 -256 ) ( 768 768 -256 ) ( 314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 443 0 ) ( 768 768 0 ) ( 768 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 443 0 ) ( 256 768 0 ) ( 768 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 443 0 ) ( 768 443 0 ) ( 768 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 115 768 -256 ) ( 128 768 -443 ) ( 314 768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 -256 ) ( 115 768 -256 ) ( 314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -443 ) ( 128 768 -443 ) ( 115 428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 -256 ) ( 314 768 -256 ) ( 128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 -256 ) ( 128 222 -443 ) ( 115 428 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 768 -443 ) ( 768 768 -256 ) ( 314 768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -443 ) ( 128 768 -443 ) ( 314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 222 -443 ) ( 768 768 -443 ) ( 128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 314 -256 ) ( 768 768 -256 ) ( 768 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 -256 ) ( 314 768 -256 ) ( 768 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 -256 ) ( 768 314 -256 ) ( 768 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 768 768 -768 ) ( 128 768 -768 ) ( 128 222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 222 -443 ) ( 768 222 -768 ) ( 128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 768 -443 ) ( 768 768 -768 ) ( 768 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 768 -443 ) ( 128 768 -768 ) ( 768 768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -443 ) ( 128 222 -768 ) ( 128 768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -443 ) ( 128 768 -443 ) ( 768 768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 0 768 0 ) ( 115 768 -256 ) ( 256 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 512 0 ) ( 0 768 0 ) ( 256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 -256 ) ( 115 768 -256 ) ( 0 512 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 443 0 ) ( 256 768 0 ) ( 115 428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 443 0 ) ( 115 428 -256 ) ( 0 512 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 0 768 -443 ) ( 128 768 -443 ) ( 115 768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 -443 ) ( 0 768 -443 ) ( 115 428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -443 ) ( 128 768 -443 ) ( 0 256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 -256 ) ( 115 768 -256 ) ( 128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 -256 ) ( 128 222 -443 ) ( 0 256 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 0 768 -768 ) ( 128 768 -768 ) ( 128 768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 -443 ) ( 0 768 -443 ) ( 128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 -768 ) ( 0 768 -768 ) ( 0 256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -768 ) ( 128 768 -768 ) ( 0 256 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -443 ) ( 128 768 -443 ) ( 128 222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -443 ) ( 128 222 -768 ) ( 0 256 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 0 256 -768 ) ( 0 0 -768 ) ( 128 222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 -443 ) ( 0 256 -768 ) ( 128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 -512 ) ( 0 0 -768 ) ( 0 256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -443 ) ( 128 222 -768 ) ( 0 0 -512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 -443 ) ( 0 0 -512 ) ( 0 256 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -115 768 -256 ) ( 115 768 -256 ) ( 0 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 428 -256 ) ( -115 768 -256 ) ( 0 512 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 -256 ) ( 115 768 -256 ) ( -115 428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 512 0 ) ( 0 768 0 ) ( 115 428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 512 0 ) ( 115 428 -256 ) ( -115 428 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -115 768 -256 ) ( 0 768 -443 ) ( 115 768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 428 -256 ) ( -115 768 -256 ) ( 115 428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 -443 ) ( 0 768 -443 ) ( -115 428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 -256 ) ( 115 768 -256 ) ( 0 256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 -256 ) ( 0 256 -443 ) ( -115 428 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 0 -512 0 ) ( 115 -428 -256 ) ( 256 -443 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 0 -512 0 ) ( 0 -768 0 ) ( 115 -428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 -428 -256 ) ( 115 -768 -256 ) ( 256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 -443 0 ) ( 256 -768 0 ) ( 0 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 -768 0 ) ( 115 -768 -256 ) ( 0 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 115 -428 -256 ) ( 0 -256 -443 ) ( 128 -222 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 115 -428 -256 ) ( 115 -768 -256 ) ( 0 -256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 -443 ) ( 0 -768 -443 ) ( 128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 -443 ) ( 128 -768 -443 ) ( 115 -428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -768 -443 ) ( 0 -768 -443 ) ( 115 -768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 0 -256 -443 ) ( 0 -256 -768 ) ( 128 -222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 -443 ) ( 0 -768 -443 ) ( 0 -256 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 -768 ) ( 0 -768 -768 ) ( 128 -222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 -768 ) ( 128 -768 -768 ) ( 128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 -443 ) ( 128 -768 -443 ) ( 0 -256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -768 -768 ) ( 0 -768 -768 ) ( 0 -768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 0 -256 -443 ) ( 0 0 -512 ) ( 128 -222 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 0 -256 -443 ) ( 0 -256 -768 ) ( 0 0 -512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 -512 ) ( 0 0 -768 ) ( 128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 -443 ) ( 128 -222 -768 ) ( 0 -256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 -768 ) ( 0 0 -768 ) ( 0 -256 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 256 -443 0 ) ( 115 -428 -256 ) ( 314 -314 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 256 -443 0 ) ( 256 -768 0 ) ( 115 -428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 -428 -256 ) ( 115 -768 -256 ) ( 314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -314 -256 ) ( 314 -768 -256 ) ( 256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -768 -256 ) ( 115 -768 -256 ) ( 256 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 115 -428 -256 ) ( 128 -222 -443 ) ( 314 -314 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 115 -428 -256 ) ( 115 -768 -256 ) ( 128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 -443 ) ( 128 -768 -443 ) ( 314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -314 -256 ) ( 314 -768 -256 ) ( 115 -428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -768 -256 ) ( 128 -768 -443 ) ( 115 -768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 256 -443 0 ) ( 314 -314 -256 ) ( 443 -256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 256 -443 0 ) ( 256 -768 0 ) ( 314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -314 -256 ) ( 314 -768 -256 ) ( 443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 -256 0 ) ( 443 -768 0 ) ( 256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 -768 0 ) ( 314 -768 -256 ) ( 256 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 314 -314 -256 ) ( 128 -222 -443 ) ( 222 -128 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 314 -314 -256 ) ( 314 -768 -256 ) ( 128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 -443 ) ( 128 -768 -443 ) ( 222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 -443 ) ( 222 -768 -443 ) ( 314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -768 -443 ) ( 128 -768 -443 ) ( 314 -768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 128 -222 -443 ) ( 128 -222 -768 ) ( 222 -128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 -443 ) ( 128 -768 -443 ) ( 128 -222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 -768 ) ( 128 -768 -768 ) ( 222 -128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 -768 ) ( 222 -768 -768 ) ( 222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 -443 ) ( 222 -768 -443 ) ( 128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -768 -768 ) ( 128 -768 -768 ) ( 128 -768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 128 -222 -443 ) ( 0 0 -512 ) ( 222 -128 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 128 -222 -443 ) ( 128 -222 -768 ) ( 0 0 -512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 -512 ) ( 0 0 -768 ) ( 222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 -443 ) ( 222 -128 -768 ) ( 128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 -768 ) ( 0 0 -768 ) ( 128 -222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 443 -256 0 ) ( 314 -314 -256 ) ( 428 -115 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 443 -256 0 ) ( 768 -256 0 ) ( 314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -314 -256 ) ( 768 -314 -256 ) ( 428 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 -115 -256 ) ( 768 -115 -256 ) ( 443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -115 -256 ) ( 768 -314 -256 ) ( 768 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 443 -256 0 ) ( 443 -768 0 ) ( 314 -768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 -256 0 ) ( 768 -256 0 ) ( 443 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 -768 0 ) ( 768 -768 0 ) ( 314 -768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -768 -256 ) ( 768 -768 -256 ) ( 314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -314 -256 ) ( 768 -314 -256 ) ( 443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -768 -256 ) ( 768 -768 0 ) ( 768 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 314 -314 -256 ) ( 222 -128 -443 ) ( 428 -115 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 314 -314 -256 ) ( 768 -314 -256 ) ( 222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 -443 ) ( 768 -128 -443 ) ( 428 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 -115 -256 ) ( 768 -115 -256 ) ( 314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -115 -256 ) ( 768 -128 -443 ) ( 768 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 314 -314 -256 ) ( 314 -768 -256 ) ( 222 -768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -314 -256 ) ( 768 -314 -256 ) ( 314 -768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -768 -256 ) ( 768 -768 -256 ) ( 222 -768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -768 -443 ) ( 768 -768 -443 ) ( 222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 -443 ) ( 768 -128 -443 ) ( 314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -768 -443 ) ( 768 -768 -256 ) ( 768 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 222 -128 -443 ) ( 768 -128 -443 ) ( 768 -768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 -443 ) ( 222 -128 -768 ) ( 768 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -128 -443 ) ( 768 -128 -768 ) ( 768 -768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -768 -443 ) ( 768 -768 -768 ) ( 222 -768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -768 -443 ) ( 222 -768 -768 ) ( 222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -768 -768 ) ( 768 -128 -768 ) ( 222 -128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 443 -256 0 ) ( 428 -115 -256 ) ( 512 0 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 443 -256 0 ) ( 768 -256 0 ) ( 428 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 -115 -256 ) ( 768 -115 -256 ) ( 512 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 512 0 0 ) ( 768 0 0 ) ( 443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 0 0 ) ( 768 -115 -256 ) ( 768 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 428 -115 -256 ) ( 222 -128 -443 ) ( 256 0 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 428 -115 -256 ) ( 768 -115 -256 ) ( 222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 -443 ) ( 768 -128 -443 ) ( 256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 -443 ) ( 768 0 -443 ) ( 428 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 0 -443 ) ( 768 -128 -443 ) ( 768 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 222 -128 -443 ) ( 222 -128 -768 ) ( 256 0 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 -443 ) ( 768 -128 -443 ) ( 222 -128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 -768 ) ( 768 -128 -768 ) ( 256 0 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 -768 ) ( 768 0 -768 ) ( 256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 -443 ) ( 768 0 -443 ) ( 222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 0 -768 ) ( 768 -128 -768 ) ( 768 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 222 -128 -443 ) ( 0 0 -512 ) ( 256 0 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 222 -128 -443 ) ( 222 -128 -768 ) ( 0 0 -512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 -512 ) ( 0 0 -768 ) ( 256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 -443 ) ( 256 0 -768 ) ( 222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 -768 ) ( 0 0 -768 ) ( 222 -128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 512 0 0 ) ( 428 -115 -256 ) ( 428 115 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 512 0 0 ) ( 768 0 0 ) ( 428 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 -115 -256 ) ( 768 -115 -256 ) ( 428 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 -256 ) ( 768 115 -256 ) ( 512 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 115 -256 ) ( 768 -115 -256 ) ( 768 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 428 -115 -256 ) ( 256 0 -443 ) ( 428 115 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 428 -115 -256 ) ( 768 -115 -256 ) ( 256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 -443 ) ( 768 0 -443 ) ( 428 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 -256 ) ( 768 115 -256 ) ( 428 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 115 -256 ) ( 768 0 -443 ) ( 768 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -768 -256 0 ) ( -768 -115 -256 ) ( -768 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 -256 0 ) ( -768 -256 0 ) ( -512 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 -256 ) ( -768 -115 -256 ) ( -443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -512 0 0 ) ( -768 0 0 ) ( -428 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -512 0 0 ) ( -428 -115 -256 ) ( -443 -256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 -128 -443 ) ( -768 0 -443 ) ( -768 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 -443 ) ( -768 -128 -443 ) ( -428 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 -443 ) ( -768 0 -443 ) ( -222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 -256 ) ( -768 -115 -256 ) ( -256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 -256 ) ( -256 0 -443 ) ( -222 -128 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 -128 -768 ) ( -768 0 -768 ) ( -768 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 -443 ) ( -768 -128 -443 ) ( -256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 -768 ) ( -768 -128 -768 ) ( -222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 -768 ) ( -768 0 -768 ) ( -222 -128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 -443 ) ( -768 0 -443 ) ( -256 0 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 -443 ) ( -256 0 -768 ) ( -222 -128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -222 -128 -768 ) ( 0 0 -768 ) ( -256 0 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 -443 ) ( -222 -128 -768 ) ( -256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 -512 ) ( 0 0 -768 ) ( -222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 -443 ) ( -256 0 -768 ) ( 0 0 -512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 -443 ) ( 0 0 -512 ) ( -222 -128 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 -314 -256 ) ( -768 -115 -256 ) ( -768 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 -256 ) ( -768 -314 -256 ) ( -443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 -256 ) ( -768 -115 -256 ) ( -314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 -256 0 ) ( -768 -256 0 ) ( -428 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 -256 0 ) ( -428 -115 -256 ) ( -314 -314 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 -314 -256 ) ( -768 -128 -443 ) ( -768 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 -256 ) ( -768 -314 -256 ) ( -428 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 -443 ) ( -768 -128 -443 ) ( -314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 -256 ) ( -768 -115 -256 ) ( -222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 -256 ) ( -222 -128 -443 ) ( -314 -314 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 -443 0 ) ( -768 -314 -256 ) ( -768 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 -443 0 ) ( -768 -443 0 ) ( -443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 -256 ) ( -768 -314 -256 ) ( -256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 -256 0 ) ( -768 -256 0 ) ( -314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 -256 0 ) ( -314 -314 -256 ) ( -256 -443 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 -222 -443 ) ( -768 -128 -443 ) ( -768 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -443 ) ( -768 -222 -443 ) ( -314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 -443 ) ( -768 -128 -443 ) ( -128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 -256 ) ( -768 -314 -256 ) ( -222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 -256 ) ( -222 -128 -443 ) ( -128 -222 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 -222 -768 ) ( -768 -128 -768 ) ( -768 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -443 ) ( -768 -222 -443 ) ( -222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -768 ) ( -768 -222 -768 ) ( -128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 -768 ) ( -768 -128 -768 ) ( -128 -222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 -443 ) ( -768 -128 -443 ) ( -222 -128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 -443 ) ( -222 -128 -768 ) ( -128 -222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -128 -222 -768 ) ( 0 0 -768 ) ( -222 -128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -443 ) ( -128 -222 -768 ) ( -222 -128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 -512 ) ( 0 0 -768 ) ( -128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 -443 ) ( -222 -128 -768 ) ( 0 0 -512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 -443 ) ( 0 0 -512 ) ( -128 -222 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -115 -768 -256 ) ( -314 -768 -256 ) ( -256 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 -256 ) ( -115 -768 -256 ) ( -256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 -256 ) ( -314 -768 -256 ) ( -115 -428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 -443 0 ) ( -256 -768 0 ) ( -314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 -443 0 ) ( -314 -314 -256 ) ( -115 -428 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 -768 -256 ) ( -768 -768 0 ) ( -256 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 -256 ) ( -314 -768 -256 ) ( -256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 -314 -256 ) ( -768 -768 -256 ) ( -314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 -443 0 ) ( -768 -768 0 ) ( -768 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 -443 0 ) ( -256 -768 0 ) ( -768 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 -443 0 ) ( -768 -443 0 ) ( -768 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -115 -768 -256 ) ( -128 -768 -443 ) ( -314 -768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 -256 ) ( -115 -768 -256 ) ( -314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -443 ) ( -128 -768 -443 ) ( -115 -428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 -256 ) ( -314 -768 -256 ) ( -128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 -256 ) ( -128 -222 -443 ) ( -115 -428 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 -768 -443 ) ( -768 -768 -256 ) ( -314 -768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -443 ) ( -128 -768 -443 ) ( -314 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 -222 -443 ) ( -768 -768 -443 ) ( -128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 -314 -256 ) ( -768 -768 -256 ) ( -768 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 -256 ) ( -314 -768 -256 ) ( -768 -314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 -256 ) ( -768 -314 -256 ) ( -768 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -768 -768 -768 ) ( -128 -768 -768 ) ( -128 -222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 -222 -443 ) ( -768 -222 -768 ) ( -128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 -768 -443 ) ( -768 -768 -768 ) ( -768 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -768 -443 ) ( -128 -768 -768 ) ( -768 -768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -443 ) ( -128 -222 -768 ) ( -128 -768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -443 ) ( -128 -768 -443 ) ( -768 -768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 0 -768 0 ) ( -115 -768 -256 ) ( -256 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -512 0 ) ( 0 -768 0 ) ( -256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 -256 ) ( -115 -768 -256 ) ( 0 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 -443 0 ) ( -256 -768 0 ) ( -115 -428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 -443 0 ) ( -115 -428 -256 ) ( 0 -512 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 0 -768 -443 ) ( -128 -768 -443 ) ( -115 -768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 -443 ) ( 0 -768 -443 ) ( -115 -428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -443 ) ( -128 -768 -443 ) ( 0 -256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 -256 ) ( -115 -768 -256 ) ( -128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 -256 ) ( -128 -222 -443 ) ( 0 -256 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 0 -768 -768 ) ( -128 -768 -768 ) ( -128 -768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 -443 ) ( 0 -768 -443 ) ( -128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 -768 ) ( 0 -768 -768 ) ( 0 -256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -768 ) ( -128 -768 -768 ) ( 0 -256 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -443 ) ( -128 -768 -443 ) ( -128 -222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -443 ) ( -128 -222 -768 ) ( 0 -256 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 0 -256 -768 ) ( 0 0 -768 ) ( -128 -222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 -443 ) ( 0 -256 -768 ) ( -128 -222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 -512 ) ( 0 0 -768 ) ( 0 -256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -443 ) ( -128 -222 -768 ) ( 0 0 -512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 -443 ) ( 0 0 -512 ) ( 0 -256 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 115 -768 -256 ) ( -115 -768 -256 ) ( 0 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 -428 -256 ) ( 115 -768 -256 ) ( 0 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 -256 ) ( -115 -768 -256 ) ( 115 -428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -512 0 ) ( 0 -768 0 ) ( -115 -428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -512 0 ) ( -115 -428 -256 ) ( 115 -428 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 115 -768 -256 ) ( 0 -768 -443 ) ( -115 -768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 -428 -256 ) ( 115 -768 -256 ) ( -115 -428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 -443 ) ( 0 -768 -443 ) ( 115 -428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 -256 ) ( -115 -768 -256 ) ( 0 -256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 -256 ) ( 0 -256 -443 ) ( 115 -428 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 0 512 0 ) ( -115 428 -256 ) ( -256 443 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 0 512 0 ) ( 0 768 0 ) ( -115 428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 428 -256 ) ( -115 768 -256 ) ( -256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 443 0 ) ( -256 768 0 ) ( 0 512 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 768 0 ) ( -115 768 -256 ) ( 0 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -115 428 -256 ) ( 0 256 -443 ) ( -128 222 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -115 428 -256 ) ( -115 768 -256 ) ( 0 256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 -443 ) ( 0 768 -443 ) ( -128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 -443 ) ( -128 768 -443 ) ( -115 428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 768 -443 ) ( 0 768 -443 ) ( -115 768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 0 256 -443 ) ( 0 256 -768 ) ( -128 222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 -443 ) ( 0 768 -443 ) ( 0 256 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 -768 ) ( 0 768 -768 ) ( -128 222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 -768 ) ( -128 768 -768 ) ( -128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 -443 ) ( -128 768 -443 ) ( 0 256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 768 -768 ) ( 0 768 -768 ) ( 0 768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 0 256 -443 ) ( 0 0 -512 ) ( -128 222 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 0 256 -443 ) ( 0 256 -768 ) ( 0 0 -512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 -512 ) ( 0 0 -768 ) ( -128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 -443 ) ( -128 222 -768 ) ( 0 256 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 -768 ) ( 0 0 -768 ) ( 0 256 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -256 443 0 ) ( -115 428 -256 ) ( -314 314 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -256 443 0 ) ( -256 768 0 ) ( -115 428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 428 -256 ) ( -115 768 -256 ) ( -314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 314 -256 ) ( -314 768 -256 ) ( -256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 768 -256 ) ( -115 768 -256 ) ( -256 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -115 428 -256 ) ( -128 222 -443 ) ( -314 314 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -115 428 -256 ) ( -115 768 -256 ) ( -128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 -443 ) ( -128 768 -443 ) ( -314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 314 -256 ) ( -314 768 -256 ) ( -115 428 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 768 -256 ) ( -128 768 -443 ) ( -115 768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -256 443 0 ) ( -314 314 -256 ) ( -443 256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -256 443 0 ) ( -256 768 0 ) ( -314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 314 -256 ) ( -314 768 -256 ) ( -443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 256 0 ) ( -443 768 0 ) ( -256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 768 0 ) ( -314 768 -256 ) ( -256 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -314 314 -256 ) ( -128 222 -443 ) ( -222 128 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -314 314 -256 ) ( -314 768 -256 ) ( -128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 -443 ) ( -128 768 -443 ) ( -222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 -443 ) ( -222 768 -443 ) ( -314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 768 -443 ) ( -128 768 -443 ) ( -314 768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -128 222 -443 ) ( -128 222 -768 ) ( -222 128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 -443 ) ( -128 768 -443 ) ( -128 222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 -768 ) ( -128 768 -768 ) ( -222 128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 -768 ) ( -222 768 -768 ) ( -222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 -443 ) ( -222 768 -443 ) ( -128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 768 -768 ) ( -128 768 -768 ) ( -128 768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -128 222 -443 ) ( 0 0 -512 ) ( -222 128 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -128 222 -443 ) ( -128 222 -768 ) ( 0 0 -512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 -512 ) ( 0 0 -768 ) ( -222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 -443 ) ( -222 128 -768 ) ( -128 222 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 -768 ) ( 0 0 -768 ) ( -128 222 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -443 256 0 ) ( -314 314 -256 ) ( -428 115 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -443 256 0 ) ( -768 256 0 ) ( -314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 314 -256 ) ( -768 314 -256 ) ( -428 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 115 -256 ) ( -768 115 -256 ) ( -443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 115 -256 ) ( -768 314 -256 ) ( -768 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -443 256 0 ) ( -443 768 0 ) ( -314 768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 256 0 ) ( -768 256 0 ) ( -443 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 768 0 ) ( -768 768 0 ) ( -314 768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 768 -256 ) ( -768 768 -256 ) ( -314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 314 -256 ) ( -768 314 -256 ) ( -443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 768 -256 ) ( -768 768 0 ) ( -768 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -314 314 -256 ) ( -222 128 -443 ) ( -428 115 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -314 314 -256 ) ( -768 314 -256 ) ( -222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 -443 ) ( -768 128 -443 ) ( -428 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 115 -256 ) ( -768 115 -256 ) ( -314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 115 -256 ) ( -768 128 -443 ) ( -768 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -314 314 -256 ) ( -314 768 -256 ) ( -222 768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 314 -256 ) ( -768 314 -256 ) ( -314 768 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 768 -256 ) ( -768 768 -256 ) ( -222 768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 768 -443 ) ( -768 768 -443 ) ( -222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 -443 ) ( -768 128 -443 ) ( -314 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 768 -443 ) ( -768 768 -256 ) ( -768 314 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -222 128 -443 ) ( -768 128 -443 ) ( -768 768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 -443 ) ( -222 128 -768 ) ( -768 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 128 -443 ) ( -768 128 -768 ) ( -768 768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 768 -443 ) ( -768 768 -768 ) ( -222 768 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 768 -443 ) ( -222 768 -768 ) ( -222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 768 -768 ) ( -768 128 -768 ) ( -222 128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -443 256 0 ) ( -428 115 -256 ) ( -512 0 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -443 256 0 ) ( -768 256 0 ) ( -428 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 115 -256 ) ( -768 115 -256 ) ( -512 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -512 0 0 ) ( -768 0 0 ) ( -443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 0 0 ) ( -768 115 -256 ) ( -768 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -428 115 -256 ) ( -222 128 -443 ) ( -256 0 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -428 115 -256 ) ( -768 115 -256 ) ( -222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 -443 ) ( -768 128 -443 ) ( -256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 -443 ) ( -768 0 -443 ) ( -428 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 0 -443 ) ( -768 128 -443 ) ( -768 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -222 128 -443 ) ( -222 128 -768 ) ( -256 0 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 -443 ) ( -768 128 -443 ) ( -222 128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 -768 ) ( -768 128 -768 ) ( -256 0 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 -768 ) ( -768 0 -768 ) ( -256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 -443 ) ( -768 0 -443 ) ( -222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 0 -768 ) ( -768 128 -768 ) ( -768 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -222 128 -443 ) ( 0 0 -512 ) ( -256 0 -443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -222 128 -443 ) ( -222 128 -768 ) ( 0 0 -512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 -512 ) ( 0 0 -768 ) ( -256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 -443 ) ( -256 0 -768 ) ( -222 128 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 -768 ) ( 0 0 -768 ) ( -222 128 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -512 0 0 ) ( -428 115 -256 ) ( -428 -115 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -512 0 0 ) ( -768 0 0 ) ( -428 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 115 -256 ) ( -768 115 -256 ) ( -428 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 -256 ) ( -768 -115 -256 ) ( -512 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 -115 -256 ) ( -768 115 -256 ) ( -768 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -428 115 -256 ) ( -256 0 -443 ) ( -428 -115 -256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -428 115 -256 ) ( -768 115 -256 ) ( -256 0 -443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 -443 ) ( -768 0 -443 ) ( -428 -115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 -256 ) ( -768 -115 -256 ) ( -428 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 -115 -256 ) ( -768 0 -443 ) ( -768 115 -256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 512 0 0 ) ( 428 -115 256 ) ( 443 -256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 512 0 0 ) ( 768 0 0 ) ( 428 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 -115 256 ) ( 768 -115 256 ) ( 443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 -256 0 ) ( 768 -256 0 ) ( 512 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -256 0 ) ( 768 -115 256 ) ( 768 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 428 -115 256 ) ( 256 0 443 ) ( 222 -128 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 428 -115 256 ) ( 768 -115 256 ) ( 256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 443 ) ( 768 0 443 ) ( 222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 443 ) ( 768 -128 443 ) ( 428 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -128 443 ) ( 768 0 443 ) ( 768 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 256 0 443 ) ( 256 0 768 ) ( 222 -128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 443 ) ( 768 0 443 ) ( 256 0 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 768 ) ( 768 0 768 ) ( 222 -128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 768 ) ( 768 -128 768 ) ( 222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 443 ) ( 768 -128 443 ) ( 256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -128 768 ) ( 768 0 768 ) ( 768 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 256 0 443 ) ( 0 0 512 ) ( 222 -128 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 256 0 443 ) ( 256 0 768 ) ( 0 0 512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 512 ) ( 0 0 768 ) ( 222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 443 ) ( 222 -128 768 ) ( 256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 768 ) ( 0 0 768 ) ( 256 0 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 443 -256 0 ) ( 428 -115 256 ) ( 314 -314 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 443 -256 0 ) ( 768 -256 0 ) ( 428 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 -115 256 ) ( 768 -115 256 ) ( 314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -314 256 ) ( 768 -314 256 ) ( 443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -314 256 ) ( 768 -115 256 ) ( 768 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 428 -115 256 ) ( 222 -128 443 ) ( 314 -314 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 428 -115 256 ) ( 768 -115 256 ) ( 222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 443 ) ( 768 -128 443 ) ( 314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -314 256 ) ( 768 -314 256 ) ( 428 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -314 256 ) ( 768 -128 443 ) ( 768 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 443 -256 0 ) ( 314 -314 256 ) ( 256 -443 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 443 -256 0 ) ( 768 -256 0 ) ( 314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -314 256 ) ( 768 -314 256 ) ( 256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 -443 0 ) ( 768 -443 0 ) ( 443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -443 0 ) ( 768 -314 256 ) ( 768 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 314 -314 256 ) ( 222 -128 443 ) ( 128 -222 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 314 -314 256 ) ( 768 -314 256 ) ( 222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 443 ) ( 768 -128 443 ) ( 128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 443 ) ( 768 -222 443 ) ( 314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -222 443 ) ( 768 -128 443 ) ( 768 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 222 -128 443 ) ( 222 -128 768 ) ( 128 -222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 443 ) ( 768 -128 443 ) ( 222 -128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 -128 768 ) ( 768 -128 768 ) ( 128 -222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 768 ) ( 768 -222 768 ) ( 128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 443 ) ( 768 -222 443 ) ( 222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -222 768 ) ( 768 -128 768 ) ( 768 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 222 -128 443 ) ( 0 0 512 ) ( 128 -222 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 222 -128 443 ) ( 222 -128 768 ) ( 0 0 512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 512 ) ( 0 0 768 ) ( 128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 443 ) ( 128 -222 768 ) ( 222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 768 ) ( 0 0 768 ) ( 222 -128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 256 -443 0 ) ( 314 -314 256 ) ( 115 -428 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 256 -443 0 ) ( 256 -768 0 ) ( 314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -314 256 ) ( 314 -768 256 ) ( 115 -428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 -428 256 ) ( 115 -768 256 ) ( 256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 -768 256 ) ( 314 -768 256 ) ( 256 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 256 -443 0 ) ( 768 -443 0 ) ( 768 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 -443 0 ) ( 256 -768 0 ) ( 768 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -443 0 ) ( 768 -768 0 ) ( 768 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -314 256 ) ( 768 -768 256 ) ( 314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -314 256 ) ( 314 -768 256 ) ( 256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -768 256 ) ( 768 -768 0 ) ( 256 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 314 -314 256 ) ( 128 -222 443 ) ( 115 -428 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 314 -314 256 ) ( 314 -768 256 ) ( 128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 443 ) ( 128 -768 443 ) ( 115 -428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 -428 256 ) ( 115 -768 256 ) ( 314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 -768 256 ) ( 128 -768 443 ) ( 314 -768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 314 -314 256 ) ( 768 -314 256 ) ( 768 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 -314 256 ) ( 314 -768 256 ) ( 768 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -314 256 ) ( 768 -768 256 ) ( 768 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -222 443 ) ( 768 -768 443 ) ( 128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 443 ) ( 128 -768 443 ) ( 314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -768 443 ) ( 768 -768 256 ) ( 314 -768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 128 -222 443 ) ( 128 -768 443 ) ( 768 -768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 443 ) ( 128 -222 768 ) ( 128 -768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -768 443 ) ( 128 -768 768 ) ( 768 -768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -768 443 ) ( 768 -768 768 ) ( 768 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -222 443 ) ( 768 -222 768 ) ( 128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 -768 768 ) ( 128 -768 768 ) ( 128 -222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 256 -443 0 ) ( 115 -428 256 ) ( 0 -512 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 256 -443 0 ) ( 256 -768 0 ) ( 115 -428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 -428 256 ) ( 115 -768 256 ) ( 0 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -512 0 ) ( 0 -768 0 ) ( 256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -768 0 ) ( 115 -768 256 ) ( 256 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 115 -428 256 ) ( 128 -222 443 ) ( 0 -256 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 115 -428 256 ) ( 115 -768 256 ) ( 128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 443 ) ( 128 -768 443 ) ( 0 -256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 443 ) ( 0 -768 443 ) ( 115 -428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -768 443 ) ( 128 -768 443 ) ( 115 -768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 128 -222 443 ) ( 128 -222 768 ) ( 0 -256 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 443 ) ( 128 -768 443 ) ( 128 -222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 -222 768 ) ( 128 -768 768 ) ( 0 -256 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 768 ) ( 0 -768 768 ) ( 0 -256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 443 ) ( 0 -768 443 ) ( 128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -768 768 ) ( 128 -768 768 ) ( 128 -768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 128 -222 443 ) ( 0 0 512 ) ( 0 -256 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 128 -222 443 ) ( 128 -222 768 ) ( 0 0 512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 512 ) ( 0 0 768 ) ( 0 -256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 443 ) ( 0 -256 768 ) ( 128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 768 ) ( 0 0 768 ) ( 128 -222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 0 -512 0 ) ( 115 -428 256 ) ( -115 -428 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 0 -512 0 ) ( 0 -768 0 ) ( 115 -428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 -428 256 ) ( 115 -768 256 ) ( -115 -428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 256 ) ( -115 -768 256 ) ( 0 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -768 256 ) ( 115 -768 256 ) ( 0 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 115 -428 256 ) ( 0 -256 443 ) ( -115 -428 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 115 -428 256 ) ( 115 -768 256 ) ( 0 -256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 443 ) ( 0 -768 443 ) ( -115 -428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 256 ) ( -115 -768 256 ) ( 115 -428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -768 256 ) ( 0 -768 443 ) ( 115 -768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 256 768 0 ) ( 115 768 256 ) ( 0 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 443 0 ) ( 256 768 0 ) ( 0 512 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 256 ) ( 115 768 256 ) ( 256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 512 0 ) ( 0 768 0 ) ( 115 428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 512 0 ) ( 115 428 256 ) ( 256 443 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 128 768 443 ) ( 0 768 443 ) ( 115 768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 443 ) ( 128 768 443 ) ( 115 428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 443 ) ( 0 768 443 ) ( 128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 256 ) ( 115 768 256 ) ( 0 256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 256 ) ( 0 256 443 ) ( 128 222 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 128 768 768 ) ( 0 768 768 ) ( 0 768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 443 ) ( 128 768 443 ) ( 0 256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 768 ) ( 128 768 768 ) ( 128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 768 ) ( 0 768 768 ) ( 128 222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 443 ) ( 0 768 443 ) ( 0 256 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 443 ) ( 0 256 768 ) ( 128 222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 128 222 768 ) ( 0 0 768 ) ( 0 256 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 443 ) ( 128 222 768 ) ( 0 256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 512 ) ( 0 0 768 ) ( 128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 443 ) ( 0 256 768 ) ( 0 0 512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 443 ) ( 0 0 512 ) ( 128 222 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 314 768 256 ) ( 115 768 256 ) ( 256 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 256 ) ( 314 768 256 ) ( 256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 256 ) ( 115 768 256 ) ( 314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 443 0 ) ( 256 768 0 ) ( 115 428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 443 0 ) ( 115 428 256 ) ( 314 314 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 314 768 256 ) ( 128 768 443 ) ( 115 768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 256 ) ( 314 768 256 ) ( 115 428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 443 ) ( 128 768 443 ) ( 314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 256 ) ( 115 768 256 ) ( 128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 256 ) ( 128 222 443 ) ( 314 314 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 443 768 0 ) ( 314 768 256 ) ( 256 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 256 0 ) ( 443 768 0 ) ( 256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 256 ) ( 314 768 256 ) ( 443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 443 0 ) ( 256 768 0 ) ( 314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 443 0 ) ( 314 314 256 ) ( 443 256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 222 768 443 ) ( 128 768 443 ) ( 314 768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 443 ) ( 222 768 443 ) ( 314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 443 ) ( 128 768 443 ) ( 222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 256 ) ( 314 768 256 ) ( 128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 256 ) ( 128 222 443 ) ( 222 128 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 222 768 768 ) ( 128 768 768 ) ( 128 768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 443 ) ( 222 768 443 ) ( 128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 768 ) ( 222 768 768 ) ( 222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 768 ) ( 128 768 768 ) ( 222 128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 443 ) ( 128 768 443 ) ( 128 222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 443 ) ( 128 222 768 ) ( 222 128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 222 128 768 ) ( 0 0 768 ) ( 128 222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 443 ) ( 222 128 768 ) ( 128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 512 ) ( 0 0 768 ) ( 222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 443 ) ( 128 222 768 ) ( 0 0 512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 128 222 443 ) ( 0 0 512 ) ( 222 128 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 115 256 ) ( 768 314 256 ) ( 768 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 256 ) ( 768 115 256 ) ( 443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 256 ) ( 768 314 256 ) ( 428 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 256 0 ) ( 768 256 0 ) ( 314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 256 0 ) ( 314 314 256 ) ( 428 115 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 768 256 ) ( 768 768 0 ) ( 768 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 256 ) ( 768 314 256 ) ( 443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 768 256 ) ( 768 768 256 ) ( 314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 768 0 ) ( 768 768 0 ) ( 314 768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 256 0 ) ( 768 256 0 ) ( 443 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 256 0 ) ( 443 768 0 ) ( 314 768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 768 115 256 ) ( 768 128 443 ) ( 768 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 256 ) ( 768 115 256 ) ( 314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 443 ) ( 768 128 443 ) ( 428 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 256 ) ( 768 314 256 ) ( 222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 256 ) ( 222 128 443 ) ( 428 115 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 768 443 ) ( 768 768 256 ) ( 768 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 443 ) ( 768 128 443 ) ( 314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 768 443 ) ( 768 768 443 ) ( 222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 768 256 ) ( 768 768 256 ) ( 222 768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 256 ) ( 768 314 256 ) ( 314 768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 314 314 256 ) ( 314 768 256 ) ( 222 768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 768 768 768 ) ( 768 128 768 ) ( 222 128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 768 443 ) ( 222 768 768 ) ( 222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 768 443 ) ( 768 768 768 ) ( 222 768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 768 128 443 ) ( 768 128 768 ) ( 768 768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 443 ) ( 222 128 768 ) ( 768 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 443 ) ( 768 128 443 ) ( 768 768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 768 0 0 ) ( 768 115 256 ) ( 768 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 512 0 0 ) ( 768 0 0 ) ( 443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 256 ) ( 768 115 256 ) ( 512 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 256 0 ) ( 768 256 0 ) ( 428 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 443 256 0 ) ( 428 115 256 ) ( 512 0 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 0 443 ) ( 768 128 443 ) ( 768 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 443 ) ( 768 0 443 ) ( 428 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 443 ) ( 768 128 443 ) ( 256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 256 ) ( 768 115 256 ) ( 222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 256 ) ( 222 128 443 ) ( 256 0 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 0 768 ) ( 768 128 768 ) ( 768 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 443 ) ( 768 0 443 ) ( 222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 768 ) ( 768 0 768 ) ( 256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 768 ) ( 768 128 768 ) ( 256 0 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 443 ) ( 768 128 443 ) ( 222 128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 443 ) ( 222 128 768 ) ( 256 0 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 256 0 768 ) ( 0 0 768 ) ( 222 128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 443 ) ( 256 0 768 ) ( 222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 512 ) ( 0 0 768 ) ( 256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 443 ) ( 222 128 768 ) ( 0 0 512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 222 128 443 ) ( 0 0 512 ) ( 256 0 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 -115 256 ) ( 768 115 256 ) ( 768 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 -115 256 ) ( 768 -115 256 ) ( 512 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 256 ) ( 768 115 256 ) ( 428 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 512 0 0 ) ( 768 0 0 ) ( 428 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 512 0 0 ) ( 428 115 256 ) ( 428 -115 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 768 -115 256 ) ( 768 0 443 ) ( 768 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 -115 256 ) ( 768 -115 256 ) ( 428 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 256 0 443 ) ( 768 0 443 ) ( 428 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 256 ) ( 768 115 256 ) ( 256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 428 115 256 ) ( 256 0 443 ) ( 428 -115 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -512 0 0 ) ( -428 115 256 ) ( -443 256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -512 0 0 ) ( -768 0 0 ) ( -428 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 115 256 ) ( -768 115 256 ) ( -443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 256 0 ) ( -768 256 0 ) ( -512 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 256 0 ) ( -768 115 256 ) ( -768 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -428 115 256 ) ( -256 0 443 ) ( -222 128 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -428 115 256 ) ( -768 115 256 ) ( -256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 443 ) ( -768 0 443 ) ( -222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 443 ) ( -768 128 443 ) ( -428 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 128 443 ) ( -768 0 443 ) ( -768 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -256 0 443 ) ( -256 0 768 ) ( -222 128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 443 ) ( -768 0 443 ) ( -256 0 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 768 ) ( -768 0 768 ) ( -222 128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 768 ) ( -768 128 768 ) ( -222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 443 ) ( -768 128 443 ) ( -256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 128 768 ) ( -768 0 768 ) ( -768 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -256 0 443 ) ( 0 0 512 ) ( -222 128 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -256 0 443 ) ( -256 0 768 ) ( 0 0 512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 512 ) ( 0 0 768 ) ( -222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 443 ) ( -222 128 768 ) ( -256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 768 ) ( 0 0 768 ) ( -256 0 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -443 256 0 ) ( -428 115 256 ) ( -314 314 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -443 256 0 ) ( -768 256 0 ) ( -428 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 115 256 ) ( -768 115 256 ) ( -314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 314 256 ) ( -768 314 256 ) ( -443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 314 256 ) ( -768 115 256 ) ( -768 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -428 115 256 ) ( -222 128 443 ) ( -314 314 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -428 115 256 ) ( -768 115 256 ) ( -222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 443 ) ( -768 128 443 ) ( -314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 314 256 ) ( -768 314 256 ) ( -428 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 314 256 ) ( -768 128 443 ) ( -768 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -443 256 0 ) ( -314 314 256 ) ( -256 443 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -443 256 0 ) ( -768 256 0 ) ( -314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 314 256 ) ( -768 314 256 ) ( -256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 443 0 ) ( -768 443 0 ) ( -443 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 443 0 ) ( -768 314 256 ) ( -768 256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -314 314 256 ) ( -222 128 443 ) ( -128 222 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -314 314 256 ) ( -768 314 256 ) ( -222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 443 ) ( -768 128 443 ) ( -128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 443 ) ( -768 222 443 ) ( -314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 222 443 ) ( -768 128 443 ) ( -768 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -222 128 443 ) ( -222 128 768 ) ( -128 222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 443 ) ( -768 128 443 ) ( -222 128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 128 768 ) ( -768 128 768 ) ( -128 222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 768 ) ( -768 222 768 ) ( -128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 443 ) ( -768 222 443 ) ( -222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 222 768 ) ( -768 128 768 ) ( -768 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -222 128 443 ) ( 0 0 512 ) ( -128 222 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -222 128 443 ) ( -222 128 768 ) ( 0 0 512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 512 ) ( 0 0 768 ) ( -128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 443 ) ( -128 222 768 ) ( -222 128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 768 ) ( 0 0 768 ) ( -222 128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -256 443 0 ) ( -314 314 256 ) ( -115 428 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -256 443 0 ) ( -256 768 0 ) ( -314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 314 256 ) ( -314 768 256 ) ( -115 428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 428 256 ) ( -115 768 256 ) ( -256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 768 256 ) ( -314 768 256 ) ( -256 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -256 443 0 ) ( -768 443 0 ) ( -768 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 443 0 ) ( -256 768 0 ) ( -768 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 443 0 ) ( -768 768 0 ) ( -768 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 314 256 ) ( -768 768 256 ) ( -314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 314 256 ) ( -314 768 256 ) ( -256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 768 256 ) ( -768 768 0 ) ( -256 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -314 314 256 ) ( -128 222 443 ) ( -115 428 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -314 314 256 ) ( -314 768 256 ) ( -128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 443 ) ( -128 768 443 ) ( -115 428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 428 256 ) ( -115 768 256 ) ( -314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 768 256 ) ( -128 768 443 ) ( -314 768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -314 314 256 ) ( -768 314 256 ) ( -768 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 314 256 ) ( -314 768 256 ) ( -768 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 314 256 ) ( -768 768 256 ) ( -768 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 222 443 ) ( -768 768 443 ) ( -128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 443 ) ( -128 768 443 ) ( -314 314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 768 443 ) ( -768 768 256 ) ( -314 768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -128 222 443 ) ( -128 768 443 ) ( -768 768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 443 ) ( -128 222 768 ) ( -128 768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 768 443 ) ( -128 768 768 ) ( -768 768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 768 443 ) ( -768 768 768 ) ( -768 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 222 443 ) ( -768 222 768 ) ( -128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 768 768 ) ( -128 768 768 ) ( -128 222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -256 443 0 ) ( -115 428 256 ) ( 0 512 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -256 443 0 ) ( -256 768 0 ) ( -115 428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 428 256 ) ( -115 768 256 ) ( 0 512 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 512 0 ) ( 0 768 0 ) ( -256 443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 768 0 ) ( -115 768 256 ) ( -256 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -115 428 256 ) ( -128 222 443 ) ( 0 256 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -115 428 256 ) ( -115 768 256 ) ( -128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 443 ) ( -128 768 443 ) ( 0 256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 443 ) ( 0 768 443 ) ( -115 428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 768 443 ) ( -128 768 443 ) ( -115 768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -128 222 443 ) ( -128 222 768 ) ( 0 256 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 443 ) ( -128 768 443 ) ( -128 222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 222 768 ) ( -128 768 768 ) ( 0 256 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 768 ) ( 0 768 768 ) ( 0 256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 443 ) ( 0 768 443 ) ( -128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 768 768 ) ( -128 768 768 ) ( -128 768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -128 222 443 ) ( 0 0 512 ) ( 0 256 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -128 222 443 ) ( -128 222 768 ) ( 0 0 512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 512 ) ( 0 0 768 ) ( 0 256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 443 ) ( 0 256 768 ) ( -128 222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 768 ) ( 0 0 768 ) ( -128 222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 0 512 0 ) ( -115 428 256 ) ( 115 428 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 0 512 0 ) ( 0 768 0 ) ( -115 428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 428 256 ) ( -115 768 256 ) ( 115 428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 256 ) ( 115 768 256 ) ( 0 512 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 768 256 ) ( -115 768 256 ) ( 0 768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -115 428 256 ) ( 0 256 443 ) ( 115 428 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( -115 428 256 ) ( -115 768 256 ) ( 0 256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 256 443 ) ( 0 768 443 ) ( 115 428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 428 256 ) ( 115 768 256 ) ( -115 428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 115 768 256 ) ( 0 768 443 ) ( -115 768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -256 -768 0 ) ( -115 -768 256 ) ( 0 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 -443 0 ) ( -256 -768 0 ) ( 0 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 256 ) ( -115 -768 256 ) ( -256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -512 0 ) ( 0 -768 0 ) ( -115 -428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -512 0 ) ( -115 -428 256 ) ( -256 -443 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -128 -768 443 ) ( 0 -768 443 ) ( -115 -768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 443 ) ( -128 -768 443 ) ( -115 -428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 443 ) ( 0 -768 443 ) ( -128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 256 ) ( -115 -768 256 ) ( 0 -256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 256 ) ( 0 -256 443 ) ( -128 -222 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -128 -768 768 ) ( 0 -768 768 ) ( 0 -768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 443 ) ( -128 -768 443 ) ( 0 -256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 768 ) ( -128 -768 768 ) ( -128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 768 ) ( 0 -768 768 ) ( -128 -222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 443 ) ( 0 -768 443 ) ( 0 -256 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 443 ) ( 0 -256 768 ) ( -128 -222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -128 -222 768 ) ( 0 0 768 ) ( 0 -256 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 443 ) ( -128 -222 768 ) ( 0 -256 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 512 ) ( 0 0 768 ) ( -128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 443 ) ( 0 -256 768 ) ( 0 0 512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 -256 443 ) ( 0 0 512 ) ( -128 -222 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -314 -768 256 ) ( -115 -768 256 ) ( -256 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 256 ) ( -314 -768 256 ) ( -256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 256 ) ( -115 -768 256 ) ( -314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 -443 0 ) ( -256 -768 0 ) ( -115 -428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 -443 0 ) ( -115 -428 256 ) ( -314 -314 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -314 -768 256 ) ( -128 -768 443 ) ( -115 -768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 256 ) ( -314 -768 256 ) ( -115 -428 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 443 ) ( -128 -768 443 ) ( -314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 256 ) ( -115 -768 256 ) ( -128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -115 -428 256 ) ( -128 -222 443 ) ( -314 -314 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -443 -768 0 ) ( -314 -768 256 ) ( -256 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 -256 0 ) ( -443 -768 0 ) ( -256 -443 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 256 ) ( -314 -768 256 ) ( -443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 -443 0 ) ( -256 -768 0 ) ( -314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 -443 0 ) ( -314 -314 256 ) ( -443 -256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -222 -768 443 ) ( -128 -768 443 ) ( -314 -768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 443 ) ( -222 -768 443 ) ( -314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 443 ) ( -128 -768 443 ) ( -222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 256 ) ( -314 -768 256 ) ( -128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 256 ) ( -128 -222 443 ) ( -222 -128 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -222 -768 768 ) ( -128 -768 768 ) ( -128 -768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 443 ) ( -222 -768 443 ) ( -128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 768 ) ( -222 -768 768 ) ( -222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 768 ) ( -128 -768 768 ) ( -222 -128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 443 ) ( -128 -768 443 ) ( -128 -222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 443 ) ( -128 -222 768 ) ( -222 -128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -222 -128 768 ) ( 0 0 768 ) ( -128 -222 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 443 ) ( -222 -128 768 ) ( -128 -222 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 512 ) ( 0 0 768 ) ( -222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 443 ) ( -128 -222 768 ) ( 0 0 512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -128 -222 443 ) ( 0 0 512 ) ( -222 -128 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 -115 256 ) ( -768 -314 256 ) ( -768 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 256 ) ( -768 -115 256 ) ( -443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 256 ) ( -768 -314 256 ) ( -428 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 -256 0 ) ( -768 -256 0 ) ( -314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 -256 0 ) ( -314 -314 256 ) ( -428 -115 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 -768 256 ) ( -768 -768 0 ) ( -768 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 256 ) ( -768 -314 256 ) ( -443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -768 256 ) ( -768 -768 256 ) ( -314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 -768 0 ) ( -768 -768 0 ) ( -314 -768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 -256 0 ) ( -768 -256 0 ) ( -443 -768 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 -256 0 ) ( -443 -768 0 ) ( -314 -768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -768 -115 256 ) ( -768 -128 443 ) ( -768 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 256 ) ( -768 -115 256 ) ( -314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 443 ) ( -768 -128 443 ) ( -428 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 256 ) ( -768 -314 256 ) ( -222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 256 ) ( -222 -128 443 ) ( -428 -115 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 -768 443 ) ( -768 -768 256 ) ( -768 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 443 ) ( -768 -128 443 ) ( -314 -314 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -768 443 ) ( -768 -768 443 ) ( -222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -768 256 ) ( -768 -768 256 ) ( -222 -768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 256 ) ( -768 -314 256 ) ( -314 -768 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -314 -314 256 ) ( -314 -768 256 ) ( -222 -768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -768 -768 768 ) ( -768 -128 768 ) ( -222 -128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -768 443 ) ( -222 -768 768 ) ( -222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 -768 443 ) ( -768 -768 768 ) ( -222 -768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -768 -128 443 ) ( -768 -128 768 ) ( -768 -768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 443 ) ( -222 -128 768 ) ( -768 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 443 ) ( -768 -128 443 ) ( -768 -768 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -768 0 0 ) ( -768 -115 256 ) ( -768 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -512 0 0 ) ( -768 0 0 ) ( -443 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 256 ) ( -768 -115 256 ) ( -512 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 -256 0 ) ( -768 -256 0 ) ( -428 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -443 -256 0 ) ( -428 -115 256 ) ( -512 0 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 0 443 ) ( -768 -128 443 ) ( -768 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 443 ) ( -768 0 443 ) ( -428 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 443 ) ( -768 -128 443 ) ( -256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 256 ) ( -768 -115 256 ) ( -222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 256 ) ( -222 -128 443 ) ( -256 0 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 0 768 ) ( -768 -128 768 ) ( -768 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 443 ) ( -768 0 443 ) ( -222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 768 ) ( -768 0 768 ) ( -256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 768 ) ( -768 -128 768 ) ( -256 0 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 443 ) ( -768 -128 443 ) ( -222 -128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 443 ) ( -222 -128 768 ) ( -256 0 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( -256 0 768 ) ( 0 0 768 ) ( -222 -128 768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 443 ) ( -256 0 768 ) ( -222 -128 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 0 0 512 ) ( 0 0 768 ) ( -256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 443 ) ( -222 -128 768 ) ( 0 0 512 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -222 -128 443 ) ( 0 0 512 ) ( -256 0 443 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 115 256 ) ( -768 -115 256 ) ( -768 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 115 256 ) ( -768 115 256 ) ( -512 0 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 256 ) ( -768 -115 256 ) ( -428 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -512 0 0 ) ( -768 0 0 ) ( -428 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -512 0 0 ) ( -428 -115 256 ) ( -428 115 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( -768 115 256 ) ( -768 0 443 ) ( -768 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 115 256 ) ( -768 115 256 ) ( -428 -115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -256 0 443 ) ( -768 0 443 ) ( -428 115 256 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 256 ) ( -768 -115 256 ) ( -256 0 443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -428 -115 256 ) ( -256 0 443 ) ( -428 115 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 1024 768 -768 ) ( 768 768 -768 ) ( 768 -128 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 832 -128 768 ) ( 832 768 768 ) ( 1088 768 768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 704 -768 0 ) ( 960 -768 0 ) ( 960 -768 -256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 776 -128 0 ) ( 776 768 0 ) ( 776 768 -256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 1024 768 0 ) ( 768 768 0 ) ( 768 768 -256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 768 768 0 ) ( 768 -128 0 ) ( 768 -128 -256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 768 -768 -768 ) ( -768 -768 -768 ) ( -768 -832 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -768 -832 768 ) ( -768 -768 768 ) ( 768 -768 768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -768 -776 760 ) ( 768 -776 760 ) ( 768 -776 -776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 768 -832 768 ) ( 768 -768 768 ) ( 768 -768 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 768 -768 768 ) ( -768 -768 768 ) ( -768 -768 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -768 -768 768 ) ( -768 -832 768 ) ( -768 -832 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -768 768 -768 ) ( -1088 768 -768 ) ( -1088 -768 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -1088 -768 768 ) ( -1088 768 768 ) ( -768 768 768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -1088 -768 768 ) ( -768 -768 768 ) ( -768 -768 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -768 -768 768 ) ( -768 768 768 ) ( -768 768 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -768 768 768 ) ( -1088 768 768 ) ( -1088 768 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -776 704 768 ) ( -776 -832 768 ) ( -776 -832 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 768 1088 -768 ) ( -768 1088 -768 ) ( -768 768 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -768 768 768 ) ( -768 1088 768 ) ( 768 1088 768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -768 768 768 ) ( 768 768 768 ) ( 768 768 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 768 768 768 ) ( 768 1088 768 ) ( 768 1088 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 832 776 768 ) ( -704 776 768 ) ( -704 776 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -768 1088 768 ) ( -768 768 768 ) ( -768 768 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 768 768 768 ) ( -768 768 768 ) ( -768 -768 768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -744 -704 776 ) ( -744 832 776 ) ( 792 832 776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -768 -768 1344 ) ( 768 -768 1344 ) ( 768 -768 768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 768 -768 1344 ) ( 768 768 1344 ) ( 768 768 768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 768 768 1344 ) ( -768 768 1344 ) ( -768 768 768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -768 768 1344 ) ( -768 -768 1344 ) ( -768 -768 768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 768 768 -776 ) ( -768 768 -776 ) ( -768 -768 -776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -768 -768 -768 ) ( -768 768 -768 ) ( 768 768 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -768 -768 -768 ) ( 768 -768 -768 ) ( 768 -768 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 768 -768 -768 ) ( 768 768 -768 ) ( 768 768 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 768 768 -768 ) ( -768 768 -768 ) ( -768 768 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -768 768 -768 ) ( -768 -768 -768 ) ( -768 -768 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+}
+{
+"origin" "-64 0 -384"
+"classname" "info_player_deathmatch"
+}
+{
+"light" "1000"
+"origin" "0 0 64"
+"classname" "light"
+}
diff --git a/regression_tests/q3map2/coarse_snap_normal/README.txt b/regression_tests/q3map2/coarse_snap_normal/README.txt
new file mode 100644 (file)
index 0000000..6525380
--- /dev/null
@@ -0,0 +1,16 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+Because of the coarse nature of SnapNormal(), planes that are 0.25 degrees
+away from being axial are "snapped" to be axial.  The "normal epsilon"
+is a very small value by default, and cannot go much smaller (without
+running into limits of floating point numbers).  The problem with
+SnapNormal() is that we compare the components of the normal that are near
+1, instead of comaring the components that are near 0.  This leads to a very
+coarse and inaccurate SnapNormal().
+
+If you open the example map in Radiant, you can see that the red brick should
+touch the middle checkered brick at the edge.  However, once this map is
+compiled, the edges are a significant distance apart.  This is due to the
+coarse and inaccurate nature of SnapNormal().  Likewise, the green brick should
+be flush with the center tiled brick, but it's not.
diff --git a/regression_tests/q3map2/coarse_snap_normal/maps/coarse_snap_normal.map b/regression_tests/q3map2/coarse_snap_normal/maps/coarse_snap_normal.map
new file mode 100644 (file)
index 0000000..9be4523
--- /dev/null
@@ -0,0 +1,84 @@
+{
+"classname" "worldspawn"
+{
+( 544 312 -8 ) ( -584 312 -8 ) ( -584 -488 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -576 -488 0 ) ( -576 312 0 ) ( 552 312 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -584 -512 8 ) ( 544 -512 8 ) ( 544 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -488 8 ) ( 512 312 8 ) ( 512 312 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 528 512 8 ) ( -600 512 8 ) ( -600 512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 312 8 ) ( -512 -488 8 ) ( -512 -488 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 720 512 0 ) ( 512 512 0 ) ( 512 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -512 512 ) ( 512 512 512 ) ( 720 512 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -512 512 ) ( 720 -512 512 ) ( 720 -512 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 520 -512 520 ) ( 520 512 520 ) ( 520 512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 720 512 512 ) ( 512 512 512 ) ( 512 512 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 512 512 ) ( 512 -512 512 ) ( 512 -512 -8 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( -512 512 0 ) ( -592 512 0 ) ( -592 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -592 -512 512 ) ( -592 512 512 ) ( -512 512 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -592 -512 512 ) ( -512 -512 512 ) ( -512 -512 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -512 512 ) ( -512 512 512 ) ( -512 512 -8 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -512 512 512 ) ( -592 512 512 ) ( -592 512 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -520 512 536 ) ( -520 -512 536 ) ( -520 -512 16 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 512 512 512 ) ( -512 512 512 ) ( -512 -512 512 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -488 -512 520 ) ( -488 512 520 ) ( 536 512 520 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -512 664 ) ( 512 -512 664 ) ( 512 -512 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -512 664 ) ( 512 512 664 ) ( 512 512 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 512 664 ) ( -512 512 664 ) ( -512 512 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 512 664 ) ( -512 -512 664 ) ( -512 -512 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 512 608 0 ) ( -512 608 0 ) ( -512 520 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 520 512 ) ( -512 608 512 ) ( 512 608 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 512 512 ) ( 512 512 512 ) ( 512 512 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 512 520 512 ) ( 512 608 512 ) ( 512 608 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 520 520 ) ( -512 520 520 ) ( -512 520 8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 608 512 ) ( -512 520 512 ) ( -512 520 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 512 -512 0 ) ( -512 -512 0 ) ( -512 -600 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -600 512 ) ( -512 -512 512 ) ( 512 -512 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -520 520 ) ( 512 -520 520 ) ( 512 -520 8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -600 512 ) ( 512 -512 512 ) ( 512 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -512 512 ) ( -512 -512 512 ) ( -512 -512 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -512 -512 512 ) ( -512 -600 512 ) ( -512 -600 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 512 72 64 ) ( -512 72 64 ) ( -512 -448 64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -128 448 260 ) ( 192 448 260 ) ( 192 -448 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -512 -448 256 ) ( 512 -448 256 ) ( 512 -448 56 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 192 -440 256 ) ( 192 80 256 ) ( 192 80 56 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 192 448 260 ) ( -128 448 260 ) ( -128 448 64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -128 56 256 ) ( -128 -464 256 ) ( -128 -464 56 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 192 -448 232 ) ( -128 -448 232 ) ( -128 -472 232 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( -128 -472 256 ) ( -128 -448 256 ) ( 192 -448 256 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( -128 -472 256 ) ( 192 -472 256 ) ( 192 -472 232 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( 192 -472 256 ) ( 192 -448 256 ) ( 192 -448 232 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( 192 -448 256 ) ( -128 -448 256 ) ( -128 -448 232 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( -128 -448 256 ) ( -128 -472 256 ) ( -128 -472 232 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 192 472 260 ) ( -128 472 260 ) ( -128 448 260 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+( -128 448 280 ) ( -128 472 280 ) ( 192 472 280 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+( -128 448 280 ) ( 192 448 280 ) ( 192 448 256 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+( 192 448 280 ) ( 192 472 280 ) ( 192 472 256 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+( 192 472 280 ) ( -128 472 280 ) ( -128 472 256 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+( -128 472 280 ) ( -128 448 280 ) ( -128 448 256 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+}
+}
+{
+"light" "3000"
+"origin" "0 0 384"
+"classname" "light"
+}
+{
+"origin" "0 -64 384"
+"classname" "info_player_deathmatch"
+}
diff --git a/regression_tests/q3map2/decal_misalignment/README.txt b/regression_tests/q3map2/decal_misalignment/README.txt
new file mode 100644 (file)
index 0000000..f9aa3d6
--- /dev/null
@@ -0,0 +1,16 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+The info_null in the map for the decal is not 100% below the center of the
+decal itself, because to be totally below it would have to lie on half-units.
+So, the info_null lies almost directly below the center of the decal.  In
+this particular case, all kinds of bad things happen to the decal.  For one,
+during compiling we get warnings like this:
+
+  Bad texture matrix! (B) (50.512253, -49.515625) != (50.484375, -49.515625)
+  Bad texture matrix! (C) (48.723190, -49.522587) != (48.695312, -49.515625)
+  Bad texture matrix! (B) (48.723186, -49.522587) != (48.695312, -49.515625)
+
+If you look at where the decal (it's just a blue translucent tile texture)
+meets the far wall, it's clearly not aligned correctly.  The tile on the decal
+and the tile on the wall should align perfectly, and it's quite a bit off.
diff --git a/regression_tests/q3map2/decal_misalignment/maps/decal_misalignment.map b/regression_tests/q3map2/decal_misalignment/maps/decal_misalignment.map
new file mode 100644 (file)
index 0000000..b764bf2
--- /dev/null
@@ -0,0 +1,89 @@
+{
+"classname" "worldspawn"
+{
+( 6472 6336 -960 ) ( 6288 6336 -960 ) ( 6288 6320 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6264 6320 -576 ) ( 6264 6336 -576 ) ( 6448 6336 -576 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6280 6328 -832 ) ( 6464 6328 -832 ) ( 6464 6328 -848 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6464 6320 -832 ) ( 6464 6336 -832 ) ( 6464 6336 -848 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6464 6336 -832 ) ( 6280 6336 -832 ) ( 6280 6336 -848 ) radiant_regression_tests/bigtile 0 0 0 0.500000 0.500000 0 0 0
+( 6144 6336 -832 ) ( 6144 6320 -832 ) ( 6144 6320 -848 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6552 6520 -960 ) ( 6464 6520 -960 ) ( 6464 6336 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6464 6336 -576 ) ( 6464 6520 -576 ) ( 6552 6520 -576 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6464 6336 -576 ) ( 6552 6336 -576 ) ( 6552 6336 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6472 6344 -576 ) ( 6472 6528 -576 ) ( 6472 6528 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6528 7360 -576 ) ( 6440 7360 -576 ) ( 6440 7360 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6464 6520 -576 ) ( 6464 6336 -576 ) ( 6464 6336 -960 ) radiant_regression_tests/bigtile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 6464 7424 -960 ) ( 6144 7424 -960 ) ( 6144 7360 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 7360 -576 ) ( 6144 7424 -576 ) ( 6464 7424 -576 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 7360 -576 ) ( 6464 7360 -576 ) ( 6464 7360 -960 ) radiant_regression_tests/bigtile 0 0 0 0.500000 0.500000 0 0 0
+( 6464 7360 -576 ) ( 6464 7424 -576 ) ( 6464 7424 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6464 7368 -576 ) ( 6144 7368 -576 ) ( 6144 7368 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 7424 -576 ) ( 6144 7360 -576 ) ( 6144 7360 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6144 7360 -960 ) ( 5880 7360 -960 ) ( 5880 6808 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 5880 6808 -576 ) ( 5880 7360 -576 ) ( 6144 7360 -576 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 5864 6336 -576 ) ( 6128 6336 -576 ) ( 6128 6336 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 6808 -576 ) ( 6144 7360 -576 ) ( 6144 7360 -960 ) radiant_regression_tests/bigtile 0 0 0 0.500000 0.500000 0 0 0
+( 6144 7360 -576 ) ( 5880 7360 -576 ) ( 5880 7360 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6136 7384 -576 ) ( 6136 6832 -576 ) ( 6136 6832 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6456 7360 -968 ) ( 6136 7360 -968 ) ( 6136 6336 -968 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 6336 -960 ) ( 6144 7360 -960 ) ( 6464 7360 -960 ) radiant_regression_tests/bigtile 0 0 0 0.500000 0.500000 0 0 0
+( 6144 6336 -960 ) ( 6464 6336 -960 ) ( 6464 6336 -1008 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6464 6336 -960 ) ( 6464 7360 -960 ) ( 6464 7360 -1008 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6464 7360 -960 ) ( 6144 7360 -960 ) ( 6144 7360 -1008 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 7360 -960 ) ( 6144 6336 -960 ) ( 6144 6336 -1008 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6464 7360 -576 ) ( 6152 7360 -576 ) ( 6152 6336 -576 ) radiant_regression_tests/bigtile 0 0 0 0.500000 0.500000 0 0 0
+( 6176 6336 -568 ) ( 6176 7360 -568 ) ( 6488 7360 -568 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6152 6336 -472 ) ( 6464 6336 -472 ) ( 6464 6336 -576 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6464 6336 -472 ) ( 6464 7360 -472 ) ( 6464 7360 -576 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6464 7360 -472 ) ( 6152 7360 -472 ) ( 6152 7360 -576 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 7360 -472 ) ( 6144 6336 -472 ) ( 6144 6336 -576 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6200 7360 -896 ) ( 6200 6336 -896 ) ( 6592 6336 -896 ) radiant_regression_tests/glass 0 0 0 0.500000 0.500000 134217728 257 0
+( 6360 6336 -832 ) ( 6360 7256 -832 ) ( 6464 7256 -832 ) radiant_regression_tests/glass 0 0 0 0.500000 0.500000 134217728 257 0
+( 6208 6337 -832 ) ( 6400 6337 -832 ) ( 6400 6337 -896 ) radiant_regression_tests/glass 0 0 0 0.500000 0.500000 134217728 257 0
+( 6463 6336 -816 ) ( 6463 7360 -816 ) ( 6463 7360 -880 ) radiant_regression_tests/glass 0 0 0 0.500000 0.500000 134217728 257 0
+( 6232 7264 -896 ) ( 6232 7264 -832 ) ( 6232 6337 -896 ) radiant_regression_tests/glass 0 0 0 0.500000 0.500000 134217728 257 0
+( 6232 7256 -832 ) ( 6232 7256 -896 ) ( 6463 7256 -832 ) radiant_regression_tests/glass 0 0 0 0.500000 0.500000 134217728 257 0
+}
+}
+{
+"target" "checker"
+"classname" "_decal"
+{
+patchDef2
+{
+radiant_regression_tests/tile_trans
+( 3 3 0 0 0 )
+(
+( ( 6462 7255 -832 50.484375 -56.679688 ) ( 6462 6796.500000 -832 50.484375 -53.097656 ) ( 6462 6338 -832 50.484375 -49.515625 ) )
+( ( 6347.500000 7255 -832 49.589844 -56.679688 ) ( 6347.500000 6796.500000 -832 49.589844 -53.097656 ) ( 6347.500000 6338 -832 49.589844 -49.515625 ) )
+( ( 6233 7255 -832 48.695312 -56.679688 ) ( 6233 6796.500000 -832 48.695312 -53.097656 ) ( 6233 6338 -832 48.695312 -49.515625 ) )
+)
+}
+}
+}
+{
+"targetname" "checker"
+"origin" "6347 6796 -840"
+"classname" "info_null"
+}
+{
+"origin" "6288 6704 -712"
+"classname" "info_player_deathmatch"
+}
+{
+"light" "2000"
+"origin" "6304 6792 -704"
+"classname" "light"
+}
diff --git a/regression_tests/q3map2/decal_misalignment/scripts/radiant_regression_tests.shader b/regression_tests/q3map2/decal_misalignment/scripts/radiant_regression_tests.shader
new file mode 100644 (file)
index 0000000..af31c07
--- /dev/null
@@ -0,0 +1,29 @@
+textures/radiant_regression_tests/tile_trans
+{
+    qer_trans 0.9
+    q3map_bounceScale 0.0
+    surfaceparm trans
+    cull disable
+    polygonOffset
+    {
+        map textures/radiant_regression_tests/tile_trans.tga
+        blendFunc blend
+        alphaGen const 1
+    }
+}
+
+textures/radiant_regression_tests/glass
+{
+    qer_editorImage textures/radiant_regression_tests/qer_glass.tga
+    qer_trans 0.6
+    q3map_bounceScale 0.0
+    surfaceparm nolightmap
+    surfaceparm detail
+    surfaceparm trans
+    cull disable
+    {
+        map textures/radiant_regression_tests/glass.tga
+        blendFunc add
+        tcGen environment
+    }
+}
diff --git a/regression_tests/q3map2/degenerate_winding/README.txt b/regression_tests/q3map2/degenerate_winding/README.txt
new file mode 100644 (file)
index 0000000..b060d08
--- /dev/null
@@ -0,0 +1,4 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+I'm testing when windings become degenerate.
diff --git a/regression_tests/q3map2/degenerate_winding/maps/degenerate_winding.map b/regression_tests/q3map2/degenerate_winding/maps/degenerate_winding.map
new file mode 100644 (file)
index 0000000..808de18
--- /dev/null
@@ -0,0 +1,68 @@
+{
+"classname" "worldspawn"
+{
+( 256 256 -8 ) ( -256 256 -8 ) ( -256 -264 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 -264 0 ) ( -256 256 0 ) ( 256 256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -256 -256 8 ) ( 256 -256 8 ) ( 256 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 -264 8 ) ( 256 256 8 ) ( 256 256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 256 8 ) ( -256 256 8 ) ( -256 256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 256 8 ) ( -256 -264 8 ) ( -256 -264 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 296 256 0 ) ( 256 256 0 ) ( 256 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 280 -256 512 ) ( 280 256 512 ) ( 320 256 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 -256 392 ) ( 296 -256 392 ) ( 296 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 264 -256 384 ) ( 264 256 384 ) ( 264 256 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 296 256 392 ) ( 256 256 392 ) ( 256 256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 256 392 ) ( 256 -256 392 ) ( 256 -256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( -256 256 0 ) ( -320 256 0 ) ( -320 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -320 -256 512 ) ( -320 256 512 ) ( -256 256 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -320 -256 504 ) ( -256 -256 504 ) ( -256 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 -256 504 ) ( -256 256 504 ) ( -256 256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -256 256 504 ) ( -320 256 504 ) ( -320 256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -264 256 496 ) ( -264 -256 496 ) ( -264 -256 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 256 256 512 ) ( -256 256 512 ) ( -256 -256 512 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -224 -256 520 ) ( -224 256 520 ) ( 288 256 520 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 -256 584 ) ( 256 -256 584 ) ( 256 -256 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 -256 584 ) ( 256 256 584 ) ( 256 256 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 256 584 ) ( -256 256 584 ) ( -256 256 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 256 584 ) ( -256 -256 584 ) ( -256 -256 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 256 328 0 ) ( -256 328 0 ) ( -256 256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 256 512 ) ( -256 328 512 ) ( 256 328 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 256 512 ) ( 256 256 512 ) ( 256 256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 256 256 512 ) ( 256 328 512 ) ( 256 328 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 264 536 ) ( -256 264 536 ) ( -256 264 24 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 328 512 ) ( -256 256 512 ) ( -256 256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 256 -256 0 ) ( -256 -256 0 ) ( -256 -304 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 -304 512 ) ( -256 -256 512 ) ( 256 -256 512 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 -264 520 ) ( 256 -264 520 ) ( 256 -264 8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 -304 512 ) ( 256 -256 512 ) ( 256 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 -256 512 ) ( -256 -256 512 ) ( -256 -256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -256 -256 512 ) ( -256 -304 512 ) ( -256 -304 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 64 0 128 ) ( 8 0 128 ) ( 8 -8 128 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+( 8 -8 464 ) ( 8 0 464 ) ( 64 0 464 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+( -240 8 464 ) ( -240 0 464 ) ( -240 0 160 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+( -240 24 128 ) ( 160 8 128 ) ( -240 24 464 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( 160 8 128 ) ( -240 0 128 ) ( 160 8 464 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( 159 11 128 ) ( 159 0 128 ) ( 159 11 464 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+}
+}
+{
+"light" "1000"
+"origin" "-40 0 32"
+"classname" "light"
+}
+{
+"origin" "-40 128 96"
+"classname" "info_player_deathmatch"
+}
diff --git a/regression_tests/q3map2/degenerate_winding2/README.txt b/regression_tests/q3map2/degenerate_winding2/README.txt
new file mode 100644 (file)
index 0000000..b36f2db
--- /dev/null
@@ -0,0 +1,14 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+The sample map contains a wedge brush.  The tip (the sharp edge) of the wedge
+is chopped off by 2 planes, leaving very narrow windings.  Each of these 2
+narrow windings is less than 0.1 units tall.  However, the wedge has height
+exactly equal to 1/8 unit at the point where it is chopped.  Therefore,
+the two narrow sides caused by the chops are expected to be degenerate and the
+top face of the wedge is expected to be unaffected.  This should leave a
+"hole" in the narrow part of the wedge.
+
+The hole isn't desirable but it's expected based on the logic in the code.
+Still, if there is a hole in the brush, I consider this regression test to
+be broken.
diff --git a/regression_tests/q3map2/degenerate_winding2/maps/degenerate_winding2.map b/regression_tests/q3map2/degenerate_winding2/maps/degenerate_winding2.map
new file mode 100644 (file)
index 0000000..70abf7c
--- /dev/null
@@ -0,0 +1,69 @@
+{
+"classname" "worldspawn"
+{
+( 7 0 0 ) ( 7 0 1 ) ( 7 64 1 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( 7 0 0 ) ( 7 64 0 ) ( -1 64 0 ) radiant_regression_tests/blue 0 0 0 0.500000 0.500000 0 0 0
+( 7 0 1 ) ( 7 0 0 ) ( -1 0 0 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( -1 64 0 ) ( 7 64 0 ) ( 7 64 1 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( 7 0 1 ) ( -1 0 0 ) ( -1 64 0 ) radiant_regression_tests/blue 0 0 0 0.500000 0.500000 0 0 0
+( -1 0 2 ) ( 0 0 0 ) ( 0 64 0 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+( 1 0 2 ) ( -7 0 -13 ) ( -7 64 -13 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 128 72 -72 ) ( -128 72 -72 ) ( -128 8 -72 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -128 120 -64 ) ( -128 184 -64 ) ( 128 184 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -128 -128 -64 ) ( 128 -128 -64 ) ( 128 -128 -72 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 0 -64 ) ( 192 64 -64 ) ( 192 64 -72 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 128 192 -64 ) ( -128 192 -64 ) ( -128 192 -72 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 64 -64 ) ( -192 0 -64 ) ( -192 0 -72 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 256 192 -64 ) ( 192 192 -64 ) ( 192 -128 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 -128 256 ) ( 192 192 256 ) ( 256 192 256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 -128 256 ) ( 256 -128 256 ) ( 256 -128 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 200 -128 240 ) ( 200 192 240 ) ( 200 192 -80 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 192 256 ) ( 192 192 256 ) ( 192 192 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 192 256 ) ( 192 -128 256 ) ( 192 -128 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( -192 192 -64 ) ( -280 192 -64 ) ( -280 -128 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -280 -128 256 ) ( -280 192 256 ) ( -192 192 256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -280 -128 256 ) ( -192 -128 256 ) ( -192 -128 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 -128 256 ) ( -192 192 256 ) ( -192 192 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -192 192 256 ) ( -280 192 256 ) ( -280 192 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -200 192 256 ) ( -200 -128 256 ) ( -200 -128 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 192 192 256 ) ( -192 192 256 ) ( -192 -128 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -176 -128 264 ) ( -176 192 264 ) ( 208 192 264 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 -128 304 ) ( 192 -128 304 ) ( 192 -128 248 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 -128 304 ) ( 192 192 304 ) ( 192 192 248 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 192 304 ) ( -192 192 304 ) ( -192 192 248 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 192 304 ) ( -192 -128 304 ) ( -192 -128 248 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 192 272 -64 ) ( -192 272 -64 ) ( -192 192 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 192 256 ) ( -192 272 256 ) ( 192 272 256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 192 256 ) ( 192 192 256 ) ( 192 192 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 192 192 256 ) ( 192 272 256 ) ( 192 272 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 200 256 ) ( -192 200 256 ) ( -192 200 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 272 256 ) ( -192 192 256 ) ( -192 192 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 192 -128 -64 ) ( -192 -128 -64 ) ( -192 -192 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 -192 256 ) ( -192 -128 256 ) ( 192 -128 256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 -136 280 ) ( 192 -136 280 ) ( 192 -136 -40 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 -192 256 ) ( 192 -128 256 ) ( 192 -128 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 -128 256 ) ( -192 -128 256 ) ( -192 -128 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -192 -128 256 ) ( -192 -192 256 ) ( -192 -192 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+}
+{
+"light" "1000"
+"origin" "-8 40 128"
+"classname" "light"
+}
+{
+"origin" "-112 -40 40"
+"classname" "info_player_deathmatch"
+}
diff --git a/regression_tests/q3map2/degenerate_winding3/README.txt b/regression_tests/q3map2/degenerate_winding3/README.txt
new file mode 100644 (file)
index 0000000..3aa08fc
--- /dev/null
@@ -0,0 +1,18 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+The sample map contains a wedge brush.  The tip (the sharp edge) of the wedge
+is chopped off by the YZ plane (side 5, or the last side, of the brush).
+The height of the wedge where it is chopped is about 0.9.  This makes it
+barely smaller than DEGENERATE_EPSILON.  So the face resulting from the chop
+is probably degenerate, and that winding will be removed.  I'm now wondering
+what happens to the rest of the brush.  0.9 rounded to the nearest 1/8 unit
+is 1/8, so the top face of the brush should get a slight raise, making the
+"hole" even bigger.  The sides will have degenerate edges near the chop, so
+they will become triangles, creating open slivers in the sides.
+
+Although this behavior is a tad nasty, it is expected based on the way the
+code is written.  I want to make sure nothing really nasty happens.
+
+I consider this regression test to be broken if there is a "hole" in the brush,
+and I consider this test to be very broken if something more drastic happens.
diff --git a/regression_tests/q3map2/degenerate_winding3/maps/degenerate_winding3.map b/regression_tests/q3map2/degenerate_winding3/maps/degenerate_winding3.map
new file mode 100644 (file)
index 0000000..1817265
--- /dev/null
@@ -0,0 +1,68 @@
+{
+"classname" "worldspawn"
+{
+( 10 0 0 ) ( 10 0 1 ) ( 10 64 1 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( 10 0 0 ) ( 10 64 0 ) ( -1 64 0 ) radiant_regression_tests/blue 0 0 0 0.500000 0.500000 0 0 0
+( 10 0 1 ) ( 10 0 0 ) ( -1 0 0 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( -1 64 0 ) ( 10 64 0 ) ( 10 64 1 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( 10 0 1 ) ( -1 0 0 ) ( -1 64 0 ) radiant_regression_tests/blue 0 0 0 0.500000 0.500000 0 0 0
+( 0 0 1 ) ( 0 0 0 ) ( 0 64 0 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 128 72 -72 ) ( -128 72 -72 ) ( -128 8 -72 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -128 120 -64 ) ( -128 184 -64 ) ( 128 184 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -128 -128 -64 ) ( 128 -128 -64 ) ( 128 -128 -72 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 0 -64 ) ( 192 64 -64 ) ( 192 64 -72 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 128 192 -64 ) ( -128 192 -64 ) ( -128 192 -72 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 64 -64 ) ( -192 0 -64 ) ( -192 0 -72 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 256 192 -64 ) ( 192 192 -64 ) ( 192 -128 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 -128 256 ) ( 192 192 256 ) ( 256 192 256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 -128 256 ) ( 256 -128 256 ) ( 256 -128 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 200 -128 240 ) ( 200 192 240 ) ( 200 192 -80 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 192 256 ) ( 192 192 256 ) ( 192 192 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 192 256 ) ( 192 -128 256 ) ( 192 -128 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( -192 192 -64 ) ( -280 192 -64 ) ( -280 -128 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -280 -128 256 ) ( -280 192 256 ) ( -192 192 256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -280 -128 256 ) ( -192 -128 256 ) ( -192 -128 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 -128 256 ) ( -192 192 256 ) ( -192 192 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -192 192 256 ) ( -280 192 256 ) ( -280 192 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -200 192 256 ) ( -200 -128 256 ) ( -200 -128 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 192 192 256 ) ( -192 192 256 ) ( -192 -128 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -176 -128 264 ) ( -176 192 264 ) ( 208 192 264 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 -128 304 ) ( 192 -128 304 ) ( 192 -128 248 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 -128 304 ) ( 192 192 304 ) ( 192 192 248 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 192 304 ) ( -192 192 304 ) ( -192 192 248 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 192 304 ) ( -192 -128 304 ) ( -192 -128 248 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 192 272 -64 ) ( -192 272 -64 ) ( -192 192 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 192 256 ) ( -192 272 256 ) ( 192 272 256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 192 256 ) ( 192 192 256 ) ( 192 192 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 192 192 256 ) ( 192 272 256 ) ( 192 272 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 200 256 ) ( -192 200 256 ) ( -192 200 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 272 256 ) ( -192 192 256 ) ( -192 192 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 192 -128 -64 ) ( -192 -128 -64 ) ( -192 -192 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 -192 256 ) ( -192 -128 256 ) ( 192 -128 256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -192 -136 280 ) ( 192 -136 280 ) ( 192 -136 -40 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 -192 256 ) ( 192 -128 256 ) ( 192 -128 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 192 -128 256 ) ( -192 -128 256 ) ( -192 -128 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -192 -128 256 ) ( -192 -192 256 ) ( -192 -192 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+}
+{
+"light" "1000"
+"origin" "-8 40 128"
+"classname" "light"
+}
+{
+"origin" "-112 -40 40"
+"classname" "info_player_deathmatch"
+}
diff --git a/regression_tests/q3map2/disappearing_sliver/README.txt b/regression_tests/q3map2/disappearing_sliver/README.txt
new file mode 100644 (file)
index 0000000..a65d920
--- /dev/null
@@ -0,0 +1,183 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+The example map, maps/disappearing_sliver.map, contains an example of this bug.
+There are 6 walls in the map, and one tall thin triangular sliver brush in the
+middle of the room (7 brushes total).  Only one face of the sliver in the
+middle of the room is a draw surface.  The bug is that this sliver surface is
+not rendered in the compiled BSP.  Note that the sliver brush was hand-crafted
+to demonstrate the bug.  If you re-save the map, Radiant might adjust the
+order in which the planes on the brush are defined, and this might, as a side
+effect, get rid of the immediate bug.
+
+To trigger the bug, compile the map; you don't need -vis or -light.  Only
+-bsp (the first q3map2 stage) is necessary to trigger the bug.  The only
+entities in the map are 2 lights and a single info_player_deathmatch, so the
+map will compile for any Q3 mod.
+
+
+SOLUTION TO PROBLEM:
+====================
+
+Several days were spent studying this problem in great detail.
+
+The fix for this problem was to make the outcome of the VectorNormalize()
+function libs/mathlib/mathlib.c more accurate.  The previous code in this
+function looks something like this:
+
+  vec_t length, ilength; // vec_t is a typedef for 32 bit float.
+
+  /* Compute length */
+
+  ilength = 1.0f/length;
+  out[0] = in[0]*ilength;
+  out[1] = in[1]*ilength;
+  out[2] = in[2]*ilength;
+
+As you can see, we are introducing a lot of extra error into our normalized
+vector by multiplying by the reciprocal length instead of outright dividing
+by the length.  The new fixed code looks like this:
+
+  out[0] = in[0]/length;
+  out[1] = in[1]/length;
+  out[2] = in[2]/length;
+
+And we get rid of the recpirocal length ilength altogether.  Even the
+slightest math errors are magnified in successive calls to linear algebra
+functions.
+
+The change described above was commmitted to GtkRadiant trunk as revision 363.
+
+
+POSSIBLE SIDE EFFECTS:
+======================
+
+The only negative side effect is that compilation of a map might take longer
+due to an increased number of divide operations.  (I'm actually not sure if
+that is indeed the case.)  Another side effect might be that if you're used
+to a map being broken (missing triangles) or having "sparklies" between
+brushes, those might be gone now.  :-)
+
+
+IN-DEPTH DISCUSSION:
+====================
+
+VectorNormalize() is used very frequently in Radiant and tools code.  My goal
+for this fix was to make the least amount of code change but still be able to
+demonstrate a significant improvement in math accuracy (including a fix to
+the test case).  At the same time don't risk that any other bugs pop up as a
+side effect of this change.
+
+Here is the sequence of calls (stack trace) that cause the example bug to
+happen:
+
+  main() in main.c -->
+    BSPMain() in bsp.c -->
+      LoadMapFile() in map.c -->
+        ParseMapEntity() in map.c -->
+          ParseBrush() in map.c -->
+            FinishBrush() in map.c -->
+              CreateBrushWindings() in brush.c -->
+                ChopWindingInPlace() in polylib.c
+
+What basically happens in this sequence of calls is that a brush is parsed
+out of the map file, "infinite" planes are created for each brush face, and
+then the planes are "intersected" to find the exact vertex topologies of each
+brush face.  The vertex topology of the visible face of the sliver (in the
+example map) gets computed with a significant amount of math error.  If we
+did our math with infinite precision, the sliver face would have the following
+vertices:
+
+  (67 -1022 0)
+  (88 -892 -768)
+  (134 -1015 0)
+
+In fact, if you open the map file (disappearing_sliver.map), you can actually
+see these exact points embedded in the third plane defined on brush 0.
+
+I managed to print out the actual computed vertices of the sliver face before
+and after this bug fix.  Basically this is printed out after all the
+ChopWindingInPlace() calls in the above stack trace:
+
+  (66.984695 -1021.998657 0.000000)
+  (87.989571 -891.969116 -768.174316)
+  (133.998917 -1014.997314 0.000000)
+
+(If you want to print this out for yourself, use winding_logging.patch.)
+
+The same vertices after the bugfix have the following coordinates:
+
+  (67.000229 -1021.998657 0.000000)
+  (88.000175 -891.999146 -767.997437)
+  (133.999146 -1014.998779 0.000000)
+
+As you can see, the vertices after the fix are substantially more accurate,
+and all it took was an improvement to VectorNormalize().
+
+The problem before the fix was the Z coordinate of the second point, namely
+-768.174316.  There is a lot of "snap to nearest 1/8 unit" and "epsilon 0.1"
+code used throughout q3map2.  0.174 is greater than the 0.1 epsilon, and that
+is the problem.
+
+  main() in main.c -->
+    BSPMain() in bsp.c -->
+      ProcessModels() in bsp.c -->
+        ProcessWorldModel() in bsp.c -->
+          ClipSidesIntoTree() in surface.c -->
+            ClipSideIntoTree_r() in surface.c -->
+              ClipWindingEpsilon() in polylib.c
+
+Now what ClipWindingEpsilon() does is, since -768.174316 reaches below the
+plane z = -768 (and over the 0.1 epsilon), it clips the winding_t and creates
+two points where there used to be only one.
+
+  main() in main.c -->
+    BSPMain() in bsp.c -->
+      ProcessModels() in bsp.c -->
+        ProcessWorldModel() in bsp.c
+          FixTJunctions() in tjunction.c
+            FixBrokenSurface() in tjunction.c
+
+FixBrokenSurface() realizes that there are two points very close together
+(in our case, since they were "snapped", the are coincident in fact).
+Therefore it reports the surface to be broken.  The drawable surface is
+deleted as a result.
+
+
+RELATED BUGS:
+=============
+
+A lot of the math operations in the Radiant codebase cut corners like this
+example demonstrates.  There is a lot more code like this that can be
+improved upon.  In fact, it may make sense to use 64 bit floating points in
+some important math operations (and then convert back to 32 bit for the return
+values).  Plans are to look at similar code and improve it.
+
+The following "issue" was discovered while doing research for this bug.
+If FixBrokenSurface() sees two points very close together, it attempts to
+partially fix the problem (the code is not complete) and then returns false,
+which means that the surface is broken and should not be used.  So in fact
+it attempts to fix the problem partially but none of the fixes are used.
+It seems that FixBrokenSurface() should be fixed to completely fix the case
+where there are two close points, and should report the surface as fixed.
+This might be a destabilizing change however, so if this is indeed fixed, it
+may make sense to activate the fix only if a certain flag is set.
+
+
+MORE NOTES:
+===========
+
+As stated above, the accuracy after revision 363 is:
+
+  (67.000229 -1021.998657 0.000000)
+  (88.000175 -891.999146 -767.997437)
+  (133.999146 -1014.998779 0.000000)
+
+A further change was committed for a related problem in revision 377.  After
+this change:
+
+  (66.99955750 -1022.00262451 0.00000000)
+  (87.99969482 -892.00170898 -768.00524902)
+  (133.99958801 -1015.00195312 0.00000000)
+
+The results look similar with respect to the amount of error present.
diff --git a/regression_tests/q3map2/disappearing_sliver/maps/disappearing_sliver.map b/regression_tests/q3map2/disappearing_sliver/maps/disappearing_sliver.map
new file mode 100644 (file)
index 0000000..8252886
--- /dev/null
@@ -0,0 +1,73 @@
+{
+"classname" "worldspawn"
+{
+( -704 -1152 0 ) ( 4480 -1152 0 ) ( -704 -1152 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 67 -1022 0 ) ( 67 -4096 0 ) ( 88 -892 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 67 -1022 0 ) ( 88 -892 -768 ) ( 134 -1015 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 88 -892 -768 ) ( 88 -4096 -768 ) ( 134 -1015 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 134 -1015 0 ) ( 134 -4096 0 ) ( 67 -1022 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 584 -640 -768 ) ( 520 -640 -768 ) ( 520 -1160 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 528 -1160 320 ) ( 528 -640 320 ) ( 592 -640 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 528 -1152 0 ) ( 592 -1152 0 ) ( 592 -1152 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 520 -1160 0 ) ( 520 -640 0 ) ( 520 -640 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 584 -640 0 ) ( 520 -640 0 ) ( 520 -640 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -640 0 ) ( 512 -1160 0 ) ( 512 -1160 -768 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 512 -552 -768 ) ( -296 -552 -768 ) ( -296 -640 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -296 -640 320 ) ( -296 -552 320 ) ( 512 -552 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -296 -640 320 ) ( 512 -640 320 ) ( 512 -640 -768 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 512 -640 320 ) ( 512 -552 320 ) ( 512 -552 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 528 -632 320 ) ( -280 -632 320 ) ( -280 -632 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -536 320 ) ( -512 -624 320 ) ( -512 -624 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -512 -648 -768 ) ( -536 -648 -768 ) ( -536 -1152 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -536 -1152 320 ) ( -536 -648 320 ) ( -512 -648 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -536 -1152 320 ) ( -512 -1152 320 ) ( -512 -1152 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -1152 320 ) ( -512 -648 320 ) ( -512 -648 -768 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -512 -640 320 ) ( -536 -640 320 ) ( -536 -640 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -520 -648 320 ) ( -520 -1152 320 ) ( -520 -1152 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 512 -640 320 ) ( 24 -640 320 ) ( 24 -1152 320 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 48 -1152 328 ) ( 48 -640 328 ) ( 536 -640 328 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 24 -1152 440 ) ( 512 -1152 440 ) ( 512 -1152 328 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -1152 440 ) ( 512 -640 440 ) ( 512 -640 328 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -640 440 ) ( 24 -640 440 ) ( 24 -640 328 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -640 464 ) ( -512 -1152 464 ) ( -512 -1152 352 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -328 -896 -776 ) ( -512 -896 -776 ) ( -512 -1152 -776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -1152 -768 ) ( -512 -896 -768 ) ( -328 -896 -768 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -512 -1152 -768 ) ( -328 -1152 -768 ) ( -328 -1152 -776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -896 -768 ) ( -512 -1152 -768 ) ( -512 -1152 -776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -1152 -768 ) ( 512 -896 -768 ) ( 512 -896 -776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -368 -640 -824 ) ( -856 -640 -824 ) ( -856 -640 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -512 -1168 320 ) ( -512 -1584 320 ) ( -512 -1584 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 1152 -1152 320 ) ( 176 -1152 320 ) ( 176 -1152 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 512 -1576 320 ) ( 512 -1160 320 ) ( 512 -1160 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 208 -1160 320 ) ( 1184 -1160 320 ) ( 1184 -1160 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 176 -1568 320 ) ( 176 -1152 320 ) ( 1152 -1152 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 -1152 -768 ) ( -520 -1152 -768 ) ( -520 -1192 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+}
+{
+"light" "3000"
+"origin" "0 -768 -480"
+"classname" "light"
+}
+{
+"angle" "270"
+"origin" "0 -712 -640"
+"classname" "info_player_deathmatch"
+}
+{
+"classname" "light"
+"origin" "0 -832 160"
+"light" "3000"
+}
diff --git a/regression_tests/q3map2/disappearing_sliver/winding_logging.patch b/regression_tests/q3map2/disappearing_sliver/winding_logging.patch
new file mode 100644 (file)
index 0000000..a1babe9
--- /dev/null
@@ -0,0 +1,105 @@
+Index: tools/quake3/q3map2/brush.c
+===================================================================
+--- tools/quake3/q3map2/brush.c        (revision 391)
++++ tools/quake3/q3map2/brush.c        (working copy)
+@@ -421,10 +421,16 @@
+       side_t          *side;
+       plane_t         *plane;
+       
+-      
++      static  int     brushord = -1;
++      brushord++;
++
++      Sys_Printf("In CreateBrushWindings() for brush %i\n", brushord);        
++
+       /* walk the list of brush sides */
+       for( i = 0; i < brush->numsides; i++ )
+       {
++              Sys_Printf("    Handling side %i on the brush\n", i);
++
+               /* get side and plane */
+               side = &brush->sides[ i ];
+               plane = &mapplanes[ side->planenum ];
+@@ -435,7 +441,13 @@
+ #else
+               w = BaseWindingForPlane( plane->normal, plane->dist );
+ #endif
+-              
++
++              Sys_Printf("        Before clipping we have:\n");
++              int z;
++              for (z = 0; z < w->numpoints; z++) {
++                      Sys_Printf("            (%.8f %.8f %.8f)\n", w->p[z][0], w->p[z][1], w->p[z][2]);
++              }
++
+               /* walk the list of brush sides */
+               for( j = 0; j < brush->numsides && w != NULL; j++ )
+               {
+@@ -451,7 +463,20 @@
+ #else
+                       ChopWindingInPlace( &w, plane->normal, plane->dist, 0 ); // CLIP_EPSILON );
+ #endif
+-                      
++
++                      Sys_Printf("        After clipping w/ side %i we have:\n", j);
++                      if (w)
++                      {
++                              for (z = 0; z < w->numpoints; z++)
++                              {
++                                      Sys_Printf("            (%.8f %.8f %.8f)\n", w->p[z][0], w->p[z][1], w->p[z][2]);
++                              }
++                      }
++                      else
++                      {
++                              Sys_Printf("            winding is NULL\n");
++                      }
++
+                       /* ydnar: fix broken windings that would generate trifans */
+ #if EXPERIMENTAL_HIGH_PRECISION_MATH_Q3MAP2_FIXES
+                       FixWindingAccu(w);
+Index: tools/quake3/q3map2/map.c
+===================================================================
+--- tools/quake3/q3map2/map.c  (revision 391)
++++ tools/quake3/q3map2/map.c  (working copy)
+@@ -803,7 +803,11 @@
+       char                    shader[ MAX_QPATH ];
+       int                             flags;
+       
++      static  int     brushord = -1;
++      brushord++;
+       
++      Sys_Printf("In ParseRawBrush() for brush %i\n", brushord);
++
+       /* initial setup */
+       buildBrush->numsides = 0;
+       buildBrush->detail = qfalse;
+@@ -812,9 +816,12 @@
+       if( g_bBrushPrimit == BPRIMIT_NEWBRUSHES )
+               MatchToken( "{" );
+       
++      int sideord = -1;
++
+       /* parse sides */
+       while( 1 )
+       {
++              sideord++;
+               if( !GetToken( qtrue ) )
+                       break;
+               if( !strcmp( token, "}" ) )
+@@ -917,7 +924,16 @@
+               }
+               
+               /* find the plane number */
++              Sys_Printf("    Side %i:\n", sideord);
++              Sys_Printf("        (%f %f %f)\n", planePoints[0][0], planePoints[0][1], planePoints[0][2]);
++              Sys_Printf("        (%f %f %f)\n", planePoints[1][0], planePoints[1][1], planePoints[1][2]);
++              Sys_Printf("        (%f %f %f)\n", planePoints[2][0], planePoints[2][1], planePoints[2][2]);
+               planenum = MapPlaneFromPoints( planePoints );
++              Sys_Printf("        normal: (%.10f %.10f %.10f)\n",
++                              mapplanes[planenum].normal[0],
++                              mapplanes[planenum].normal[1],
++                              mapplanes[planenum].normal[2]);
++              Sys_Printf("        dist: %.10f\n", mapplanes[planenum].dist);
+               side->planenum = planenum;
+               
+               /* bp: get the texture mapping for this texturedef / plane combination */
diff --git a/regression_tests/q3map2/disappearing_sliver2/README.txt b/regression_tests/q3map2/disappearing_sliver2/README.txt
new file mode 100644 (file)
index 0000000..ffa12be
--- /dev/null
@@ -0,0 +1,93 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+The example map, maps/disappearing_sliver2.map, contains an example of this
+bug.  The triangle sliver surface in the middle of the room is not rendered
+in the final BSP.
+
+To trigger the bug, compile the map; you don't need -vis or -light.  Only
+-bsp (the first q3map2 stage) is necessary to trigger the bug.  The only
+entities in the map are a light and a info_player_deathmatch, so the map will
+compile for any Q3 mod.
+
+
+SOLUTION TO PROBLEM:
+====================
+
+It was discovered that BaseWindingForPlane() in polylib.c did some sloppy
+mathematics with significant loss of precision.  Those problems have been
+addressed in commits to revisions 371 and 377.
+
+
+POSSIBLE SIDE EFFECTS:
+======================
+
+Great care was taken to preserve the exact behavior of the original
+BaseWindingForPlane() function except for the loss of precision.  Therefore
+no negative side effects should be seen.  In fact performance may be
+increased.
+
+
+IN-DEPTH DISCUSSION:
+====================
+
+Turns out that the problem is very similar to the original disappearing_sliver
+regression test.  You should read that README.txt to familiarize yourself
+with the situation.
+
+The thing we need to look at is side 0 of brush 0, if you applied
+winding_logging.patch from disappearing_sliver regression test:
+
+  In ParseRawBrush() for brush 0
+      Side 0:
+          (6784.000000 16241.000000 -1722.000000)
+          (6144.000000 16083.000000 -1443.000000)
+          (6144.000000 16122.000000 -1424.000000)
+
+That is the exact plane defninition of our problem sliver, and in fact those
+are also the correct points for the actual vertices of the triangle.
+
+Now the results of the winding for this surface after all the clipping takes
+place:
+
+  (6784.12500000 16241.02343750 -1722.06250000)
+  (6144.00000000 16082.99218750 -1443.00781250)
+  (6144.00000000 16122.00000000 -1424.00390625)
+
+As you can see, 6784.12500000 is more than epsilon distance (0.1) away from
+the correct point.  This is a big problem.
+
+After we apply the fix committed in revision 371, the result after clipping
+is this:
+
+  (6784.06250000 16241.01171875 -1722.03515625)
+  (6144.00000000 16082.99609375 -1443.00781250)
+  (6144.00000000 16122.00000000 -1424.00585938)
+
+As you can see, all points but one have an increase in accuracy.  This is
+still not accurate enough in my opinion, but is a step in the right direction.
+
+After the fix committed in revision 377, which is a further attempt to address
+BaseWindingForPlane(), we get the following accuracy:
+
+  (6784.00000000 16241.00000000 -1722.00000000)
+  (6144.00000000 16083.00000000 -1443.00000000)
+  (6144.00000000 16122.00000000 -1424.00000000)
+
+It's just a fluke for this particular case, but obviouly revision 377 looks
+favorably upon this regression test, because there is zero percent error.
+
+
+MORE NOTES:
+===========
+
+I attempted to improve upon revision 371 by streamlining the code in
+BaseWindingForPlane() some more.  Those attempts were committed as revision
+375.  After revision 375:
+
+  (6784.09375000 16241.01757812 -1722.04687500)
+  (6144.00000000 16082.99414062 -1443.00390625)
+  (6144.00000000 16122.00000000 -1424.00097656)
+
+Revision 375 has since been reverted (undone) because of the loss in
+accuracy.  Revision 377 is a fix for those failed attempts.
diff --git a/regression_tests/q3map2/disappearing_sliver2/maps/disappearing_sliver2.map b/regression_tests/q3map2/disappearing_sliver2/maps/disappearing_sliver2.map
new file mode 100644 (file)
index 0000000..53e1871
--- /dev/null
@@ -0,0 +1,69 @@
+{
+"message" "Icy Fantasy by Rambetter"
+"classname" "worldspawn"
+{
+( 6784 16241 -1722 ) ( 6144 16083 -1443 ) ( 6144 16122 -1424 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 6784 16241 -1722 ) ( 6784 16241 -2048 ) ( 6144 16083 -1443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6144 16083 -1443 ) ( 6144 16083 -2048 ) ( 6144 16122 -1424 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6144 16122 -1424 ) ( 6144 16122 -2048 ) ( 6784 16241 -1722 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6144 16122 -2048 ) ( 6144 16083 -2048 ) ( 6784 16241 -2048 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 6136 16424 168 ) ( 6136 15928 168 ) ( 6136 15928 -3544 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6112 16896 160 ) ( 6000 16896 160 ) ( 6000 16896 -3552 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15936 160 ) ( 6144 16432 160 ) ( 6144 16432 -3552 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6032 15936 160 ) ( 6144 15936 160 ) ( 6144 15936 -3552 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6128 15936 -896 ) ( 6128 16432 -896 ) ( 6240 16432 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6160 16432 -2048 ) ( 6048 16432 -2048 ) ( 6048 15936 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6784 16672 -1296 ) ( 6784 16176 -1296 ) ( 6784 16176 -1776 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6144 16896 -1312 ) ( 6136 16896 -1312 ) ( 6136 16896 -1792 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6792 16160 -1296 ) ( 6792 16656 -1296 ) ( 6792 16656 -1776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6136 15936 -1280 ) ( 6144 15936 -1280 ) ( 6144 15936 -1760 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6136 16192 -896 ) ( 6136 16688 -896 ) ( 6144 16688 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16672 -2048 ) ( 6136 16672 -2048 ) ( 6136 16176 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6144 15936 -896 ) ( 6144 15880 -896 ) ( 6144 15880 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 15936 -896 ) ( 6144 15936 -896 ) ( 6144 15936 -2048 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6784 15880 -896 ) ( 6784 15936 -896 ) ( 6784 15936 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15928 -896 ) ( 6784 15928 -896 ) ( 6784 15928 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15880 -896 ) ( 6144 15936 -896 ) ( 6784 15936 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 15936 -2048 ) ( 6144 15936 -2048 ) ( 6144 15880 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6144 16960 -896 ) ( 6144 16896 -896 ) ( 6144 16896 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16904 -896 ) ( 6144 16904 -896 ) ( 6144 16904 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16896 -896 ) ( 6784 16960 -896 ) ( 6784 16960 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16896 -896 ) ( 6784 16896 -896 ) ( 6784 16896 -2048 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6144 16896 -896 ) ( 6144 16960 -896 ) ( 6784 16960 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16960 -2048 ) ( 6144 16960 -2048 ) ( 6144 16896 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6144 16896 -784 ) ( 6144 16536 -784 ) ( 6144 16536 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16896 -784 ) ( 6144 16896 -784 ) ( 6144 16896 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16536 -784 ) ( 6784 16896 -784 ) ( 6784 16896 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15936 -744 ) ( 6784 15936 -744 ) ( 6784 15936 -856 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16552 -888 ) ( 6144 16912 -888 ) ( 6784 16912 -888 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16896 -896 ) ( 6144 16896 -896 ) ( 6144 16536 -896 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 6144 16544 -2048 ) ( 6144 15936 -2048 ) ( 6144 15936 -2376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16896 -2048 ) ( 6144 16896 -2048 ) ( 6144 16896 -2376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 15936 -2048 ) ( 6784 16544 -2048 ) ( 6784 16544 -2376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15936 -2048 ) ( 6784 15936 -2048 ) ( 6784 15936 -2376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15936 -2048 ) ( 6144 16544 -2048 ) ( 6784 16544 -2048 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6784 16584 -2056 ) ( 6144 16584 -2056 ) ( 6144 15976 -2056 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+}
+{
+"classname" "info_player_deathmatch"
+"origin" "6432 16168 -1472"
+"angle" "180"
+}
+{
+"classname" "light"
+"origin" "6440 16160 -1192"
+"light" "1000"
+}
diff --git a/regression_tests/q3map2/disappearing_sliver3/NOTES.txt b/regression_tests/q3map2/disappearing_sliver3/NOTES.txt
new file mode 100644 (file)
index 0000000..70bb752
--- /dev/null
@@ -0,0 +1,72 @@
+Random notes for Rambetter, don't expect to understand this:
+============================================================
+
+Brush 0 is the problem.
+
+Side 0 is the problem (under surf tri).
+Side 1 is the +y 4-face.
+Side 2 is the -x 4-face.
+Side 3 is the -y 4-face.
+side 4 is the +z tri.
+
+(6144, 16122) -> (6784, 16241)
+x "climb" of side 1 is 6784 - 6144 = 640.
+y "climb" of side 1 is 16241 - 16122 = 119.
+
+x/y "climb rate" of side 1 is 640 / 119 = 5.378151261.
+
+After clipping side 0 against side 1, we get
+************
+**** (-262144, -33762.8125) -> (262144, 63722)
+************
+The slope of that is (262144 + 262144) / (63722 + 33762.8125) = 5.378150571. 
+
+(-262144, y) -> (6784, 16241)
+So (6784 + 262144) / (16241 - y) = 640 / 119
+So y = 16241 - ((119 * (6784 + 262144)) / 640) = -33762.8
+
+(6144, 16122) -> (262144, y)
+So (262144 - 6144) / (y - 16122) = 640 / 119
+So y = 16122 + ((119 * (262144 - 6144)) / 640) = 63722
+
+After clipping side 0 against side 1 should have
+************
+**** (-262144, -33762.8) -> (262144, 63722)
+************
+
+Random notes for Rambetter, don't expect to understand this:
+============================================================
+
+Brush 0 is the problem.
+
+Side 0 is the problem (under surf tri).
+Side 1 is the +y 4-face.
+Side 2 is the -x 4-face.
+Side 3 is the -y 4-face.
+side 4 is the +z tri.
+
+(6144, 16122) -> (6784, 16241)
+x "climb" of side 1 is 6784 - 6144 = 640.
+y "climb" of side 1 is 16241 - 16122 = 119.
+
+x/y "climb rate" of side 1 is 640 / 119 = 5.378151261.
+
+After clipping side 0 against side 1, we get
+************
+**** (-262144, -33762.8125) -> (262144, 63722)
+************
+The slope of that is (262144 + 262144) / (63722 + 33762.8125) = 5.378150571. 
+
+(-262144, y) -> (6784, 16241)
+So (6784 + 262144) / (16241 - y) = 640 / 119
+So y = 16241 - ((119 * (6784 + 262144)) / 640) = -33762.8
+
+(6144, 16122) -> (262144, y)
+So (262144 - 6144) / (y - 16122) = 640 / 119
+So y = 16122 + ((119 * (262144 - 6144)) / 640) = 63722
+
+After clipping side 0 against side 1 should have
+************
+**** (-262144, -33762.8) -> (262144, 63722)
+************
+
diff --git a/regression_tests/q3map2/disappearing_sliver3/README.txt b/regression_tests/q3map2/disappearing_sliver3/README.txt
new file mode 100644 (file)
index 0000000..839bd69
--- /dev/null
@@ -0,0 +1,49 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+The example map, maps/disappearing_sliver3.map, contains an example of this
+bug.  The triangle sliver surface in the middle of the room is not rendered
+in the final BSP.
+
+To trigger the bug, compile the map; you don't need -vis or -light.  Only
+-bsp (the first q3map2 stage) is necessary to trigger the bug.  The only
+entities in the map are a light and a info_player_deathmatch, so the map will
+compile for any Q3 mod.
+
+
+SOLUTION TO PROBLEM:
+====================
+
+More work has been done to BaseWindingForPlane() to make it more accurate.
+This function is in polylib.c.  The changes to fix this regression test were
+committed in revision 377; however, those changes are not "good enough".
+
+
+IN-DEPTH DISCUSSION:
+====================
+
+This is the problem triangle:
+
+  In ParseRawBrush() for brush 0
+      Side 0:
+          (6144.000000 16122.000000 -2048.000000)
+          (6144.000000 16083.000000 -2048.000000)
+          (6784.000000 16241.000000 -2048.000000)
+
+Computed winding before fix:
+
+  (6784.16406250 16241.04101562 -2048.00000000)
+  (6144.00000000 16122.00976562 -2048.00000000)
+  (6144.00000000 16083.00000000 -2048.00000000)
+
+Obviously the 6784.16406250 is beyond epsilon error.
+
+After revision 377:
+
+  (6783.85937500 16240.96484375 -2048.00000000)
+  (6144.00000000 16121.99218750 -2048.00000000)
+  (6144.00000000 16083.00000000 -2048.00000000)
+
+Even though this fixes the regression test, the error in 6783.85937500 is
+still greater than epsilon (but fortunately in the opposite direction).  So
+I don't consider this test case to be fixed quite yet.
diff --git a/regression_tests/q3map2/disappearing_sliver3/maps/disappearing_sliver3.map b/regression_tests/q3map2/disappearing_sliver3/maps/disappearing_sliver3.map
new file mode 100644 (file)
index 0000000..a56c649
--- /dev/null
@@ -0,0 +1,68 @@
+{
+"classname" "worldspawn"
+{
+( 6144 16122 -2048 ) ( 6144 16083 -2048 ) ( 6784 16241 -2048 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 6144 16122 -1424 ) ( 6144 16122 -2048 ) ( 6784 16241 -1722 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6144 16083 -1443 ) ( 6144 16083 -2048 ) ( 6144 16122 -1424 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6784 16241 -1722 ) ( 6784 16241 -2048 ) ( 6144 16083 -1443 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6784 16241 -1722 ) ( 6144 16083 -1443 ) ( 6144 16122 -1424 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 6160 16432 -2240 ) ( 6048 16432 -2240 ) ( 6048 15936 -2240 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6128 15936 -1376 ) ( 6128 16432 -1376 ) ( 6240 16432 -1376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6032 15936 160 ) ( 6144 15936 160 ) ( 6144 15936 -3552 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15936 -512 ) ( 6144 16432 -512 ) ( 6144 16432 -4224 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6112 16896 160 ) ( 6000 16896 160 ) ( 6000 16896 -3552 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6136 16424 168 ) ( 6136 15928 168 ) ( 6136 15928 -3544 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6144 16672 -2240 ) ( 6136 16672 -2240 ) ( 6136 16176 -2240 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6136 16192 -1376 ) ( 6136 16688 -1376 ) ( 6144 16688 -1376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6136 15936 -1280 ) ( 6144 15936 -1280 ) ( 6144 15936 -1760 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6792 16160 -1296 ) ( 6792 16656 -1296 ) ( 6792 16656 -1776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16896 -1312 ) ( 6136 16896 -1312 ) ( 6136 16896 -1792 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16672 -1968 ) ( 6784 16176 -1968 ) ( 6784 16176 -2448 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 6784 15936 -2240 ) ( 6144 15936 -2240 ) ( 6144 15880 -2240 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15880 -1376 ) ( 6144 15936 -1376 ) ( 6784 15936 -1376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15928 -896 ) ( 6784 15928 -896 ) ( 6784 15928 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 15880 -1568 ) ( 6784 15936 -1568 ) ( 6784 15936 -2720 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 15936 -896 ) ( 6144 15936 -896 ) ( 6144 15936 -2048 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6144 15936 -1568 ) ( 6144 15880 -1568 ) ( 6144 15880 -2720 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6784 16960 -2240 ) ( 6144 16960 -2240 ) ( 6144 16896 -2240 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16896 -1376 ) ( 6144 16960 -1376 ) ( 6784 16960 -1376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16896 -896 ) ( 6784 16896 -896 ) ( 6784 16896 -2048 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6784 16896 -1568 ) ( 6784 16960 -1568 ) ( 6784 16960 -2720 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16904 -896 ) ( 6144 16904 -896 ) ( 6144 16904 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16960 -1568 ) ( 6144 16896 -1568 ) ( 6144 16896 -2720 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6784 16896 -1376 ) ( 6144 16896 -1376 ) ( 6144 16536 -1376 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6144 16552 -1368 ) ( 6144 16912 -1368 ) ( 6784 16912 -1368 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15936 -1224 ) ( 6784 15936 -1224 ) ( 6784 15936 -1336 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16536 -1264 ) ( 6784 16896 -1264 ) ( 6784 16896 -1376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16896 -1264 ) ( 6144 16896 -1264 ) ( 6144 16896 -1376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16896 -1264 ) ( 6144 16536 -1264 ) ( 6144 16536 -1376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6784 16584 -2248 ) ( 6144 16584 -2248 ) ( 6144 15976 -2248 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15936 -2240 ) ( 6144 16544 -2240 ) ( 6784 16544 -2240 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6144 15936 -2240 ) ( 6784 15936 -2240 ) ( 6784 15936 -2568 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 15936 -2240 ) ( 6784 16544 -2240 ) ( 6784 16544 -2568 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16896 -2240 ) ( 6144 16896 -2240 ) ( 6144 16896 -2568 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16544 -2240 ) ( 6144 15936 -2240 ) ( 6144 15936 -2568 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+}
+{
+"angle" "180"
+"origin" "6432 16168 -2144"
+"classname" "info_player_deathmatch"
+}
+{
+"light" "1000"
+"origin" "6504 16160 -2152"
+"classname" "light"
+}
diff --git a/regression_tests/q3map2/duplicate_plane/README.txt b/regression_tests/q3map2/duplicate_plane/README.txt
new file mode 100644 (file)
index 0000000..8c2ef02
--- /dev/null
@@ -0,0 +1,13 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+The 4-sided brush in the middle of the room (brush 0) has a duplicate plane.
+The last side (side 4) is a duplicate of the third side (side 2) with the
+vertexes re-arranged.
+
+I wanted to make sure that ChopWindingInPlaceAccu() is doing the right thing
+by setting a winding to NULL when all its points lie on the plane that the
+winding is being chopped with.  This seems to be the case.  My concern was
+that both windings for that duplicate plane will be NULL'ed out.
+
+Seems that some other code might be fixing duplicate planes.  That's OK.
diff --git a/regression_tests/q3map2/duplicate_plane/maps/duplicate_plane.map b/regression_tests/q3map2/duplicate_plane/maps/duplicate_plane.map
new file mode 100644 (file)
index 0000000..d1913b4
--- /dev/null
@@ -0,0 +1,67 @@
+{
+"classname" "worldspawn"
+{
+( 136 128 64 ) ( -128 128 64 ) ( -128 -192 64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 136 128 384 ) ( -128 128 384 ) ( -128 128 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 128 -192 0 ) ( -128 128 0 ) ( 128 -192 384 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -128 128 256 ) ( 128 128 64 ) ( -128 -192 256 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 128 -192 384 ) ( 128 -192 0 ) ( -128 128 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 256 256 -8 ) ( -256 256 -8 ) ( -256 -256 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 -256 0 ) ( -256 256 0 ) ( 256 256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -256 -256 8 ) ( 256 -256 8 ) ( 256 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 -256 8 ) ( 256 256 8 ) ( 256 256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 256 8 ) ( -256 256 8 ) ( -256 256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 256 8 ) ( -256 -256 8 ) ( -256 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -256 256 0 ) ( -280 256 0 ) ( -280 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -280 -256 384 ) ( -280 256 384 ) ( -256 256 384 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -280 -256 384 ) ( -256 -256 384 ) ( -256 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 -256 384 ) ( -256 256 384 ) ( -256 256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -256 256 384 ) ( -280 256 384 ) ( -280 256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -264 256 392 ) ( -264 -256 392 ) ( -264 -256 8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 280 256 0 ) ( 256 256 0 ) ( 256 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 -256 384 ) ( 256 256 384 ) ( 280 256 384 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 -256 384 ) ( 280 -256 384 ) ( 280 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 264 -256 384 ) ( 264 256 384 ) ( 264 256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 280 256 384 ) ( 256 256 384 ) ( 256 256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 256 384 ) ( 256 -256 384 ) ( 256 -256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 256 256 384 ) ( -256 256 384 ) ( -256 -256 384 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -248 -256 392 ) ( -248 256 392 ) ( 264 256 392 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 -256 424 ) ( 256 -256 424 ) ( 256 -256 384 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 -256 424 ) ( 256 256 424 ) ( 256 256 384 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 256 424 ) ( -256 256 424 ) ( -256 256 384 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 256 424 ) ( -256 -256 424 ) ( -256 -256 384 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 256 296 0 ) ( -256 296 0 ) ( -256 256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 256 384 ) ( -256 296 384 ) ( 256 296 384 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 256 384 ) ( 256 256 384 ) ( 256 256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 256 256 384 ) ( 256 296 384 ) ( 256 296 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 264 392 ) ( -256 264 392 ) ( -256 264 8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 296 384 ) ( -256 256 384 ) ( -256 256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 256 -256 0 ) ( -256 -256 0 ) ( -256 -296 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 -296 384 ) ( -256 -256 384 ) ( 256 -256 384 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -256 -264 392 ) ( 256 -264 392 ) ( 256 -264 8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 -296 384 ) ( 256 -256 384 ) ( 256 -256 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 256 -256 384 ) ( -256 -256 384 ) ( -256 -256 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -256 -256 384 ) ( -256 -296 384 ) ( -256 -296 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+}
+{
+"origin" "-8 16 256"
+"classname" "info_player_deathmatch"
+}
+{
+"light" "1000"
+"origin" "-32 -40 256"
+"classname" "light"
+}
diff --git a/regression_tests/q3map2/model_clipping_45_degrees/README.txt b/regression_tests/q3map2/model_clipping_45_degrees/README.txt
new file mode 100644 (file)
index 0000000..c3c2f88
--- /dev/null
@@ -0,0 +1,7 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+There are 3 model wedges in the map that are auto-clipped.  The middle wedge
+with the 45 degree slope is the problem.  The slope face does not become solid;
+therefore, there is a nonsolid "hole" on the wedge part.  The other two wedges
+are fine.  45 degrees seems to be a problem for model clipping.
diff --git a/regression_tests/q3map2/model_clipping_45_degrees/maps/model_clipping_45_degrees.map b/regression_tests/q3map2/model_clipping_45_degrees/maps/model_clipping_45_degrees.map
new file mode 100644 (file)
index 0000000..f358dba
--- /dev/null
@@ -0,0 +1,81 @@
+{
+"classname" "worldspawn"
+{
+( 392 512 -8 ) ( 0 512 -8 ) ( 0 448 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 0 448 0 ) ( 0 512 0 ) ( 392 512 0 ) radiant_regression_tests/bigtile 0 0 0 0.500000 0.500000 0 0 0
+( 104 -192 0 ) ( 496 -192 0 ) ( 496 -192 -16 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 384 448 0 ) ( 384 512 0 ) ( 384 512 -16 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 400 640 0 ) ( 8 640 0 ) ( 8 640 -16 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -128 528 0 ) ( -128 464 0 ) ( -128 464 -16 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -128 688 320 ) ( -128 640 320 ) ( -128 640 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 384 648 320 ) ( -128 648 320 ) ( -128 648 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 384 640 320 ) ( 384 688 320 ) ( 384 688 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -128 640 320 ) ( 384 640 320 ) ( 384 640 0 ) radiant_regression_tests/bigtile 0 0 0 0.500000 0.500000 0 0 0
+( -128 640 320 ) ( -128 688 320 ) ( 384 688 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 384 688 0 ) ( -128 688 0 ) ( -128 640 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -128 -184 328 ) ( -128 -240 328 ) ( -128 -240 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 384 -192 328 ) ( -128 -192 328 ) ( -128 -192 0 ) radiant_regression_tests/bigtile 0 0 0 0.500000 0.500000 0 0 0
+( 384 -240 328 ) ( 384 -184 328 ) ( 384 -184 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -128 -200 320 ) ( 384 -200 320 ) ( 384 -200 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -128 -240 320 ) ( -128 -184 320 ) ( 384 -184 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 384 -184 0 ) ( -128 -184 0 ) ( -128 -240 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -128 248 392 ) ( -128 -192 392 ) ( -128 -192 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 384 640 408 ) ( -128 640 408 ) ( -128 640 336 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 384 -192 392 ) ( 384 248 392 ) ( 384 248 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -128 -192 392 ) ( 384 -192 392 ) ( 384 -192 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -128 -176 328 ) ( -128 264 328 ) ( 384 264 328 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 384 248 320 ) ( -128 248 320 ) ( -128 -192 320 ) radiant_regression_tests/bigtile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 384 640 320 ) ( 384 -192 320 ) ( 384 -192 0 ) radiant_regression_tests/bigtile 0 0 0 0.500000 0.500000 0 0 0
+( 432 640 320 ) ( 384 640 320 ) ( 384 640 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 392 -192 320 ) ( 392 640 320 ) ( 392 640 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 384 -192 320 ) ( 432 -192 320 ) ( 432 -192 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 384 -192 320 ) ( 384 640 320 ) ( 432 640 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 432 640 0 ) ( 384 640 0 ) ( 384 -192 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -136 640 328 ) ( -136 -192 328 ) ( -136 -192 8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -128 640 312 ) ( -224 640 312 ) ( -224 640 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -128 -192 312 ) ( -128 640 312 ) ( -128 640 -8 ) radiant_regression_tests/bigtile 0 0 0 0.500000 0.500000 0 0 0
+( -224 -192 312 ) ( -128 -192 312 ) ( -128 -192 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -224 -192 320 ) ( -224 640 320 ) ( -128 640 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -128 640 0 ) ( -224 640 0 ) ( -224 -192 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+}
+{
+"model" "models/mapobjects/wedges/wedge_shallow.ase"
+"origin" "0 -96 0"
+"classname" "misc_model"
+}
+{
+"model" "models/mapobjects/wedges/wedge_45.ase"
+"origin" "0 160 0"
+"classname" "misc_model"
+}
+{
+"model" "models/mapobjects/wedges/wedge_steep.ase"
+"origin" "0 416 0"
+"classname" "misc_model"
+}
+{
+"classname" "light"
+"origin" "192 384 160"
+"light" "800"
+}
+{
+"light" "800"
+"origin" "192 64 160"
+"classname" "light"
+}
+{
+"classname" "info_player_deathmatch"
+"origin" "256 208 128"
+"angle" "225"
+}
diff --git a/regression_tests/q3map2/model_clipping_45_degrees/models/mapobjects/wedges/wedge_45.ase b/regression_tests/q3map2/model_clipping_45_degrees/models/mapobjects/wedges/wedge_45.ase
new file mode 100644 (file)
index 0000000..dfb0d41
--- /dev/null
@@ -0,0 +1,368 @@
+*3DSMAX_ASCIIEXPORT    200\r
+*COMMENT       "Generated by Q3Map2 (ydnar) -convert -format ase"\r
+*SCENE {\r
+       *SCENE_FILENAME "wedge_45.bsp"\r
+       *SCENE_FIRSTFRAME       0\r
+       *SCENE_LASTFRAME        100\r
+       *SCENE_FRAMESPEED       30\r
+       *SCENE_TICKSPERFRAME    160\r
+       *SCENE_BACKGROUND_STATIC        0.0000  0.0000  0.0000\r
+       *SCENE_AMBIENT_STATIC   0.0000  0.0000  0.0000\r
+}\r
+*MATERIAL_LIST {\r
+       *MATERIAL_COUNT 2\r
+       *MATERIAL       0       {\r
+               *MATERIAL_NAME  "textures/radiant_regression_tests/tile_model"\r
+               *MATERIAL_CLASS "Standard"\r
+               *MATERIAL_DIFFUSE       1.000000        1.000000        0.833333\r
+               *MATERIAL_SHADING Phong\r
+               *MAP_DIFFUSE    {\r
+                       *MAP_NAME       "textures/radiant_regression_tests/tile_model"\r
+                       *MAP_CLASS      "Bitmap"\r
+                       *MAP_SUBNO      1\r
+                       *MAP_AMOUNT     1.0\r
+                       *MAP_TYPE       Screen\r
+                       *BITMAP "..\textures\radiant_regression_tests\tile_model.tga"\r
+                       *BITMAP_FILTER  Pyramidal\r
+               }\r
+       }\r
+       *MATERIAL       1       {\r
+               *MATERIAL_NAME  "noshader"\r
+               *MATERIAL_CLASS "Standard"\r
+               *MATERIAL_DIFFUSE       1.000000        1.000000        1.000000\r
+               *MATERIAL_SHADING Phong\r
+               *MAP_DIFFUSE    {\r
+                       *MAP_NAME       "noshader"\r
+                       *MAP_CLASS      "Bitmap"\r
+                       *MAP_SUBNO      1\r
+                       *MAP_AMOUNT     1.0\r
+                       *MAP_TYPE       Screen\r
+                       *BITMAP "..\noshader.tga"\r
+                       *BITMAP_FILTER  Pyramidal\r
+               }\r
+       }\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf0"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf0"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       128.000000      0.000000        0.000000\r
+                       *MESH_VERTEX    1       64.000000       0.000000        64.000000\r
+                       *MESH_VERTEX    2       128.000000      128.000000      0.000000\r
+                       *MESH_VERTEX    3       64.000000       128.000000      64.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.707107        0.000000        0.707107\r
+                       *MESH_FACENORMAL        1       0.707107        0.000000        0.707107\r
+                       *MESH_VERTEXNORMAL      0       0.707107        0.000000        0.707107\r
+                       *MESH_VERTEXNORMAL      1       0.707107        0.000000        0.707107\r
+                       *MESH_VERTEXNORMAL      2       0.707107        0.000000        0.707107\r
+                       *MESH_VERTEXNORMAL      3       0.707107        0.000000        0.707107\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       1.000000        -1.000000       1.000000\r
+                       *MESH_TVERT     1       -1.000000       -1.000000       1.000000\r
+                       *MESH_TVERT     2       1.000000        3.000000        1.000000\r
+                       *MESH_TVERT     3       -1.000000       3.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf1"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf1"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       0.000000        128.000000      64.000000\r
+                       *MESH_VERTEX    1       0.000000        128.000000      0.000000\r
+                       *MESH_VERTEX    2       64.000000       128.000000      64.000000\r
+                       *MESH_VERTEX    3       128.000000      128.000000      0.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.707107        0.000000        0.707107\r
+                       *MESH_FACENORMAL        1       0.707107        0.000000        0.707107\r
+                       *MESH_VERTEXNORMAL      0       0.000000        1.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      1       0.000000        1.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      2       0.000000        1.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      3       0.000000        1.000000        0.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       -2.000000       2.000000        1.000000\r
+                       *MESH_TVERT     1       -2.000000       0.000000        1.000000\r
+                       *MESH_TVERT     2       0.000000        2.000000        1.000000\r
+                       *MESH_TVERT     3       2.000000        0.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf2"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf2"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       64.000000       0.000000        64.000000\r
+                       *MESH_VERTEX    1       0.000000        0.000000        64.000000\r
+                       *MESH_VERTEX    2       64.000000       128.000000      64.000000\r
+                       *MESH_VERTEX    3       0.000000        128.000000      64.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.707107        0.000000        0.707107\r
+                       *MESH_FACENORMAL        1       0.707107        0.000000        0.707107\r
+                       *MESH_VERTEXNORMAL      0       0.000000        0.000000        1.000000\r
+                       *MESH_VERTEXNORMAL      1       0.000000        0.000000        1.000000\r
+                       *MESH_VERTEXNORMAL      2       0.000000        0.000000        1.000000\r
+                       *MESH_VERTEXNORMAL      3       0.000000        0.000000        1.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       1.000000        -1.000000       1.000000\r
+                       *MESH_TVERT     1       -1.000000       -1.000000       1.000000\r
+                       *MESH_TVERT     2       1.000000        3.000000        1.000000\r
+                       *MESH_TVERT     3       -1.000000       3.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf3"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf3"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       0.000000        0.000000        64.000000\r
+                       *MESH_VERTEX    1       0.000000        0.000000        0.000000\r
+                       *MESH_VERTEX    2       0.000000        128.000000      64.000000\r
+                       *MESH_VERTEX    3       0.000000        128.000000      0.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.707107        0.000000        0.707107\r
+                       *MESH_FACENORMAL        1       0.707107        0.000000        0.707107\r
+                       *MESH_VERTEXNORMAL      0       -1.000000       0.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      1       -1.000000       0.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      2       -1.000000       0.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      3       -1.000000       0.000000        0.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       -2.000000       2.000000        1.000000\r
+                       *MESH_TVERT     1       -2.000000       0.000000        1.000000\r
+                       *MESH_TVERT     2       2.000000        2.000000        1.000000\r
+                       *MESH_TVERT     3       2.000000        0.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf4"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf4"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       128.000000      0.000000        0.000000\r
+                       *MESH_VERTEX    1       0.000000        0.000000        0.000000\r
+                       *MESH_VERTEX    2       64.000000       0.000000        64.000000\r
+                       *MESH_VERTEX    3       0.000000        0.000000        64.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.707107        0.000000        0.707107\r
+                       *MESH_FACENORMAL        1       0.707107        0.000000        0.707107\r
+                       *MESH_VERTEXNORMAL      0       0.000000        -1.000000       0.000000\r
+                       *MESH_VERTEXNORMAL      1       0.000000        -1.000000       0.000000\r
+                       *MESH_VERTEXNORMAL      2       0.000000        -1.000000       0.000000\r
+                       *MESH_VERTEXNORMAL      3       0.000000        -1.000000       0.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       2.000000        0.000000        1.000000\r
+                       *MESH_TVERT     1       -2.000000       0.000000        1.000000\r
+                       *MESH_TVERT     2       0.000000        2.000000        1.000000\r
+                       *MESH_TVERT     3       -2.000000       2.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf5"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf5"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       0.000000        128.000000      0.000000\r
+                       *MESH_VERTEX    1       0.000000        0.000000        0.000000\r
+                       *MESH_VERTEX    2       128.000000      128.000000      0.000000\r
+                       *MESH_VERTEX    3       128.000000      0.000000        0.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.707107        0.000000        0.707107\r
+                       *MESH_FACENORMAL        1       0.707107        0.000000        0.707107\r
+                       *MESH_VERTEXNORMAL      0       0.000000        0.000000        -1.000000\r
+                       *MESH_VERTEXNORMAL      1       0.000000        0.000000        -1.000000\r
+                       *MESH_VERTEXNORMAL      2       0.000000        0.000000        -1.000000\r
+                       *MESH_VERTEXNORMAL      3       0.000000        0.000000        -1.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       -2.000000       3.000000        1.000000\r
+                       *MESH_TVERT     1       -2.000000       -1.000000       1.000000\r
+                       *MESH_TVERT     2       2.000000        3.000000        1.000000\r
+                       *MESH_TVERT     3       2.000000        -1.000000       1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
diff --git a/regression_tests/q3map2/model_clipping_45_degrees/models/mapobjects/wedges/wedge_shallow.ase b/regression_tests/q3map2/model_clipping_45_degrees/models/mapobjects/wedges/wedge_shallow.ase
new file mode 100644 (file)
index 0000000..4e23fd4
--- /dev/null
@@ -0,0 +1,368 @@
+*3DSMAX_ASCIIEXPORT    200\r
+*COMMENT       "Generated by Q3Map2 (ydnar) -convert -format ase"\r
+*SCENE {\r
+       *SCENE_FILENAME "wedge_shallow.bsp"\r
+       *SCENE_FIRSTFRAME       0\r
+       *SCENE_LASTFRAME        100\r
+       *SCENE_FRAMESPEED       30\r
+       *SCENE_TICKSPERFRAME    160\r
+       *SCENE_BACKGROUND_STATIC        0.0000  0.0000  0.0000\r
+       *SCENE_AMBIENT_STATIC   0.0000  0.0000  0.0000\r
+}\r
+*MATERIAL_LIST {\r
+       *MATERIAL_COUNT 2\r
+       *MATERIAL       0       {\r
+               *MATERIAL_NAME  "textures/radiant_regression_tests/tile_model"\r
+               *MATERIAL_CLASS "Standard"\r
+               *MATERIAL_DIFFUSE       1.000000        1.000000        0.833333\r
+               *MATERIAL_SHADING Phong\r
+               *MAP_DIFFUSE    {\r
+                       *MAP_NAME       "textures/radiant_regression_tests/tile_model"\r
+                       *MAP_CLASS      "Bitmap"\r
+                       *MAP_SUBNO      1\r
+                       *MAP_AMOUNT     1.0\r
+                       *MAP_TYPE       Screen\r
+                       *BITMAP "..\textures\radiant_regression_tests\tile_model.tga"\r
+                       *BITMAP_FILTER  Pyramidal\r
+               }\r
+       }\r
+       *MATERIAL       1       {\r
+               *MATERIAL_NAME  "noshader"\r
+               *MATERIAL_CLASS "Standard"\r
+               *MATERIAL_DIFFUSE       1.000000        1.000000        1.000000\r
+               *MATERIAL_SHADING Phong\r
+               *MAP_DIFFUSE    {\r
+                       *MAP_NAME       "noshader"\r
+                       *MAP_CLASS      "Bitmap"\r
+                       *MAP_SUBNO      1\r
+                       *MAP_AMOUNT     1.0\r
+                       *MAP_TYPE       Screen\r
+                       *BITMAP "..\noshader.tga"\r
+                       *BITMAP_FILTER  Pyramidal\r
+               }\r
+       }\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf0"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf0"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       160.000000      0.000000        0.000000\r
+                       *MESH_VERTEX    1       64.000000       0.000000        64.000000\r
+                       *MESH_VERTEX    2       160.000000      128.000000      0.000000\r
+                       *MESH_VERTEX    3       64.000000       128.000000      64.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.554700        0.000000        0.832050\r
+                       *MESH_FACENORMAL        1       0.554700        0.000000        0.832050\r
+                       *MESH_VERTEXNORMAL      0       0.554700        0.000000        0.832050\r
+                       *MESH_VERTEXNORMAL      1       0.554700        0.000000        0.832050\r
+                       *MESH_VERTEXNORMAL      2       0.554700        0.000000        0.832050\r
+                       *MESH_VERTEXNORMAL      3       0.554700        0.000000        0.832050\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       2.000000        -1.000000       1.000000\r
+                       *MESH_TVERT     1       -1.000000       -1.000000       1.000000\r
+                       *MESH_TVERT     2       2.000000        3.000000        1.000000\r
+                       *MESH_TVERT     3       -1.000000       3.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf1"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf1"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       0.000000        128.000000      64.000000\r
+                       *MESH_VERTEX    1       0.000000        128.000000      0.000000\r
+                       *MESH_VERTEX    2       64.000000       128.000000      64.000000\r
+                       *MESH_VERTEX    3       160.000000      128.000000      0.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.554700        0.000000        0.832050\r
+                       *MESH_FACENORMAL        1       0.554700        0.000000        0.832050\r
+                       *MESH_VERTEXNORMAL      0       0.000000        1.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      1       0.000000        1.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      2       0.000000        1.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      3       0.000000        1.000000        0.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       -2.000000       2.000000        1.000000\r
+                       *MESH_TVERT     1       -2.000000       0.000000        1.000000\r
+                       *MESH_TVERT     2       0.000000        2.000000        1.000000\r
+                       *MESH_TVERT     3       3.000000        0.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf2"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf2"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       64.000000       0.000000        64.000000\r
+                       *MESH_VERTEX    1       0.000000        0.000000        64.000000\r
+                       *MESH_VERTEX    2       64.000000       128.000000      64.000000\r
+                       *MESH_VERTEX    3       0.000000        128.000000      64.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.554700        0.000000        0.832050\r
+                       *MESH_FACENORMAL        1       0.554700        0.000000        0.832050\r
+                       *MESH_VERTEXNORMAL      0       0.000000        0.000000        1.000000\r
+                       *MESH_VERTEXNORMAL      1       0.000000        0.000000        1.000000\r
+                       *MESH_VERTEXNORMAL      2       0.000000        0.000000        1.000000\r
+                       *MESH_VERTEXNORMAL      3       0.000000        0.000000        1.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       1.000000        -1.000000       1.000000\r
+                       *MESH_TVERT     1       -1.000000       -1.000000       1.000000\r
+                       *MESH_TVERT     2       1.000000        3.000000        1.000000\r
+                       *MESH_TVERT     3       -1.000000       3.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf3"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf3"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       0.000000        0.000000        64.000000\r
+                       *MESH_VERTEX    1       0.000000        0.000000        0.000000\r
+                       *MESH_VERTEX    2       0.000000        128.000000      64.000000\r
+                       *MESH_VERTEX    3       0.000000        128.000000      0.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.554700        0.000000        0.832050\r
+                       *MESH_FACENORMAL        1       0.554700        0.000000        0.832050\r
+                       *MESH_VERTEXNORMAL      0       -1.000000       0.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      1       -1.000000       0.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      2       -1.000000       0.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      3       -1.000000       0.000000        0.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       -2.000000       2.000000        1.000000\r
+                       *MESH_TVERT     1       -2.000000       0.000000        1.000000\r
+                       *MESH_TVERT     2       2.000000        2.000000        1.000000\r
+                       *MESH_TVERT     3       2.000000        0.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf4"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf4"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       160.000000      0.000000        0.000000\r
+                       *MESH_VERTEX    1       0.000000        0.000000        0.000000\r
+                       *MESH_VERTEX    2       64.000000       0.000000        64.000000\r
+                       *MESH_VERTEX    3       0.000000        0.000000        64.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.554700        0.000000        0.832050\r
+                       *MESH_FACENORMAL        1       0.554700        0.000000        0.832050\r
+                       *MESH_VERTEXNORMAL      0       0.000000        -1.000000       0.000000\r
+                       *MESH_VERTEXNORMAL      1       0.000000        -1.000000       0.000000\r
+                       *MESH_VERTEXNORMAL      2       0.000000        -1.000000       0.000000\r
+                       *MESH_VERTEXNORMAL      3       0.000000        -1.000000       0.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       3.000000        0.000000        1.000000\r
+                       *MESH_TVERT     1       -2.000000       0.000000        1.000000\r
+                       *MESH_TVERT     2       0.000000        2.000000        1.000000\r
+                       *MESH_TVERT     3       -2.000000       2.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf5"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf5"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       0.000000        128.000000      0.000000\r
+                       *MESH_VERTEX    1       0.000000        0.000000        0.000000\r
+                       *MESH_VERTEX    2       160.000000      128.000000      0.000000\r
+                       *MESH_VERTEX    3       160.000000      0.000000        0.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.554700        0.000000        0.832050\r
+                       *MESH_FACENORMAL        1       0.554700        0.000000        0.832050\r
+                       *MESH_VERTEXNORMAL      0       0.000000        0.000000        -1.000000\r
+                       *MESH_VERTEXNORMAL      1       0.000000        0.000000        -1.000000\r
+                       *MESH_VERTEXNORMAL      2       0.000000        0.000000        -1.000000\r
+                       *MESH_VERTEXNORMAL      3       0.000000        0.000000        -1.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       -2.000000       3.000000        1.000000\r
+                       *MESH_TVERT     1       -2.000000       -1.000000       1.000000\r
+                       *MESH_TVERT     2       3.000000        3.000000        1.000000\r
+                       *MESH_TVERT     3       3.000000        -1.000000       1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
diff --git a/regression_tests/q3map2/model_clipping_45_degrees/models/mapobjects/wedges/wedge_steep.ase b/regression_tests/q3map2/model_clipping_45_degrees/models/mapobjects/wedges/wedge_steep.ase
new file mode 100644 (file)
index 0000000..0e8727e
--- /dev/null
@@ -0,0 +1,368 @@
+*3DSMAX_ASCIIEXPORT    200\r
+*COMMENT       "Generated by Q3Map2 (ydnar) -convert -format ase"\r
+*SCENE {\r
+       *SCENE_FILENAME "wedge_steep.bsp"\r
+       *SCENE_FIRSTFRAME       0\r
+       *SCENE_LASTFRAME        100\r
+       *SCENE_FRAMESPEED       30\r
+       *SCENE_TICKSPERFRAME    160\r
+       *SCENE_BACKGROUND_STATIC        0.0000  0.0000  0.0000\r
+       *SCENE_AMBIENT_STATIC   0.0000  0.0000  0.0000\r
+}\r
+*MATERIAL_LIST {\r
+       *MATERIAL_COUNT 2\r
+       *MATERIAL       0       {\r
+               *MATERIAL_NAME  "textures/radiant_regression_tests/tile_model"\r
+               *MATERIAL_CLASS "Standard"\r
+               *MATERIAL_DIFFUSE       1.000000        1.000000        0.833333\r
+               *MATERIAL_SHADING Phong\r
+               *MAP_DIFFUSE    {\r
+                       *MAP_NAME       "textures/radiant_regression_tests/tile_model"\r
+                       *MAP_CLASS      "Bitmap"\r
+                       *MAP_SUBNO      1\r
+                       *MAP_AMOUNT     1.0\r
+                       *MAP_TYPE       Screen\r
+                       *BITMAP "..\textures\radiant_regression_tests\tile_model.tga"\r
+                       *BITMAP_FILTER  Pyramidal\r
+               }\r
+       }\r
+       *MATERIAL       1       {\r
+               *MATERIAL_NAME  "noshader"\r
+               *MATERIAL_CLASS "Standard"\r
+               *MATERIAL_DIFFUSE       1.000000        1.000000        1.000000\r
+               *MATERIAL_SHADING Phong\r
+               *MAP_DIFFUSE    {\r
+                       *MAP_NAME       "noshader"\r
+                       *MAP_CLASS      "Bitmap"\r
+                       *MAP_SUBNO      1\r
+                       *MAP_AMOUNT     1.0\r
+                       *MAP_TYPE       Screen\r
+                       *BITMAP "..\noshader.tga"\r
+                       *BITMAP_FILTER  Pyramidal\r
+               }\r
+       }\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf0"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf0"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       112.000000      0.000000        0.000000\r
+                       *MESH_VERTEX    1       64.000000       0.000000        64.000000\r
+                       *MESH_VERTEX    2       112.000000      128.000000      0.000000\r
+                       *MESH_VERTEX    3       64.000000       128.000000      64.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.800000        0.000000        0.600000\r
+                       *MESH_FACENORMAL        1       0.800000        0.000000        0.600000\r
+                       *MESH_VERTEXNORMAL      0       0.800000        0.000000        0.600000\r
+                       *MESH_VERTEXNORMAL      1       0.800000        0.000000        0.600000\r
+                       *MESH_VERTEXNORMAL      2       0.800000        0.000000        0.600000\r
+                       *MESH_VERTEXNORMAL      3       0.800000        0.000000        0.600000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       -2.000000       0.000000        1.000000\r
+                       *MESH_TVERT     1       -2.000000       2.000000        1.000000\r
+                       *MESH_TVERT     2       2.000000        0.000000        1.000000\r
+                       *MESH_TVERT     3       2.000000        2.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf1"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf1"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       0.000000        128.000000      64.000000\r
+                       *MESH_VERTEX    1       0.000000        128.000000      0.000000\r
+                       *MESH_VERTEX    2       64.000000       128.000000      64.000000\r
+                       *MESH_VERTEX    3       112.000000      128.000000      0.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.800000        0.000000        0.600000\r
+                       *MESH_FACENORMAL        1       0.800000        0.000000        0.600000\r
+                       *MESH_VERTEXNORMAL      0       0.000000        1.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      1       0.000000        1.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      2       0.000000        1.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      3       0.000000        1.000000        0.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       -1.000000       2.000000        1.000000\r
+                       *MESH_TVERT     1       -1.000000       0.000000        1.000000\r
+                       *MESH_TVERT     2       1.000000        2.000000        1.000000\r
+                       *MESH_TVERT     3       2.500000        0.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf2"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf2"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       64.000000       0.000000        64.000000\r
+                       *MESH_VERTEX    1       0.000000        0.000000        64.000000\r
+                       *MESH_VERTEX    2       64.000000       128.000000      64.000000\r
+                       *MESH_VERTEX    3       0.000000        128.000000      64.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.800000        0.000000        0.600000\r
+                       *MESH_FACENORMAL        1       0.800000        0.000000        0.600000\r
+                       *MESH_VERTEXNORMAL      0       0.000000        0.000000        1.000000\r
+                       *MESH_VERTEXNORMAL      1       0.000000        0.000000        1.000000\r
+                       *MESH_VERTEXNORMAL      2       0.000000        0.000000        1.000000\r
+                       *MESH_VERTEXNORMAL      3       0.000000        0.000000        1.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       1.000000        -1.000000       1.000000\r
+                       *MESH_TVERT     1       -1.000000       -1.000000       1.000000\r
+                       *MESH_TVERT     2       1.000000        3.000000        1.000000\r
+                       *MESH_TVERT     3       -1.000000       3.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf3"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf3"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       0.000000        0.000000        64.000000\r
+                       *MESH_VERTEX    1       0.000000        0.000000        0.000000\r
+                       *MESH_VERTEX    2       0.000000        128.000000      64.000000\r
+                       *MESH_VERTEX    3       0.000000        128.000000      0.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.800000        0.000000        0.600000\r
+                       *MESH_FACENORMAL        1       0.800000        0.000000        0.600000\r
+                       *MESH_VERTEXNORMAL      0       -1.000000       0.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      1       -1.000000       0.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      2       -1.000000       0.000000        0.000000\r
+                       *MESH_VERTEXNORMAL      3       -1.000000       0.000000        0.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       -2.000000       2.000000        1.000000\r
+                       *MESH_TVERT     1       -2.000000       0.000000        1.000000\r
+                       *MESH_TVERT     2       2.000000        2.000000        1.000000\r
+                       *MESH_TVERT     3       2.000000        0.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf4"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf4"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       112.000000      0.000000        0.000000\r
+                       *MESH_VERTEX    1       0.000000        0.000000        0.000000\r
+                       *MESH_VERTEX    2       64.000000       0.000000        64.000000\r
+                       *MESH_VERTEX    3       0.000000        0.000000        64.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.800000        0.000000        0.600000\r
+                       *MESH_FACENORMAL        1       0.800000        0.000000        0.600000\r
+                       *MESH_VERTEXNORMAL      0       0.000000        -1.000000       0.000000\r
+                       *MESH_VERTEXNORMAL      1       0.000000        -1.000000       0.000000\r
+                       *MESH_VERTEXNORMAL      2       0.000000        -1.000000       0.000000\r
+                       *MESH_VERTEXNORMAL      3       0.000000        -1.000000       0.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       2.500000        0.000000        1.000000\r
+                       *MESH_TVERT     1       -1.000000       0.000000        1.000000\r
+                       *MESH_TVERT     2       1.000000        2.000000        1.000000\r
+                       *MESH_TVERT     3       -1.000000       2.000000        1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
+*GEOMOBJECT    {\r
+       *NODE_NAME      "mat0model0surf5"\r
+       *NODE_TM        {\r
+               *NODE_NAME      "mat0model0surf5"\r
+               *INHERIT_POS    0       0       0\r
+               *INHERIT_ROT    0       0       0\r
+               *INHERIT_SCL    0       0       0\r
+               *TM_ROW0        1.0     0       0\r
+               *TM_ROW1        0       1.0     0\r
+               *TM_ROW2        0       0       1.0\r
+               *TM_ROW3        0       0       0\r
+               *TM_POS 0.000000        0.000000        0.000000\r
+       }\r
+       *MESH   {\r
+               *TIMEVALUE      0\r
+               *MESH_NUMVERTEX 4\r
+               *MESH_NUMFACES  2\r
+               *COMMENT        "SURFACETYPE    MST_PLANAR"\r
+               *MESH_VERTEX_LIST       {\r
+                       *MESH_VERTEX    0       0.000000        128.000000      0.000000\r
+                       *MESH_VERTEX    1       0.000000        0.000000        0.000000\r
+                       *MESH_VERTEX    2       112.000000      128.000000      0.000000\r
+                       *MESH_VERTEX    3       112.000000      0.000000        0.000000\r
+               }\r
+               *MESH_NORMALS   {\r
+                       *MESH_FACENORMAL        0       0.800000        0.000000        0.600000\r
+                       *MESH_FACENORMAL        1       0.800000        0.000000        0.600000\r
+                       *MESH_VERTEXNORMAL      0       0.000000        0.000000        -1.000000\r
+                       *MESH_VERTEXNORMAL      1       0.000000        0.000000        -1.000000\r
+                       *MESH_VERTEXNORMAL      2       0.000000        0.000000        -1.000000\r
+                       *MESH_VERTEXNORMAL      3       0.000000        0.000000        -1.000000\r
+               }\r
+               *MESH_FACE_LIST {\r
+                       *MESH_FACE      0       A:      0       B:      2       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+                       *MESH_FACE      1       A:      2       B:      3       C:      1       AB:     1       BC:     1       CA:     1       *MESH_SMOOTHING 0       *MESH_MTLID     0\r
+               }\r
+               *MESH_NUMTVERTEX        4\r
+               *MESH_TVERTLIST {\r
+                       *MESH_TVERT     0       -1.000000       3.000000        1.000000\r
+                       *MESH_TVERT     1       -1.000000       -1.000000       1.000000\r
+                       *MESH_TVERT     2       2.500000        3.000000        1.000000\r
+                       *MESH_TVERT     3       2.500000        -1.000000       1.000000\r
+               }\r
+               *MESH_NUMTVFACES        2\r
+               *MESH_TFACELIST {\r
+                       *MESH_TFACE     0       0       2       1\r
+                       *MESH_TFACE     1       2       3       1\r
+               }\r
+       }\r
+       *PROP_MOTIONBLUR        0\r
+       *PROP_CASTSHADOW        1\r
+       *PROP_RECVSHADOW        1\r
+       *MATERIAL_REF   0\r
+}\r
diff --git a/regression_tests/q3map2/model_clipping_45_degrees/scripts/radiant_regression_tests.shader b/regression_tests/q3map2/model_clipping_45_degrees/scripts/radiant_regression_tests.shader
new file mode 100644 (file)
index 0000000..a2c31ed
--- /dev/null
@@ -0,0 +1,12 @@
+textures/radiant_regression_tests/tile_model
+{
+    q3map_clipModel
+    q3map_forceMeta
+    {
+        map $lightmap
+    }
+    {
+        map textures/radiant_regression_tests/tile_model.tga
+        blendFunc filter
+    }
+}
diff --git a/regression_tests/q3map2/piercing_triangle/README.txt b/regression_tests/q3map2/piercing_triangle/README.txt
new file mode 100644 (file)
index 0000000..b09e2c3
--- /dev/null
@@ -0,0 +1,14 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+In the disappearing_triangle regression test I outlined a potential problem
+in the tjunction.c code, having to do with 2 points being too close together
+on a winding, and that winding becoming invalid (drawsurf disappearing).
+
+This example map is the same as disappearing_triangle.map, except that the
+floor is raised by 1 unit.  Therefore the floor intersects the sliver triangle.
+The resulting chopped sliver has a very short edge that is "degenerate" and
+causes that draw surf to go away due to problems in the tjunction.c code.
+
+This is speculation at this point.  I will provide more info after the bug has
+been fixed.
diff --git a/regression_tests/q3map2/piercing_triangle/maps/piercing_triangle.map b/regression_tests/q3map2/piercing_triangle/maps/piercing_triangle.map
new file mode 100644 (file)
index 0000000..8dc3552
--- /dev/null
@@ -0,0 +1,73 @@
+{
+"classname" "worldspawn"
+{
+( 134 -1015 0 ) ( 134 -4096 0 ) ( 67 -1022 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 88 -892 -768 ) ( 88 -4096 -768 ) ( 134 -1015 0 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 67 -1022 0 ) ( 88 -892 -768 ) ( 134 -1015 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+( 67 -1022 0 ) ( 67 -4096 0 ) ( 88 -892 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( -704 -1152 0 ) ( 4480 -1152 0 ) ( -704 -1152 -768 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+}
+{
+( 512 -640 0 ) ( 512 -1160 0 ) ( 512 -1160 -768 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 584 -640 0 ) ( 520 -640 0 ) ( 520 -640 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 520 -1160 0 ) ( 520 -640 0 ) ( 520 -640 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 528 -1152 0 ) ( 592 -1152 0 ) ( 592 -1152 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 528 -1160 320 ) ( 528 -640 320 ) ( 592 -640 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 583 -640 -768 ) ( 519 -640 -768 ) ( 519 -1160 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -512 -536 320 ) ( -512 -624 320 ) ( -512 -624 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 528 -632 320 ) ( -280 -632 320 ) ( -280 -632 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -640 320 ) ( 512 -552 320 ) ( 512 -552 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -296 -640 320 ) ( 512 -640 320 ) ( 512 -640 -768 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -296 -640 320 ) ( -296 -552 320 ) ( 512 -552 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 511 -552 -768 ) ( -297 -552 -768 ) ( -297 -640 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -520 -648 320 ) ( -520 -1152 320 ) ( -520 -1152 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -640 320 ) ( -536 -640 320 ) ( -536 -640 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -1152 320 ) ( -512 -648 320 ) ( -512 -648 -768 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -536 -1152 320 ) ( -512 -1152 320 ) ( -512 -1152 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -536 -1152 320 ) ( -536 -648 320 ) ( -512 -648 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -648 -768 ) ( -536 -648 -768 ) ( -536 -1152 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -512 -640 464 ) ( -512 -1152 464 ) ( -512 -1152 352 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -640 440 ) ( 24 -640 440 ) ( 24 -640 328 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -1152 440 ) ( 512 -640 440 ) ( 512 -640 328 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 24 -1152 440 ) ( 512 -1152 440 ) ( 512 -1152 328 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 48 -1152 328 ) ( 48 -640 328 ) ( 536 -640 328 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -640 320 ) ( 24 -640 320 ) ( 24 -1152 320 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( -368 -640 -824 ) ( -856 -640 -824 ) ( -856 -640 -960 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -1152 -768 ) ( 512 -896 -768 ) ( 512 -896 -776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -896 -768 ) ( -512 -1152 -768 ) ( -512 -1152 -776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -1152 -768 ) ( -328 -1152 -768 ) ( -328 -1152 -776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -511 -1152 -767 ) ( -511 -896 -767 ) ( -327 -896 -767 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -328 -896 -776 ) ( -512 -896 -776 ) ( -512 -1152 -776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -256 -1152 -768 ) ( -520 -1152 -768 ) ( -520 -1192 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 176 -1568 320 ) ( 176 -1152 320 ) ( 1152 -1152 320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 208 -1160 320 ) ( 1184 -1160 320 ) ( 1184 -1160 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -1576 320 ) ( 512 -1160 320 ) ( 512 -1160 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 1152 -1152 320 ) ( 176 -1152 320 ) ( 176 -1152 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -512 -1168 320 ) ( -512 -1584 320 ) ( -512 -1584 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+}
+{
+"classname" "light"
+"origin" "0 -768 -480"
+"light" "3000"
+}
+{
+"classname" "info_player_deathmatch"
+"origin" "0 -712 -640"
+"angle" "270"
+}
+{
+"light" "3000"
+"origin" "0 -832 160"
+"classname" "light"
+}
diff --git a/regression_tests/q3map2/plane_aliasing/README.txt b/regression_tests/q3map2/plane_aliasing/README.txt
new file mode 100644 (file)
index 0000000..c76d574
--- /dev/null
@@ -0,0 +1,129 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+This example map demonstrates what a relatively large value for plane distance
+epsilon can do as far as destroying draw surfaces.  The plane distance
+epsilon was 0.01 at the time of this writing.  This means that two planes
+with the same normal and a distance 0.00999 apart are considered to be the
+same plane.
+
+The recommended value of plane distance epsilon is more along the lines of
+0.001; however, we can't currently change this epsilon to that value due to
+lack of resolution in 32 bit floating point integers in the 2^16 number range.
+The smallest epsilon in 32 bit float land that can be added to 2^16 that
+results in a value greater than 2^16 is approximately 0.007, which is already
+practically the current default plane distance epsilon (0.01).
+
+Brush 0 in the example map is a 6-sided brush with red top face.  The red top
+face is defined such in the .map file:
+
+  ( -127 256 513 ) ( -127 384 513 ) ( 1 384 512 )
+
+During the -bsp stage,
+
+  In ParseRawBrush() for brush 0
+      Side 4:
+          (-127.000000 256.000000 513.000000)
+          (-127.000000 384.000000 513.000000)
+          (1.000000 384.000000 512.000000)
+          normal: (0.0078122616 0.0000000000 0.9999694824)
+          dist: 511.9921875000
+
+Now brush 1, the 4-sided brush with the red top face, has the following
+defined as the red top face:
+
+  ( -128 0 513 ) ( -128 128 513 ) ( 0 128 512 )
+
+It's almost the same plane, only off by a distance of about 0.01.
+
+During compiling:
+
+  In ParseRawBrush() for brush 1
+      Side 1:
+          (-128.000000 0.000000 513.000000)
+          (-128.000000 128.000000 513.000000)
+          (0.000000 128.000000 512.000000)
+          normal: (0.0078122616 0.0000000000 0.9999694824)
+          dist: 511.9921875000
+
+Note that the normal and dist are identical to the plane above, even though
+the two are different.  This leads to multiplying errors later on, when this
+side is intersected with the bottom green face.  In particular, the blue face
+disappears from the map.  The blue face:
+
+  In CreateBrushWindings() for brush 1
+      Handling side 2 on the brush
+          Before clipping we have:
+              (-262144.00000000 0.00000000 262144.00000000)
+              (262144.00000000 0.00000000 262144.00000000)
+              (262144.00000000 -0.00000000 -262144.00000000)
+              (-262144.00000000 0.00000000 -262144.00000000)
+          After clipping w/ side 0 we have:
+              (-262144.00000000 0.00000000 262144.00000000)
+              (262144.00000000 0.00000000 262144.00000000)
+              (262144.00000000 0.00000000 -19977.00073172)
+              (-262144.00000000 0.00000000 20983.00073758)
+          After clipping w/ side 1 we have:
+              (262144.00000000 0.00000000 -1535.99218726)
+              (262144.00000000 0.00000000 -19977.00073172)
+              (-128.11106773 0.00000000 513.00868046)
+          After clipping w/ side 3 we have:
+              (0.00000000 0.00000000 503.00000293)
+              (-128.11106773 0.00000000 513.00868046)
+              (-0.00000000 0.00000000 512.00781274)
+
+We see the error is greater than 0.1 in the X value -128.11106773.  This
+causes the draw surface to be discarded in processing later on.  We must
+not allow such a great error.  An error greater than or equal to 0.1 is
+considered to be very bad.
+
+This disappearing blue triangle can be fixed simply by deleting brush 0,
+the 6-sided brush that causes the bad plane alias.  I would suggest deleting
+this brush by editing the .map file manually (and then renumbering the brushes
+manually).
+
+After deleting this brush:
+
+  In ParseRawBrush() for brush 0
+      Side 1:
+          (-128.000000 0.000000 513.000000)
+          (-128.000000 128.000000 513.000000)
+          (0.000000 128.000000 512.000000)
+          normal: (0.0078122616 0.0000000000 0.9999694824)
+          dist: 511.9843750000
+
+  In CreateBrushWindings() for brush 0
+      Handling side 1 on the brush
+          Before clipping we have:
+              (262132.00000000 262136.00000000 -1535.90625143)
+              (262132.00000000 -262136.00000000 -1535.90625143)
+              (-262124.00048828 -262136.00000000 2559.84375238)
+              (-262124.00048828 262136.00000000 2559.84375238)
+          After clipping w/ side 0 we have:
+              (262132.00000000 262136.00000000 -1535.90625143)
+              (262132.00000000 -262136.00000000 -1535.90625143)
+              (-127.99993289 -262136.00000000 512.99999805)
+              (-127.99993289 262136.00000000 512.99999805)
+          After clipping w/ side 2 we have:
+              (262132.00000000 262136.00000000 -1535.90625143)
+              (262132.00000000 -0.00000000 -1535.90625143)
+              (-127.99993289 -0.00000000 512.99999805)
+              (-127.99993289 262136.00000000 512.99999805)
+          After clipping w/ side 3 we have:
+              (0.00000000 0.00000000 511.99999857)
+              (-127.99993289 -0.00000000 512.99999805)
+              (-127.99993289 127.99993289 512.99999805)
+
+Note that we're way more accurate now, and we're nowhere near to approaching
+the 0.1 error.  All it took was the deletion of a seemintly unrelated brush.
+
+
+SOLUTION TO PROBLEM:
+====================
+
+The suggested fix is to increase the resolution of plane distance from 32 bit
+float to 64 bit float for the relevant brush processing operations.  After that
+is done, decrease the default plane distance epsilon from 0.01 to 0.001.  Note
+that even though plane distance epsilon can be specified on the command-line,
+it will do no good (even if set to 0) if the plane distance is close to
+2^16.
diff --git a/regression_tests/q3map2/plane_aliasing/maps/plane_aliasing.map b/regression_tests/q3map2/plane_aliasing/maps/plane_aliasing.map
new file mode 100644 (file)
index 0000000..070d7ba
--- /dev/null
@@ -0,0 +1,74 @@
+{
+"classname" "worldspawn"
+{
+( -127 384 513 ) ( -127 256 513 ) ( -127 256 384 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 1 384 512 ) ( -127 384 512 ) ( -127 384 384 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 1 256 512 ) ( 1 384 512 ) ( 1 384 384 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -127 256 512 ) ( 1 256 512 ) ( 1 256 384 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -127 256 513 ) ( -127 384 513 ) ( 1 384 512 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+( 1 384 384 ) ( -127 384 384 ) ( -127 256 384 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 0 128 503 ) ( -128 128 513 ) ( 0 0 503 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( -128 0 513 ) ( -128 128 513 ) ( 0 128 512 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+( -128 0 512 ) ( 0 0 512 ) ( 0 0 384 ) radiant_regression_tests/blue 0 0 0 0.500000 0.500000 0 0 0
+( -128 128 503 ) ( 0 0 503 ) ( -128 128 513 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( -128 472 8 ) ( -128 320 8 ) ( -128 320 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -232 512 8 ) ( -416 512 8 ) ( -416 512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -304 8 ) ( 512 -152 8 ) ( 512 -152 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 48 -512 8 ) ( 232 -512 8 ) ( 232 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -432 232 0 ) ( -432 384 0 ) ( -248 384 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -256 384 -8 ) ( -440 384 -8 ) ( -440 232 -8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -136 512 1040 ) ( -136 -512 1040 ) ( -136 -512 8 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 512 1032 ) ( -520 512 1032 ) ( -520 512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -128 -512 1032 ) ( -128 512 1032 ) ( -128 512 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -520 -512 1032 ) ( -512 -512 1032 ) ( -512 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -520 -512 1024 ) ( -520 512 1024 ) ( -512 512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 512 0 ) ( -520 512 0 ) ( -520 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 512 512 1024 ) ( 512 -512 1024 ) ( 512 -512 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 592 512 1024 ) ( 512 512 1024 ) ( 512 512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 520 -512 1000 ) ( 520 512 1000 ) ( 520 512 -24 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -512 1024 ) ( 592 -512 1024 ) ( 592 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -512 1024 ) ( 512 512 1024 ) ( 592 512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 592 512 0 ) ( 512 512 0 ) ( 512 -512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -128 512 1200 ) ( -128 -512 1200 ) ( -128 -512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 512 1200 ) ( -512 512 1200 ) ( -512 512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -512 1200 ) ( 512 512 1200 ) ( 512 512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -512 1200 ) ( 512 -512 1200 ) ( 512 -512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -456 -512 1032 ) ( -456 512 1032 ) ( 568 512 1032 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 512 1024 ) ( -512 512 1024 ) ( -512 -512 1024 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( -128 712 1024 ) ( -128 512 1024 ) ( -128 512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 520 1040 ) ( -512 520 1040 ) ( -512 520 16 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 512 1024 ) ( 512 712 1024 ) ( 512 712 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 512 1024 ) ( 512 512 1024 ) ( 512 512 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -512 512 1024 ) ( -512 712 1024 ) ( 512 712 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 712 0 ) ( -512 712 0 ) ( -512 512 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -128 -512 1024 ) ( -128 -624 1024 ) ( -128 -624 56 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -512 1024 ) ( -512 -512 1024 ) ( -512 -512 56 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 512 -624 1024 ) ( 512 -512 1024 ) ( 512 -512 56 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -520 1048 ) ( 512 -520 1048 ) ( 512 -520 80 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -512 -624 1024 ) ( -512 -512 1024 ) ( 512 -512 1024 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 512 -504 0 ) ( -512 -504 0 ) ( -512 -616 0 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+}
+{
+"classname" "light"
+"origin" "192 64 640"
+"light" "3000"
+}
+{
+"classname" "info_player_deathmatch"
+"origin" "-64 64 640"
+}
diff --git a/regression_tests/q3map2/segmentation_fault/README.txt b/regression_tests/q3map2/segmentation_fault/README.txt
new file mode 100644 (file)
index 0000000..05f30d2
--- /dev/null
@@ -0,0 +1,27 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+The example map, maps/segmentation_fault.map, contains an example of this
+bug.  q3map2 might segfault while compiling this map.  This sort of thing
+might happen in certain intermediate versions of q3map2 while work is being
+done on fixing the math accuracy.  The bug may not have happened in older
+version of q3map2, before the math accuracy issues were addressed.
+
+To trigger the bug, compile the map; you don't need -vis or -light.  Only
+-bsp (the first q3map2 stage) is necessary to trigger the bug.  The only
+entities in the map are a light and a info_player_deathmatch, so the map will
+compile for any Q3 mod.
+
+Here is a description of the problem brush (brush #0):
+
+  side 0: -z face
+  side 1: +z face
+  side 2: -y face
+  side 3: +x face
+  side 4: +y face
+  side 5: -x face
+  side 6: problem side "accidentally showed up" :-)
+
+Side 6 is actually a superfluous plane and will be NULL'ed out in the code.
+If the code does not handle a NULL'ed out winding correctly, it will
+segfault.
diff --git a/regression_tests/q3map2/segmentation_fault/maps/segmentation_fault.map b/regression_tests/q3map2/segmentation_fault/maps/segmentation_fault.map
new file mode 100644 (file)
index 0000000..610e785
--- /dev/null
@@ -0,0 +1,69 @@
+{
+"classname" "worldspawn"
+{
+( 10296 17600 -592 ) ( 10240 17600 -592 ) ( 10240 17472 -592 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 257 0
+( 10280 17472 -576 ) ( 10280 17600 -576 ) ( 10336 17600 -576 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 257 0
+( 10280 17472 -576 ) ( 10336 17472 -576 ) ( 10336 17472 -1600 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 257 0
+( 10367 17472 -576 ) ( 10367 17600 -576 ) ( 10367 17600 -1600 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 257 0
+( 10328 17727 -576 ) ( 10272 17727 -576 ) ( 10272 17727 -1600 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 257 0
+( 10240 17608 -576 ) ( 10240 17480 -576 ) ( 10240 17480 -1600 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 257 0
+( 10240 17727 -576 ) ( 10240 17726 -621 ) ( 10335 17727 -576 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 257 0
+}
+{
+( 10504 17800 -768 ) ( 10112 17800 -768 ) ( 10112 17792 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10112 17792 -320 ) ( 10112 17800 -320 ) ( 10504 17800 -320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10112 17792 -576 ) ( 10504 17792 -576 ) ( 10504 17792 -592 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 10496 17792 -576 ) ( 10496 17800 -576 ) ( 10496 17800 -592 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10504 17800 -576 ) ( 10112 17800 -576 ) ( 10112 17800 -592 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10112 17800 -576 ) ( 10112 17792 -576 ) ( 10112 17792 -592 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 10496 17408 -768 ) ( 10112 17408 -768 ) ( 10112 17392 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10112 17384 -320 ) ( 10112 17400 -320 ) ( 10496 17400 -320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10112 17400 -544 ) ( 10496 17400 -544 ) ( 10496 17400 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10496 17392 -544 ) ( 10496 17408 -544 ) ( 10496 17408 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10496 17408 -544 ) ( 10112 17408 -544 ) ( 10112 17408 -768 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 10112 17408 -544 ) ( 10112 17392 -544 ) ( 10112 17392 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 10568 17784 -768 ) ( 10496 17784 -768 ) ( 10496 17408 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10496 17408 -320 ) ( 10496 17784 -320 ) ( 10568 17784 -320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10496 17408 -320 ) ( 10568 17408 -320 ) ( 10568 17408 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10504 17400 -320 ) ( 10504 17776 -320 ) ( 10504 17776 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10568 17792 -320 ) ( 10496 17792 -320 ) ( 10496 17792 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10496 17784 -320 ) ( 10496 17408 -320 ) ( 10496 17408 -768 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 10112 17792 -768 ) ( 10072 17792 -768 ) ( 10072 17408 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10072 17408 -320 ) ( 10072 17792 -320 ) ( 10112 17792 -320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10072 17408 -320 ) ( 10112 17408 -320 ) ( 10112 17408 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10112 17408 -320 ) ( 10112 17792 -320 ) ( 10112 17792 -768 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 10112 17792 -320 ) ( 10072 17792 -320 ) ( 10072 17792 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10104 17792 -320 ) ( 10104 17408 -320 ) ( 10104 17408 -768 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 10496 17792 -320 ) ( 10112 17792 -320 ) ( 10112 17408 -320 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 10112 17408 -312 ) ( 10112 17792 -312 ) ( 10496 17792 -312 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10112 17408 -232 ) ( 10496 17408 -232 ) ( 10496 17408 -320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10496 17408 -232 ) ( 10496 17792 -232 ) ( 10496 17792 -320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10496 17792 -232 ) ( 10112 17792 -232 ) ( 10112 17792 -320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10112 17792 -232 ) ( 10112 17408 -232 ) ( 10112 17408 -320 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 10496 17792 -776 ) ( 10112 17792 -776 ) ( 10112 17408 -776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10112 17408 -768 ) ( 10112 17792 -768 ) ( 10496 17792 -768 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 10112 17408 -768 ) ( 10496 17408 -768 ) ( 10496 17408 -856 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10496 17408 -768 ) ( 10496 17792 -768 ) ( 10496 17792 -856 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10496 17792 -768 ) ( 10112 17792 -768 ) ( 10112 17792 -856 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 10112 17792 -768 ) ( 10112 17408 -768 ) ( 10112 17408 -856 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+}
+{
+"origin" "10312 17600 -480"
+"classname" "info_player_deathmatch"
+}
+{
+"light" "1000"
+"origin" "10240 17608 -464"
+"classname" "light"
+}
diff --git a/regression_tests/q3map2/snap_plane/README.txt b/regression_tests/q3map2/snap_plane/README.txt
new file mode 100644 (file)
index 0000000..d66196b
--- /dev/null
@@ -0,0 +1,45 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+The example map, maps/snap_plane.map, contains an example of some bugs.
+The green brush with the red face is transformed into something totally
+unexpected.
+
+To trigger the bug, compile the map; you don't need -vis or -light.  Only
+-bsp (the first q3map2 stage) is necessary to trigger the bug.  The only
+entities in the map are a light and a info_player_deathmatch, so the map will
+compile for any Q3 mod.
+
+
+SOLUTION TO PROBLEM:
+====================
+
+I actually came up with this regression test after reading the code to
+SnapPlane() and SnapNormal().  I decided to make this map as a test of
+whether or not I understand how the code is broken.  Sure enough, the map
+is broken in the same way that I would expect it to be broken.
+
+The problem is that the red face of the green brush in the center of the room
+is very close to being axially aligned, but not quite.  This plane will
+therefore be "snapped" to become axial.  This is not the problem.  The
+problem is that after the snap, the plane will be shifted a great deal,
+and the corner of the green brush will no longer come even close to meeting
+the corner of the other cube brush next to it (the two corners of the two
+brushes will drift apart a great deal).
+
+If you study the legacy SnapPlane() code, you will see that planes are
+defined as a unit normal and distance from origin.  Well, because
+of the position of this brush on the side of the world extents (far from
+the original), the snap will cause drastic effects on the points that the
+plane was supposed to approximate.
+
+Another problem with SnapPlane() is that SnapNormal() snaps too liberally.
+Once SnapNormal() is changed to only snap normals that are REALLY close
+to axial (and not anything within 0.25 degrees), this bug will no longer
+appear, but the SnapPlane() problem will still be present.  So, this
+regression test should be fixed BEFORE SnapNormal() is fixed, otherwise
+create another regression test with a red face that is much much closer to
+being axially aligned.  We want to make sure that SnapPlane() is fixed when
+things actually do get snapped.
+
+The code to address these issues is currently being worked on.
diff --git a/regression_tests/q3map2/snap_plane/maps/snap_plane.map b/regression_tests/q3map2/snap_plane/maps/snap_plane.map
new file mode 100644 (file)
index 0000000..c2b490c
--- /dev/null
@@ -0,0 +1,78 @@
+{
+"classname" "worldspawn"
+{
+( -54784 5760 -64 ) ( -54976 5760 -64 ) ( -54976 5632 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -54976 5632 0 ) ( -54976 5760 0 ) ( -54784 5760 0 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -54976 5632 0 ) ( -54784 5632 0 ) ( -54784 5632 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -54784 5632 0 ) ( -54784 5760 0 ) ( -54784 5760 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -54784 5760 0 ) ( -54976 5760 0 ) ( -54976 5760 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -54976 5760 0 ) ( -54976 5632 0 ) ( -54976 5632 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( -53808 5616 -64 ) ( -55064 5616 -64 ) ( -55064 4944 -64 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( -55072 4944 0 ) ( -55072 5616 0 ) ( -53816 5616 0 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( -55040 4096 8 ) ( -53784 4096 8 ) ( -53784 4096 0 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( -54272 4936 8 ) ( -54272 5608 8 ) ( -54272 5608 0 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( -53816 5632 8 ) ( -55072 5632 8 ) ( -55072 5632 0 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( -54784 5592 8 ) ( -54784 4920 8 ) ( -54784 4920 0 ) radiant_regression_tests/green 0 0 0 0.500000 0.500000 0 0 0
+( -54528 5632 -64 ) ( -54272 5631 -64 ) ( -54528 5632 0 ) radiant_regression_tests/red 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( -54200 5904 -128 ) ( -55032 5904 -128 ) ( -55032 5824 -128 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -55024 5824 192 ) ( -55024 5904 192 ) ( -54192 5904 192 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -55040 5824 0 ) ( -54208 5824 0 ) ( -54208 5824 -64 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -54208 5824 0 ) ( -54208 5904 0 ) ( -54208 5904 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54200 5832 0 ) ( -55032 5832 0 ) ( -55032 5832 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -55040 5904 0 ) ( -55040 5824 0 ) ( -55040 5824 -64 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -54144 5824 -128 ) ( -54208 5824 -128 ) ( -54208 5424 -128 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54208 5424 192 ) ( -54208 5824 192 ) ( -54144 5824 192 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54160 4032 192 ) ( -54096 4032 192 ) ( -54096 4032 -128 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54200 5424 192 ) ( -54200 5824 192 ) ( -54200 5824 -128 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54144 5824 192 ) ( -54208 5824 192 ) ( -54208 5824 -128 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54208 5824 192 ) ( -54208 5424 192 ) ( -54208 5424 -128 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( -54208 4032 -128 ) ( -54760 4032 -128 ) ( -54760 3944 -128 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54760 3944 192 ) ( -54760 4032 192 ) ( -54208 4032 192 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54752 4024 192 ) ( -54200 4024 192 ) ( -54200 4024 -128 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54208 3944 192 ) ( -54208 4032 192 ) ( -54208 4032 -128 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54208 4032 192 ) ( -54760 4032 192 ) ( -54760 4032 -128 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -55040 4016 192 ) ( -55040 3928 192 ) ( -55040 3928 -128 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -55040 5824 -128 ) ( -55256 5824 -128 ) ( -55256 5256 -128 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -55256 5256 192 ) ( -55256 5824 192 ) ( -55040 5824 192 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -55256 4032 192 ) ( -55040 4032 192 ) ( -55040 4032 -128 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -55040 5256 192 ) ( -55040 5824 192 ) ( -55040 5824 -128 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -55040 5824 192 ) ( -55256 5824 192 ) ( -55256 5824 -128 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -55048 5808 192 ) ( -55048 5240 192 ) ( -55048 5240 -128 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -54208 4032 192 ) ( -55040 4032 192 ) ( -55040 4024 192 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -55016 4024 200 ) ( -55016 4032 200 ) ( -54184 4032 200 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -55040 4032 296 ) ( -54208 4032 296 ) ( -54208 4032 192 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54208 4024 296 ) ( -54208 4032 296 ) ( -54208 4032 192 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54200 5824 296 ) ( -55032 5824 296 ) ( -55032 5824 192 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -55040 4032 296 ) ( -55040 4024 296 ) ( -55040 4024 192 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( -54192 4560 -136 ) ( -55024 4560 -136 ) ( -55024 4552 -136 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -55040 4024 -128 ) ( -55040 4032 -128 ) ( -54208 4032 -128 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( -55040 4032 -128 ) ( -54208 4032 -128 ) ( -54208 4032 -256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54208 4024 -128 ) ( -54208 4032 -128 ) ( -54208 4032 -256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -54208 5824 -120 ) ( -55040 5824 -120 ) ( -55040 5824 -248 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( -55040 4032 -128 ) ( -55040 4024 -128 ) ( -55040 4024 -256 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+}
+{
+"light" "1000"
+"origin" "-54664 5696 40"
+"classname" "light"
+}
+{
+"angle" "360"
+"origin" "-54840 5696 88"
+"classname" "info_player_deathmatch"
+}
diff --git a/regression_tests/q3map2/sparkly_seam/README.txt b/regression_tests/q3map2/sparkly_seam/README.txt
new file mode 100644 (file)
index 0000000..3c54feb
--- /dev/null
@@ -0,0 +1,21 @@
+DESCRIPTION OF PROBLEM:
+=======================
+
+The example map, maps/sparkly_seam.map, contains two triangular brushes near
+the side of the room.  The seam between these two brushes "sparkles" even
+though the endpoints of the edges are exactly the same.
+
+To trigger the bug, compile the map; you don't need -vis or -light.  Only
+-bsp (the first q3map2 stage) is necessary to trigger the bug.  The only
+entities in the map are a light and a info_player_deathmatch, so the map will
+compile for any Q3 mod.
+
+
+SOLUTION TO PROBLEM:
+====================
+
+None yet.  The problem is likely caused by sloppy math operations (significant
+loss of precision).  This bug pops in and out of existence with every other
+commit at the moment.  The problem is likely caused by the operations in the
+brush winding computation (where the planes are intersected with each other).
+I have not gotten around to addressing that code yet.
diff --git a/regression_tests/q3map2/sparkly_seam/maps/sparkly_seam.map b/regression_tests/q3map2/sparkly_seam/maps/sparkly_seam.map
new file mode 100644 (file)
index 0000000..4b02137
--- /dev/null
@@ -0,0 +1,75 @@
+{
+"classname" "worldspawn"
+{
+( 6784 16015 -2048 ) ( 6144 15958 -2048 ) ( 6784 15936 -2048 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6784 16015 -1788 ) ( 6784 16015 -2048 ) ( 6784 15936 -1792 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6144 15958 -1471 ) ( 6144 15958 -2048 ) ( 6784 16015 -1788 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6784 15936 -1792 ) ( 6784 15936 -2048 ) ( 6144 15958 -1471 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6784 15936 -1792 ) ( 6144 15958 -1471 ) ( 6784 16015 -1788 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 6784 15936 -2048 ) ( 6144 15958 -2048 ) ( 6144 15936 -2048 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6784 15936 -1792 ) ( 6144 15936 -2048 ) ( 6144 15936 -1472 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6144 15936 -1472 ) ( 6144 15958 -2048 ) ( 6144 15958 -1471 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6144 15958 -1471 ) ( 6784 15936 -2048 ) ( 6784 15936 -1792 ) common/caulk 0 0 0 0.500000 0.500000 134217728 4 0
+( 6144 15936 -1472 ) ( 6144 15958 -1471 ) ( 6784 15936 -1792 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 134217728 0 0
+}
+{
+( 6160 16432 -2048 ) ( 6048 16432 -2048 ) ( 6048 15936 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6128 15936 -896 ) ( 6128 16432 -896 ) ( 6240 16432 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6032 15936 160 ) ( 6144 15936 160 ) ( 6144 15936 -3552 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15936 160 ) ( 6144 16432 160 ) ( 6144 16432 -3552 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6112 16896 160 ) ( 6000 16896 160 ) ( 6000 16896 -3552 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6136 16424 168 ) ( 6136 15928 168 ) ( 6136 15928 -3544 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6144 16672 -2048 ) ( 6136 16672 -2048 ) ( 6136 16176 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6136 16192 -896 ) ( 6136 16688 -896 ) ( 6144 16688 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6136 15936 -1280 ) ( 6144 15936 -1280 ) ( 6144 15936 -1760 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6792 16160 -1296 ) ( 6792 16656 -1296 ) ( 6792 16656 -1776 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16896 -1312 ) ( 6136 16896 -1312 ) ( 6136 16896 -1792 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16672 -1296 ) ( 6784 16176 -1296 ) ( 6784 16176 -1776 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+}
+{
+( 6784 15936 -2048 ) ( 6144 15936 -2048 ) ( 6144 15880 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15880 -896 ) ( 6144 15936 -896 ) ( 6784 15936 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15928 -896 ) ( 6784 15928 -896 ) ( 6784 15928 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 15880 -896 ) ( 6784 15936 -896 ) ( 6784 15936 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 15936 -896 ) ( 6144 15936 -896 ) ( 6144 15936 -2048 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6144 15936 -896 ) ( 6144 15880 -896 ) ( 6144 15880 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6784 16960 -2048 ) ( 6144 16960 -2048 ) ( 6144 16896 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16896 -896 ) ( 6144 16960 -896 ) ( 6784 16960 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16896 -896 ) ( 6784 16896 -896 ) ( 6784 16896 -2048 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6784 16896 -896 ) ( 6784 16960 -896 ) ( 6784 16960 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16904 -896 ) ( 6144 16904 -896 ) ( 6144 16904 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16960 -896 ) ( 6144 16896 -896 ) ( 6144 16896 -2048 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6784 16896 -896 ) ( 6144 16896 -896 ) ( 6144 16536 -896 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6144 16552 -888 ) ( 6144 16912 -888 ) ( 6784 16912 -888 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15936 -744 ) ( 6784 15936 -744 ) ( 6784 15936 -856 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16536 -784 ) ( 6784 16896 -784 ) ( 6784 16896 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16896 -784 ) ( 6144 16896 -784 ) ( 6144 16896 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16896 -784 ) ( 6144 16536 -784 ) ( 6144 16536 -896 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+{
+( 6784 16584 -2056 ) ( 6144 16584 -2056 ) ( 6144 15976 -2056 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 15936 -2048 ) ( 6144 16544 -2048 ) ( 6784 16544 -2048 ) radiant_regression_tests/tile 0 0 0 0.500000 0.500000 0 0 0
+( 6144 15936 -2048 ) ( 6784 15936 -2048 ) ( 6784 15936 -2376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 15936 -2048 ) ( 6784 16544 -2048 ) ( 6784 16544 -2376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6784 16896 -2048 ) ( 6144 16896 -2048 ) ( 6144 16896 -2376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+( 6144 16544 -2048 ) ( 6144 15936 -2048 ) ( 6144 15936 -2376 ) common/caulk 0 0 0 0.500000 0.500000 0 4 0
+}
+}
+{
+"angle" "180"
+"origin" "6608 15968 -1608"
+"classname" "info_player_deathmatch"
+}
+{
+"light" "1000"
+"origin" "6440 16160 -1192"
+"classname" "light"
+}
index fc8805e72da1ebf02b94ec0e02ce36702189890a..34dd173ecbd0473715dd3a688ce22ac785f6756d 100644 (file)
@@ -73,8 +73,43 @@ winding_t    *AllocWinding (int points)
        return w;
 }
 
+/*
+=============
+AllocWindingAccu
+=============
+*/
+winding_accu_t *AllocWindingAccu(int points)
+{
+       winding_accu_t  *w;
+       int             s;
+
+       if (points >= MAX_POINTS_ON_WINDING)
+               Error("AllocWindingAccu failed: MAX_POINTS_ON_WINDING exceeded");
+
+       if (numthreads == 1)
+       {
+               // At the time of this writing, these statistics were not used in any way.
+               c_winding_allocs++;
+               c_winding_points += points;
+               c_active_windings++;
+               if (c_active_windings > c_peak_windings)
+                       c_peak_windings = c_active_windings;
+       }
+       s = sizeof(vec_accu_t) * 3 * points + sizeof(int);
+       w = safe_malloc(s);
+       memset(w, 0, s); 
+       return w;
+}
+
+/*
+=============
+FreeWinding
+=============
+*/
 void FreeWinding (winding_t *w)
 {
+       if (!w) Error("FreeWinding: winding is NULL");
+
        if (*(unsigned *)w == 0xdeaddead)
                Error ("FreeWinding: freed a freed winding");
        *(unsigned *)w = 0xdeaddead;
@@ -84,6 +119,24 @@ void FreeWinding (winding_t *w)
        free (w);
 }
 
+/*
+=============
+FreeWindingAccu
+=============
+*/
+void FreeWindingAccu(winding_accu_t *w)
+{
+       if (!w) Error("FreeWindingAccu: winding is NULL");
+
+       if (*((unsigned *) w) == 0xdeaddead)
+               Error("FreeWindingAccu: freed a freed winding");
+       *((unsigned *) w) = 0xdeaddead;
+
+       if (numthreads == 1)
+               c_active_windings--;
+       free(w);
+}
+
 /*
 ============
 RemoveColinearPoints
@@ -201,9 +254,131 @@ void      WindingCenter (winding_t *w, vec3_t center)
        VectorScale (center, scale, center);
 }
 
+/*
+=================
+BaseWindingForPlaneAccu
+=================
+*/
+winding_accu_t *BaseWindingForPlaneAccu(vec3_t normal, vec_t dist)
+{
+       // The goal in this function is to replicate the behavior of the original BaseWindingForPlane()
+       // function (see below) but at the same time increasing accuracy substantially.
+
+       // The original code gave a preference for the vup vector to start out as (0, 0, 1), unless the
+       // normal had a dominant Z value, in which case vup started out as (1, 0, 0).  After that, vup
+       // was "bent" [along the plane defined by normal and vup] to become perpendicular to normal.
+       // After that the vright vector was computed as the cross product of vup and normal.
+
+       // I'm constructing the winding polygon points in a fashion similar to the method used in the
+       // original function.  Orientation is the same.  The size of the winding polygon, however, is
+       // variable in this function (depending on the angle of normal), and is larger (by about a factor
+       // of 2) than the winding polygon in the original function.
+
+       int             x, i;
+       vec_t           max, v;
+       vec3_accu_t     vright, vup, org, normalAccu;
+       winding_accu_t  *w;
+
+       // One of the components of normal must have a magnitiude greater than this value,
+       // otherwise normal is not a unit vector.  This is a little bit of inexpensive
+       // partial error checking we can do.
+       max = 0.56; // 1 / sqrt(1^2 + 1^2 + 1^2) = 0.577350269
+
+       x = -1;
+       for (i = 0; i < 3; i++) {
+               v = (vec_t) fabs(normal[i]);
+               if (v > max) {
+                       x = i;
+                       max = v;
+               }
+       }
+       if (x == -1) Error("BaseWindingForPlaneAccu: no dominant axis found because normal is too short");
+
+       switch (x) {
+               case 0: // Fall through to next case.
+               case 1:
+                       vright[0] = (vec_accu_t) -normal[1];
+                       vright[1] = (vec_accu_t) normal[0];
+                       vright[2] = 0;
+                       break;
+               case 2:
+                       vright[0] = 0;
+                       vright[1] = (vec_accu_t) -normal[2];
+                       vright[2] = (vec_accu_t) normal[1];
+                       break;
+       }
+
+       // vright and normal are now perpendicular; you can prove this by taking their
+       // dot product and seeing that it's always exactly 0 (with no error).
+
+       // NOTE: vright is NOT a unit vector at this point.  vright will have length
+       // not exceeding 1.0.  The minimum length that vright can achieve happens when,
+       // for example, the Z and X components of the normal input vector are equal,
+       // and when normal's Y component is zero.  In that case Z and X of the normal
+       // vector are both approximately 0.70711.  The resulting vright vector in this
+       // case will have a length of 0.70711.
+
+       // We're relying on the fact that MAX_WORLD_COORD is a power of 2 to keep
+       // our calculation precise and relatively free of floating point error.
+       // [However, the code will still work fine if that's not the case.]
+       VectorScaleAccu(vright, ((vec_accu_t) MAX_WORLD_COORD) * 4.0, vright);
+
+       // At time time of this writing, MAX_WORLD_COORD was 65536 (2^16).  Therefore
+       // the length of vright at this point is at least 185364.  In comparison, a
+       // corner of the world at location (65536, 65536, 65536) is distance 113512
+       // away from the origin.
+
+       VectorCopyRegularToAccu(normal, normalAccu);
+       CrossProductAccu(normalAccu, vright, vup);
+
+       // vup now has length equal to that of vright.
+
+       VectorScaleAccu(normalAccu, (vec_accu_t) dist, org);
+
+       // org is now a point on the plane defined by normal and dist.  Furthermore,
+       // org, vright, and vup are pairwise perpendicular.  Now, the 4 vectors
+       // { (+-)vright + (+-)vup } have length that is at least sqrt(185364^2 + 185364^2),
+       // which is about 262144.  That length lies outside the world, since the furthest
+       // point in the world has distance 113512 from the origin as mentioned above.
+       // Also, these 4 vectors are perpendicular to the org vector.  So adding them
+       // to org will only increase their length.  Therefore the 4 points defined below
+       // all lie outside of the world.  Furthermore, it can be easily seen that the
+       // edges connecting these 4 points (in the winding_accu_t below) lie completely
+       // outside the world.  sqrt(262144^2 + 262144^2)/2 = 185363, which is greater than
+       // 113512.
+
+       w = AllocWindingAccu(4);
+
+       VectorSubtractAccu(org, vright, w->p[0]);
+       VectorAddAccu(w->p[0], vup, w->p[0]);
+
+       VectorAddAccu(org, vright, w->p[1]);
+       VectorAddAccu(w->p[1], vup, w->p[1]);
+
+       VectorAddAccu(org, vright, w->p[2]);
+       VectorSubtractAccu(w->p[2], vup, w->p[2]);
+
+       VectorSubtractAccu(org, vright, w->p[3]);
+       VectorSubtractAccu(w->p[3], vup, w->p[3]);
+
+       w->numpoints = 4;
+
+       return w;
+}
+
 /*
 =================
 BaseWindingForPlane
+
+Original BaseWindingForPlane() function that has serious accuracy problems.  Here is why.
+The base winding is computed as a rectangle with very large coordinates.  These coordinates
+are in the range 2^17 or 2^18.  "Epsilon" (meaning the distance between two adjacent numbers)
+at these magnitudes in 32 bit floating point world is about 0.02.  So for example, if things
+go badly (by bad luck), then the whole plane could be shifted by 0.02 units (its distance could
+be off by that much).  Then if we were to compute the winding of this plane and another of
+the brush's planes met this winding at a very acute angle, that error could multiply to around
+0.1 or more when computing the final vertex coordinates of the winding.  0.1 is a very large
+error, and can lead to all sorts of disappearing triangle problems.
 =================
 */
 winding_t *BaseWindingForPlane (vec3_t normal, vec_t dist)
@@ -285,12 +460,57 @@ winding_t *CopyWinding (winding_t *w)
        size_t                  size;
        winding_t       *c;
 
+       if (!w) Error("CopyWinding: winding is NULL");
+
        c = AllocWinding (w->numpoints);
        size = (size_t)((winding_t *)NULL)->p[w->numpoints];
        memcpy (c, w, size);
        return c;
 }
 
+/*
+==================
+CopyWindingAccuIncreaseSizeAndFreeOld
+==================
+*/
+winding_accu_t *CopyWindingAccuIncreaseSizeAndFreeOld(winding_accu_t *w)
+{
+       int             i;
+       winding_accu_t  *c;
+
+       if (!w) Error("CopyWindingAccuIncreaseSizeAndFreeOld: winding is NULL");
+
+       c = AllocWindingAccu(w->numpoints + 1);
+       c->numpoints = w->numpoints;
+       for (i = 0; i < c->numpoints; i++)
+       {
+               VectorCopyAccu(w->p[i], c->p[i]);
+       }
+       FreeWindingAccu(w);
+       return c;
+}
+
+/*
+==================
+CopyWindingAccuToRegular
+==================
+*/
+winding_t      *CopyWindingAccuToRegular(winding_accu_t *w)
+{
+       int             i;
+       winding_t       *c;
+
+       if (!w) Error("CopyWindingAccuToRegular: winding is NULL");
+
+       c = AllocWinding(w->numpoints);
+       c->numpoints = w->numpoints;
+       for (i = 0; i < c->numpoints; i++)
+       {
+               VectorCopyAccuToRegular(w->p[i], c->p[i]);
+       }
+       return c;
+}
+
 /*
 ==================
 ReverseWinding
@@ -424,6 +644,147 @@ void      ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist,
 }
 
 
+/*
+=============
+ChopWindingInPlaceAccu
+=============
+*/
+void ChopWindingInPlaceAccu(winding_accu_t **inout, vec3_t normal, vec_t dist, vec_t crudeEpsilon)
+{
+       vec_accu_t      fineEpsilon;
+       winding_accu_t  *in;
+       int             counts[3];
+       int             i, j;
+       vec_accu_t      dists[MAX_POINTS_ON_WINDING + 1];
+       int             sides[MAX_POINTS_ON_WINDING + 1];
+       int             maxpts;
+       winding_accu_t  *f;
+       vec_accu_t      *p1, *p2;
+       vec_accu_t      w;
+       vec3_accu_t     mid, normalAccu;
+
+       // We require at least a very small epsilon.  It's a good idea for several reasons.
+       // First, we will be dividing by a potentially very small distance below.  We don't
+       // want that distance to be too small; otherwise, things "blow up" with little accuracy
+       // due to the division.  (After a second look, the value w below is in range (0,1), but
+       // graininess problem remains.)  Second, Having minimum epsilon also prevents the following
+       // situation.  Say for example we have a perfect octagon defined by the input winding.
+       // Say our chopping plane (defined by normal and dist) is essentially the same plane
+       // that the octagon is sitting on.  Well, due to rounding errors, it may be that point
+       // 1 of the octagon might be in front, point 2 might be in back, point 3 might be in
+       // front, point 4 might be in back, and so on.  So we could end up with a very ugly-
+       // looking chopped winding, and this might be undesirable, and would at least lead to
+       // a possible exhaustion of MAX_POINTS_ON_WINDING.  It's better to assume that points
+       // very very close to the plane are on the plane, using an infinitesimal epsilon amount.
+
+       // Now, the original ChopWindingInPlace() function used a vec_t-based winding_t.
+       // So this minimum epsilon is quite similar to casting the higher resolution numbers to
+       // the lower resolution and comparing them in the lower resolution mode.  We explicitly
+       // choose the minimum epsilon as something around the vec_t epsilon of one because we
+       // want the resolution of vec_accu_t to have a large resolution around the epsilon.
+       // Some of that leftover resolution even goes away after we scale to points far away.
+
+       // Here is a further discussion regarding the choice of smallestEpsilonAllowed.
+       // In the 32 float world (we can assume vec_t is that), the "epsilon around 1.0" is
+       // 0.00000011921.  In the 64 bit float world (we can assume vec_accu_t is that), the
+       // "epsilon around 1.0" is 0.00000000000000022204.  (By the way these two epsilons
+       // are defined as VEC_SMALLEST_EPSILON_AROUND_ONE VEC_ACCU_SMALLEST_EPSILON_AROUND_ONE
+       // respectively.)  If you divide the first by the second, you get approximately
+       // 536,885,246.  Dividing that number by 200,000 (a typical base winding coordinate)
+       // gives 2684.  So in other words, if our smallestEpsilonAllowed was chosen as exactly
+       // VEC_SMALLEST_EPSILON_AROUND_ONE, you would be guaranteed at least 2000 "ticks" in
+       // 64-bit land inside of the epsilon for all numbers we're dealing with.
+
+       static const vec_accu_t smallestEpsilonAllowed = ((vec_accu_t) VEC_SMALLEST_EPSILON_AROUND_ONE) * 0.5;
+       if (crudeEpsilon < smallestEpsilonAllowed)      fineEpsilon = smallestEpsilonAllowed;
+       else                                            fineEpsilon = (vec_accu_t) crudeEpsilon;
+
+       in = *inout;
+       counts[0] = counts[1] = counts[2] = 0;
+       VectorCopyRegularToAccu(normal, normalAccu);
+
+       for (i = 0; i < in->numpoints; i++)
+       {
+               dists[i] = DotProductAccu(in->p[i], normalAccu) - dist;
+               if (dists[i] > fineEpsilon)             sides[i] = SIDE_FRONT;
+               else if (dists[i] < -fineEpsilon)       sides[i] = SIDE_BACK;
+               else                                    sides[i] = SIDE_ON;
+               counts[sides[i]]++;
+       }
+       sides[i] = sides[0];
+       dists[i] = dists[0];
+       
+       // I'm wondering if whatever code that handles duplicate planes is robust enough
+       // that we never get a case where two nearly equal planes result in 2 NULL windings
+       // due to the 'if' statement below.  TODO: Investigate this.
+       if (!counts[SIDE_FRONT]) {
+               FreeWindingAccu(in);
+               *inout = NULL;
+               return;
+       }
+       if (!counts[SIDE_BACK]) {
+               return; // Winding is unmodified.
+       }
+
+       // NOTE: The least number of points that a winding can have at this point is 2.
+       // In that case, one point is SIDE_FRONT and the other is SIDE_BACK.
+
+       maxpts = counts[SIDE_FRONT] + 2; // We dynamically expand if this is too small.
+       f = AllocWindingAccu(maxpts);
+
+       for (i = 0; i < in->numpoints; i++)
+       {
+               p1 = in->p[i];
+
+               if (sides[i] == SIDE_ON || sides[i] == SIDE_FRONT)
+               {
+                       if (f->numpoints >= MAX_POINTS_ON_WINDING)
+                               Error("ChopWindingInPlaceAccu: MAX_POINTS_ON_WINDING");
+                       if (f->numpoints >= maxpts) // This will probably never happen.
+                       {
+                               Sys_FPrintf(SYS_VRB, "WARNING: estimate on chopped winding size incorrect (no problem)\n");
+                               f = CopyWindingAccuIncreaseSizeAndFreeOld(f);
+                               maxpts++;
+                       }
+                       VectorCopyAccu(p1, f->p[f->numpoints]);
+                       f->numpoints++;
+                       if (sides[i] == SIDE_ON) continue;
+               }
+               if (sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i])
+               {
+                       continue;
+               }
+                       
+               // Generate a split point.
+               p2 = in->p[((i + 1) == in->numpoints) ? 0 : (i + 1)];
+
+               // The divisor's absolute value is greater than the dividend's absolute value.
+               // w is in the range (0,1).
+               w = dists[i] / (dists[i] - dists[i + 1]);
+
+               for (j = 0; j < 3; j++)
+               {
+                       // Avoid round-off error when possible.  Check axis-aligned normal.
+                       if (normal[j] == 1)             mid[j] = dist;
+                       else if (normal[j] == -1)       mid[j] = -dist;
+                       else                            mid[j] = p1[j] + (w * (p2[j] - p1[j]));
+               }
+               if (f->numpoints >= MAX_POINTS_ON_WINDING)
+                       Error("ChopWindingInPlaceAccu: MAX_POINTS_ON_WINDING");
+               if (f->numpoints >= maxpts) // This will probably never happen.
+               {
+                       Sys_FPrintf(SYS_VRB, "WARNING: estimate on chopped winding size incorrect (no problem)\n");
+                       f = CopyWindingAccuIncreaseSizeAndFreeOld(f);
+                       maxpts++;
+               }
+               VectorCopyAccu(mid, f->p[f->numpoints]);
+               f->numpoints++;
+       }
+
+       FreeWindingAccu(in);
+       *inout = f;
+}
+
 /*
 =============
 ChopWindingInPlace
index d78c780d68781d2848111be2a02d58627cea98b4..1f4495d9b571fbef9a38753524f3aad20b18b707 100644 (file)
@@ -55,3 +55,20 @@ void ChopWindingInPlace (winding_t **w, vec3_t normal, vec_t dist, vec_t epsilon
 // frees the original if clipped
 
 void pw(winding_t *w);
+
+
+///////////////////////////////////////////////////////////////////////////////////////
+// Below is double-precision stuff.  This was initially needed by the base winding code
+// in q3map2 brush processing.
+///////////////////////////////////////////////////////////////////////////////////////
+
+typedef struct
+{
+       int             numpoints;
+       vec3_accu_t     p[4]; // variable sized
+} winding_accu_t;
+
+winding_accu_t *BaseWindingForPlaneAccu(vec3_t normal, vec_t dist);
+void   ChopWindingInPlaceAccu(winding_accu_t **w, vec3_t normal, vec_t dist, vec_t epsilon);
+winding_t      *CopyWindingAccuToRegular(winding_accu_t *w);
+void   FreeWindingAccu(winding_accu_t *w);
index 2517ca63d210e28ed1778863fedf2b102800e8f7..b7c50f4c3348a998a674aca65af4b14dfadc5f76 100644 (file)
@@ -277,7 +277,49 @@ void SnapWeldVector( vec3_t a, vec3_t b, vec3_t out )
        }
 }
 
+/*
+==================
+SnapWeldVectorAccu
+
+Welds two vectors into a third, taking into account nearest-to-integer
+instead of averaging.
+==================
+*/
+void SnapWeldVectorAccu(vec3_accu_t a, vec3_accu_t b, vec3_accu_t out)
+{
+       // I'm just preserving what I think was the intended logic of the original
+       // SnapWeldVector().  I'm not actually sure where this function should even
+       // be used.  I'd like to know which kinds of problems this function addresses.
+
+       // TODO: I thought we're snapping all coordinates to nearest 1/8 unit?
+       // So what is natural about snapping to the nearest integer?  Maybe we should
+       // be snapping to the nearest 1/8 unit instead?
 
+       int             i;
+       vec_accu_t      ai, bi, ad, bd;
+       
+       if (a == NULL || b == NULL || out == NULL)
+               Error("SnapWeldVectorAccu: NULL argument");
+       
+       for (i = 0; i < 3; i++)
+       {
+               ai = Q_rintAccu(a[i]);
+               bi = Q_rintAccu(b[i]);
+               ad = fabs(ai - a[i]);
+               bd = fabs(bi - b[i]);
+       
+               if (ad < bd)
+               {
+                       if (ad < SNAP_EPSILON)  out[i] = ai;
+                       else                    out[i] = a[i];
+               }
+               else
+               {
+                       if (bd < SNAP_EPSILON)  out[i] = bi;
+                       else                    out[i] = b[i];
+               }
+       }
+}
 
 /*
 FixWinding() - ydnar
@@ -338,10 +380,71 @@ qboolean FixWinding( winding_t *w )
        return valid;
 }
 
+/*
+==================
+FixWindingAccu
 
+Removes degenerate edges (edges that are too short) from a winding.
+Returns qtrue if the winding has been altered by this function.
+Returns qfalse if the winding is untouched by this function.
 
+It's advised that you check the winding after this function exits to make
+sure it still has at least 3 points.  If that is not the case, the winding
+cannot be considered valid.  The winding may degenerate to one or two points
+if the some of the winding's points are close together.
+==================
+*/
+qboolean FixWindingAccu(winding_accu_t *w)
+{
+       int             i, j, k;
+       vec3_accu_t     vec;
+       vec_accu_t      dist;
+       qboolean        done, altered;
 
+       if (w == NULL) Error("FixWindingAccu: NULL argument");
 
+       altered = qfalse;
+
+       while (qtrue)
+       {
+               if (w->numpoints < 2) break; // Don't remove the only remaining point.
+               done = qtrue;
+               for (i = 0; i < w->numpoints; i++)
+               {
+                       j = (((i + 1) == w->numpoints) ? 0 : (i + 1));
+
+                       VectorSubtractAccu(w->p[i], w->p[j], vec);
+                       dist = VectorLengthAccu(vec);
+                       if (dist < DEGENERATE_EPSILON)
+                       {
+                               // TODO: I think the "snap weld vector" was written before
+                               // some of the math precision fixes, and its purpose was
+                               // probably to address math accuracy issues.  We can think
+                               // about changing the logic here.  Maybe once plane distance
+                               // gets 64 bits, we can look at it then.
+                               SnapWeldVectorAccu(w->p[i], w->p[j], vec);
+                               VectorCopyAccu(vec, w->p[i]);
+                               for (k = j + 1; k < w->numpoints; k++)
+                               {
+                                       VectorCopyAccu(w->p[k], w->p[k - 1]);
+                               }
+                               w->numpoints--;
+                               altered = qtrue;
+                               // The only way to finish off fixing the winding consistently and
+                               // accurately is by fixing the winding all over again.  For example,
+                               // the point at index i and the point at index i-1 could now be
+                               // less than the epsilon distance apart.  There are too many special
+                               // case problems we'd need to handle if we didn't start from the
+                               // beginning.
+                               done = qfalse;
+                               break; // This will cause us to return to the "while" loop.
+                       }
+               }
+               if (done) break;
+       }
+
+       return altered;
+}
 
 
 /*
@@ -353,7 +456,11 @@ returns false if the brush doesn't enclose a valid volume
 qboolean CreateBrushWindings( brush_t *brush )
 {
        int                     i, j;
+#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES
+       winding_accu_t  *w;
+#else
        winding_t       *w;
+#endif
        side_t          *side;
        plane_t         *plane;
        
@@ -366,7 +473,11 @@ qboolean CreateBrushWindings( brush_t *brush )
                plane = &mapplanes[ side->planenum ];
                
                /* make huge winding */
+#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES
+               w = BaseWindingForPlaneAccu(plane->normal, plane->dist);
+#else
                w = BaseWindingForPlane( plane->normal, plane->dist );
+#endif
                
                /* walk the list of brush sides */
                for( j = 0; j < brush->numsides && w != NULL; j++ )
@@ -378,14 +489,39 @@ qboolean CreateBrushWindings( brush_t *brush )
                        if( brush->sides[ j ].bevel )
                                continue;
                        plane = &mapplanes[ brush->sides[ j ].planenum ^ 1 ];
+#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES
+                       ChopWindingInPlaceAccu(&w, plane->normal, plane->dist, 0);
+#else
                        ChopWindingInPlace( &w, plane->normal, plane->dist, 0 ); // CLIP_EPSILON );
+#endif
                        
                        /* ydnar: fix broken windings that would generate trifans */
+#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES
+                       // I think it's better to FixWindingAccu() once after we chop with all planes
+                       // so that error isn't multiplied.  There is nothing natural about welding
+                       // the points unless they are the final endpoints.  ChopWindingInPlaceAccu()
+                       // is able to handle all kinds of degenerate windings.
+#else
                        FixWinding( w );
+#endif
                }
                
                /* set side winding */
+#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES
+               if (w != NULL)
+               {
+                       FixWindingAccu(w);
+                       if (w->numpoints < 3)
+                       {
+                               FreeWindingAccu(w);
+                               w = NULL;
+                       }
+               }
+               side->winding = (w ? CopyWindingAccuToRegular(w) : NULL);
+               if (w) FreeWindingAccu(w);
+#else
                side->winding = w;
+#endif
        }
        
        /* find brush bounds */
@@ -506,6 +642,8 @@ void WriteBSPBrushMap( char *name, brush_t *list )
                fprintf (f, "{\n");
                for (i=0,s=list->sides ; i<list->numsides ; i++,s++)
                {
+                       // TODO: See if we can use a smaller winding to prevent resolution loss.
+                       // Is WriteBSPBrushMap() used only to decompile maps?
                        w = BaseWindingForPlane (mapplanes[s->planenum].normal, mapplanes[s->planenum].dist);
 
                        fprintf (f,"( %i %i %i ) ", (int)w->p[0][0], (int)w->p[0][1], (int)w->p[0][2]);
index 59cc3d9cc41aa7291ab07a6e814160d9bd0b938f..56262311b77bcd124ffeea19d836ce742a38b77d 100644 (file)
@@ -43,6 +43,7 @@ ConvertSurface()
 converts a bsp drawsurface to an ase chunk
 */
 
+int numLightmapsASE = 0;
 static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, vec3_t origin )
 {
        int                             i, v, face, a, b, c;
@@ -162,7 +163,15 @@ static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSur
        fprintf( f, "\t*PROP_MOTIONBLUR\t0\r\n" );
        fprintf( f, "\t*PROP_CASTSHADOW\t1\r\n" );
        fprintf( f, "\t*PROP_RECVSHADOW\t1\r\n" );
-       fprintf( f, "\t*MATERIAL_REF\t%d\r\n", ds->shaderNum );
+       if(lightmapsAsTexcoord)
+       {
+               if(ds->lightmapNum[0] >= 0 && ds->lightmapNum[0] + deluxemap < numLightmapsASE)
+                       fprintf( f, "\t*MATERIAL_REF\t%d\r\n", ds->lightmapNum[0] + deluxemap );
+               else
+                       Sys_Printf( "WARNING: lightmap %d out of range, not exporting\n", ds->lightmapNum[0] + deluxemap );
+       }
+       else
+               fprintf( f, "\t*MATERIAL_REF\t%d\r\n", ds->shaderNum );
        fprintf( f, "}\r\n" );
 }
 
@@ -280,6 +289,31 @@ static void ConvertShader( FILE *f, bspShader_t *shader, int shaderNum )
        
        fprintf( f, "\t}\r\n" );
 }
+static void ConvertLightmap( FILE *f, const char *base, int lightmapNum )
+{
+       /* print shader info */
+       fprintf( f, "\t*MATERIAL\t%d\t{\r\n", lightmapNum );
+       fprintf( f, "\t\t*MATERIAL_NAME\t\"lm_%04d\"\r\n", lightmapNum );
+       fprintf( f, "\t\t*MATERIAL_CLASS\t\"Standard\"\r\n" );
+       fprintf( f, "\t\t*MATERIAL_DIFFUSE\t1\t1\t1\r\n");
+       fprintf( f, "\t\t*MATERIAL_SHADING Phong\r\n" );
+       
+       /* print map info */
+       if(lightmapNum >= 0)
+       {
+               fprintf( f, "\t\t*MAP_DIFFUSE\t{\r\n" );
+               fprintf( f, "\t\t\t*MAP_NAME\t\"lm_%04d\"\r\n", lightmapNum );
+               fprintf( f, "\t\t\t*MAP_CLASS\t\"Bitmap\"\r\n");
+               fprintf( f, "\t\t\t*MAP_SUBNO\t1\r\n" );
+               fprintf( f, "\t\t\t*MAP_AMOUNT\t1.0\r\n" );
+               fprintf( f, "\t\t\t*MAP_TYPE\tScreen\r\n" );
+               fprintf( f, "\t\t\t*BITMAP\t\"%s\\lm_%04d.tga\"\r\n", base, lightmapNum );
+               fprintf( f, "\t\t\t*BITMAP_FILTER\tPyramidal\r\n" );
+               fprintf( f, "\t\t}\r\n" );
+       }
+       
+       fprintf( f, "\t}\r\n" );
+}
 
 
 
@@ -297,20 +331,21 @@ int ConvertBSPToASE( char *bspName )
        entity_t                *e;
        vec3_t                  origin;
        const char              *key;
-       char                    name[ 1024 ], base[ 1024 ];
+       char                    name[ 1024 ], base[ 1024 ], dirname[ 1024 ];
        
        
        /* note it */
        Sys_Printf( "--- Convert BSP to ASE ---\n" );
 
        /* create the ase filename from the bsp name */
+       strcpy( dirname, bspName );
+       StripExtension( dirname );
        strcpy( name, bspName );
        StripExtension( name );
        strcat( name, ".ase" );
        Sys_Printf( "writing %s\n", name );
        
        ExtractFileBase( bspName, base );
-       strcat( base, ".bsp" );
        
        /* open it */
        f = fopen( name, "wb" );
@@ -321,7 +356,7 @@ int ConvertBSPToASE( char *bspName )
        fprintf( f, "*3DSMAX_ASCIIEXPORT\t200\r\n" );
        fprintf( f, "*COMMENT\t\"Generated by Q3Map2 (ydnar) -convert -format ase\"\r\n" );
        fprintf( f, "*SCENE\t{\r\n" );
-       fprintf( f, "\t*SCENE_FILENAME\t\"%s\"\r\n", base );
+       fprintf( f, "\t*SCENE_FILENAME\t\"%s.bsp\"\r\n", base );
        fprintf( f, "\t*SCENE_FIRSTFRAME\t0\r\n" );
        fprintf( f, "\t*SCENE_LASTFRAME\t100\r\n" );
        fprintf( f, "\t*SCENE_FRAMESPEED\t30\r\n" );
@@ -332,11 +367,35 @@ int ConvertBSPToASE( char *bspName )
        
        /* print materials */
        fprintf( f, "*MATERIAL_LIST\t{\r\n" );
-       fprintf( f, "\t*MATERIAL_COUNT\t%d\r\n", numBSPShaders );
-       for( i = 0; i < numBSPShaders; i++ )
+       if(lightmapsAsTexcoord)
        {
-               shader = &bspShaders[ i ];
-               ConvertShader( f, shader, i );
+               int lightmapCount;
+               for( lightmapCount = 0; lightmapCount < numBSPLightmaps; lightmapCount++ )
+                       ;
+               for( ; ; lightmapCount++ )
+               {
+                       char buf[1024];
+                       FILE *tmp;
+                       snprintf(buf, sizeof(buf), "%s/lm_%04d.tga", dirname, lightmapCount);
+                       buf[sizeof(buf) - 1] = 0;
+                       tmp = fopen(buf, "rb");
+                       if(!tmp)
+                               break;
+                       fclose(tmp);
+               }
+               fprintf( f, "\t*MATERIAL_COUNT\t%d\r\n", lightmapCount );
+               for( i = 0; i < lightmapCount; i++ )
+                       ConvertLightmap( f, base, i );
+               numLightmapsASE = lightmapCount;
+       }
+       else
+       {
+               fprintf( f, "\t*MATERIAL_COUNT\t%d\r\n", numBSPShaders );
+               for( i = 0; i < numBSPShaders; i++ )
+               {
+                       shader = &bspShaders[ i ];
+                       ConvertShader( f, shader, i );
+               }
        }
        fprintf( f, "}\r\n" );
        
diff --git a/tools/quake3/q3map2/convert_obj.c b/tools/quake3/q3map2/convert_obj.c
new file mode 100644 (file)
index 0000000..08e75e1
--- /dev/null
@@ -0,0 +1,328 @@
+/* -------------------------------------------------------------------------------
+
+Copyright (C) 1999-2007 id Software, Inc. and contributors.
+For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+This file is part of GtkRadiant.
+
+GtkRadiant is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GtkRadiant is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GtkRadiant; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+----------------------------------------------------------------------------------
+
+This code has been altered significantly from its original form, to support
+several games based on the Quake III Arena engine, in the form of "Q3Map2."
+
+------------------------------------------------------------------------------- */
+
+
+
+/* marker */
+#define CONVERT_ASE_C
+
+
+
+/* dependencies */
+#include "q3map2.h"
+
+
+
+/*
+ConvertSurface()
+converts a bsp drawsurface to an obj chunk
+*/
+
+int firstLightmap = 0;
+int lastLightmap = -1;
+static void ConvertLightmapToMTL( FILE *f, const char *base, int lightmapNum );
+
+int objVertexCount = 0;
+int objLastShaderNum = -1;
+static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, vec3_t origin )
+{
+       int                             i, v, face, a, b, c;
+       bspDrawVert_t   *dv;
+       
+       /* ignore patches for now */
+       if( ds->surfaceType != MST_PLANAR && ds->surfaceType != MST_TRIANGLE_SOUP )
+               return;
+
+       fprintf(f, "g mat%dmodel%dsurf%d\r\n", ds->shaderNum, modelNum, surfaceNum);
+       switch( ds->surfaceType )
+       {
+               case MST_PLANAR:
+                       fprintf( f, "# SURFACETYPE MST_PLANAR\r\n" );
+                       break;
+               case MST_TRIANGLE_SOUP:
+                       fprintf( f, "# SURFACETYPE MST_TRIANGLE_SOUP\r\n" );
+                       break;
+       }
+
+       /* export shader */
+       if(lightmapsAsTexcoord)
+       {
+               if(objLastShaderNum != ds->lightmapNum[0])
+               {
+                       fprintf(f, "usemtl lm_%04d\r\n", ds->lightmapNum[0] + deluxemap);
+                       objLastShaderNum = ds->lightmapNum[0] + deluxemap;
+               }
+               if(ds->lightmapNum[0] + deluxemap < firstLightmap)
+               {
+                       Sys_Printf( "WARNING: lightmap %d out of range (exporting anyway)\n", ds->lightmapNum[0] + deluxemap );
+                       firstLightmap = ds->lightmapNum[0] + deluxemap;
+               }
+               if(ds->lightmapNum[0] > lastLightmap)
+               {
+                       Sys_Printf( "WARNING: lightmap %d out of range (exporting anyway)\n", ds->lightmapNum[0] + deluxemap );
+                       lastLightmap = ds->lightmapNum[0] + deluxemap;
+               }
+       }
+       else
+       {
+               if(objLastShaderNum != ds->shaderNum)
+               {
+                       fprintf(f, "usemtl %s\r\n", bspShaders[ds->shaderNum].shader);
+                       objLastShaderNum = ds->shaderNum;
+               }
+       }
+       
+       /* export vertex */
+       for( i = 0; i < ds->numVerts; i++ )
+       {
+               v = i + ds->firstVert;
+               dv = &bspDrawVerts[ v ];
+               fprintf(f, "# vertex %d\r\n", i + objVertexCount + 1);
+               fprintf(f, "v %f %f %f\r\n", dv->xyz[ 0 ], dv->xyz[ 1 ], dv->xyz[ 2 ]);
+               fprintf(f, "vn %f %f %f\r\n", dv->normal[ 0 ], dv->normal[ 1 ], dv->normal[ 2 ]);
+               if(lightmapsAsTexcoord)
+                       fprintf(f, "vt %f %f\r\n", dv->lightmap[0][0], 1.0 - dv->lightmap[0][1]);
+               else
+                       fprintf(f, "vt %f %f\r\n", dv->st[ 0 ], 1.0 - dv->st[ 1 ]);
+       }
+
+       /* export faces */
+       for( i = 0; i < ds->numIndexes; i += 3 )
+       {
+               face = (i / 3);
+               a = bspDrawIndexes[ i + ds->firstIndex ];
+               c = bspDrawIndexes[ i + ds->firstIndex + 1 ];
+               b = bspDrawIndexes[ i + ds->firstIndex + 2 ];
+               fprintf(f, "f %d/%d/%d %d/%d/%d %d/%d/%d\r\n",
+                       a + objVertexCount + 1, a + objVertexCount + 1, a + objVertexCount + 1, 
+                       b + objVertexCount + 1, b + objVertexCount + 1, b + objVertexCount + 1, 
+                       c + objVertexCount + 1, c + objVertexCount + 1, c + objVertexCount + 1
+               );
+       }
+
+       objVertexCount += ds->numVerts;
+}
+
+
+
+/*
+ConvertModel()
+exports a bsp model to an ase chunk
+*/
+
+static void ConvertModelToOBJ( FILE *f, bspModel_t *model, int modelNum, vec3_t origin )
+{
+       int                                     i, s;
+       bspDrawSurface_t        *ds;
+       
+       
+       /* go through each drawsurf in the model */
+       for( i = 0; i < model->numBSPSurfaces; i++ )
+       {
+               s = i + model->firstBSPSurface;
+               ds = &bspDrawSurfaces[ s ];
+               ConvertSurfaceToOBJ( f, model, modelNum, ds, s, origin );
+       }
+}
+
+
+
+/*
+ConvertShader()
+exports a bsp shader to an ase chunk
+*/
+
+static void ConvertShaderToMTL( FILE *f, bspShader_t *shader, int shaderNum )
+{
+       shaderInfo_t    *si;
+       char                    *c, filename[ 1024 ];
+       
+       
+       /* get shader */
+       si = ShaderInfoForShader( shader->shader );
+       if( si == NULL )
+       {
+               Sys_Printf( "WARNING: NULL shader in BSP\n" );
+               return;
+       }
+       
+       /* set bitmap filename */
+       if( si->shaderImage->filename[ 0 ] != '*' )
+               strcpy( filename, si->shaderImage->filename );
+       else
+               sprintf( filename, "%s.tga", si->shader );
+
+       /* blender hates this, so let's not do it
+       for( c = filename; *c != '\0'; c++ )
+               if( *c == '/' )
+                       *c = '\\';
+       */
+       
+       /* print shader info */
+       fprintf( f, "newmtl %s\r\n", shader->shader );
+       fprintf( f, "Kd %f %f %f\r\n", si->color[ 0 ], si->color[ 1 ], si->color[ 2 ] );
+       if(shadersAsBitmap)
+               fprintf( f, "map_Kd %s\r\n", shader->shader );
+       else
+       /* blender hates this, so let's not do it
+               fprintf( f, "map_Kd ..\\%s\r\n", filename );
+       */
+               fprintf( f, "map_Kd ../%s\r\n", filename );
+}
+
+static void ConvertLightmapToMTL( FILE *f, const char *base, int lightmapNum )
+{
+       /* print shader info */
+       fprintf( f, "newmtl lm_%04d\r\n", lightmapNum );
+       if(lightmapNum >= 0)
+       /* blender hates this, so let's not do it
+               fprintf( f, "map_Kd %s\\lm_%04d.tga\r\n", base, lightmapNum );
+       */
+               fprintf( f, "map_Kd %s/lm_%04d.tga\r\n", base, lightmapNum );
+}
+
+
+
+/*
+ConvertBSPToASE()
+exports an 3d studio ase file from the bsp
+*/
+
+int ConvertBSPToOBJ( char *bspName )
+{
+       int                             i, modelNum;
+       FILE                    *f, *fmtl;
+       bspShader_t             *shader;
+       bspModel_t              *model;
+       entity_t                *e;
+       vec3_t                  origin;
+       const char              *key;
+       char                    name[ 1024 ], base[ 1024 ], mtlname[ 1024 ], dirname[ 1024 ];
+       
+       
+       /* note it */
+       Sys_Printf( "--- Convert BSP to OBJ ---\n" );
+
+       /* create the ase filename from the bsp name */
+       strcpy( dirname, bspName );
+       StripExtension( dirname );
+       strcpy( name, bspName );
+       StripExtension( name );
+       strcat( name, ".obj" );
+       Sys_Printf( "writing %s\n", name );
+       strcpy( mtlname, bspName );
+       StripExtension( mtlname );
+       strcat( mtlname, ".mtl" );
+       Sys_Printf( "writing %s\n", mtlname );
+       
+       ExtractFileBase( bspName, base );
+       
+       /* open it */
+       f = fopen( name, "wb" );
+       if( f == NULL )
+               Error( "Open failed on %s\n", name );
+       fmtl = fopen( mtlname, "wb" );
+       if( fmtl == NULL )
+               Error( "Open failed on %s\n", mtlname );
+       
+       /* print header */
+       fprintf( f, "o %s\r\n", base );
+       fprintf( f, "# Generated by Q3Map2 (ydnar) -convert -format obj\r\n" );
+       fprintf( f, "mtllib %s.mtl\r\n", base );
+
+       fprintf( fmtl, "# Generated by Q3Map2 (ydnar) -convert -format obj\r\n" );
+       if(lightmapsAsTexcoord)
+       {
+               int lightmapCount;
+               for( lightmapCount = 0; lightmapCount < numBSPLightmaps; lightmapCount++ )
+                       ;
+               for( ; ; lightmapCount++ )
+               {
+                       char buf[1024];
+                       FILE *tmp;
+                       snprintf(buf, sizeof(buf), "%s/lm_%04d.tga", dirname, lightmapCount);
+                       buf[sizeof(buf) - 1] = 0;
+                       tmp = fopen(buf, "rb");
+                       if(!tmp)
+                               break;
+                       fclose(tmp);
+               }
+               lastLightmap = lightmapCount - 1;
+       }
+       else
+       {
+               for( i = 0; i < numBSPShaders; i++ )
+               {
+                       shader = &bspShaders[ i ];
+                       ConvertShaderToMTL( fmtl, shader, i );
+               }
+       }
+       
+       /* walk entity list */
+       for( i = 0; i < numEntities; i++ )
+       {
+               /* get entity and model */
+               e = &entities[ i ];
+               if( i == 0 )
+                       modelNum = 0;
+               else
+               {
+                       key = ValueForKey( e, "model" );
+                       if( key[ 0 ] != '*' )
+                               continue;
+                       modelNum = atoi( key + 1 );
+               }
+               model = &bspModels[ modelNum ];
+               
+               /* get entity origin */
+               key = ValueForKey( e, "origin" );
+               if( key[ 0 ] == '\0' )
+                       VectorClear( origin );
+               else
+                       GetVectorForKey( e, "origin", origin );
+               
+               /* convert model */
+               ConvertModelToOBJ( f, model, modelNum, origin );
+       }
+       
+       if(lightmapsAsTexcoord)
+       {
+               for( i = firstLightmap; i <= lastLightmap; i++ )
+                       ConvertLightmapToMTL( fmtl, base, i );
+       }
+
+       /* close the file and return */
+       fclose( f );
+       fclose( fmtl );
+       
+       /* return to sender */
+       return 0;
+}
+
+
+
index 87d32b5563e0ea262079c6f5eb9d7d682891a85b..8add5bbe09a78a221559536d92ce5309d5809bc9 100644 (file)
@@ -166,7 +166,7 @@ game_t struct
        MINIMAP_MODE_GRAY,  /* minimap mode */
        "%s.tga",           /* minimap name format */
        "IBSP",                         /* bsp file prefix */
-       46,                                     /* bsp file version */
+       47,                                     /* bsp file version */
        qfalse,                         /* cod-style lump len/ofs order */
        LoadIBSPFile,           /* bsp load function */
        WriteIBSPFile,          /* bsp write function */
diff --git a/tools/quake3/q3map2/game_reaction.h b/tools/quake3/q3map2/game_reaction.h
new file mode 100644 (file)
index 0000000..c81e724
--- /dev/null
@@ -0,0 +1,194 @@
+/* -------------------------------------------------------------------------------
+
+Copyright (C) 1999-2007 id Software, Inc. and contributors.
+For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+This file is part of GtkRadiant.
+
+GtkRadiant is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GtkRadiant is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GtkRadiant; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+----------------------------------------------------------------------------------
+
+This code has been altered significantly from its original form, to support
+several games based on the Quake III Arena engine, in the form of "Q3Map2."
+
+------------------------------------------------------------------------------- */
+
+
+
+/* marker */
+#ifndef GAME_REACTION_H
+#define GAME_REACTION_H
+
+
+
+/* -------------------------------------------------------------------------------
+
+inherit content and surface flags from game_quake3.h
+(this file must be included AFTER game_quake3.h)
+
+Additional surface flags follow.  These were given to me (Rambetter) by TTI from the Reaction team.
+Note that some of these values have more than one bit set.  I'm not sure how Reaction is using these
+bits, but this is what I got from TTI.
+
+------------------------------------------------------------------------------- */
+
+#define        REACTION_SURF_GRAVEL    0x80000
+#define        REACTION_SURF_WOOD      0x81000
+#define        REACTION_SURF_CARPET    0x100000
+#define        REACTION_SURF_METAL2    0x101000
+#define        REACTION_SURF_GLASS     0x180000
+#define        REACTION_SURF_GRASS     0x181000
+#define        REACTION_SURF_SNOW      0x200000
+#define        REACTION_SURF_MUD       0x201000
+#define        REACTION_SURF_WOOD2     0x280000
+#define        REACTION_SURF_HARDMETAL 0x281000
+#define        REACTION_SURF_LEAVES    0x300000
+#define        REACTION_SURF_CEMENT    0x301000
+#define        REACTION_SURF_MARBLE    0x380000
+#define        REACTION_SURF_SNOW2     0x381000
+#define        REACTION_SURF_HARDSTEPS 0x400000
+#define        REACTION_SURF_SAND      0x401000
+
+
+
+/* -------------------------------------------------------------------------------
+
+game_t struct
+
+------------------------------------------------------------------------------- */
+
+{
+       "reaction",                     /* -game x */
+       "Boomstick",                    /* default base game data dir */
+       ".Reaction",                            /* unix home sub-dir */
+       "reaction",                     /* magic path word */
+       "scripts",                      /* shader directory */
+       64,                                     /* max lightmapped surface verts */
+       999,                            /* max surface verts */
+       6000,                           /* max surface indexes */
+       qfalse,                         /* flares */
+       "flareshader",          /* default flare shader */
+       qfalse,                         /* wolf lighting model? */
+       128,                            /* lightmap width/height */
+       1.0f,                           /* lightmap gamma */
+       1.0f,                           /* lightmap exposure */
+       1.0f,                           /* lightmap compensate */
+       1.0f,                           /* lightgrid scale */
+       1.0f,                           /* lightgrid ambient scale */
+       qfalse,                         /* light angle attenuation uses half-lambert curve */
+       qfalse,                         /* disable shader lightstyles hack */
+       qfalse,                         /* keep light entities on bsp */
+       8,                                      /* default patchMeta subdivisions tolerance */
+       qfalse,                         /* patch casting enabled */
+       qfalse,                         /* compile deluxemaps */
+       0,                                      /* deluxemaps default mode */
+       512,                /* minimap size */
+       1.0f,               /* minimap sharpener */
+       0.0f,               /* minimap border */
+       qtrue,              /* minimap keep aspect */
+       MINIMAP_MODE_GRAY,  /* minimap mode */
+       "%s.tga",           /* minimap name format */
+       "IBSP",                         /* bsp file prefix */
+       46,                                     /* bsp file version */
+       qfalse,                         /* cod-style lump len/ofs order */
+       LoadIBSPFile,           /* bsp load function */
+       WriteIBSPFile,          /* bsp write function */
+
+       {
+               /* name                         contentFlags                            contentFlagsClear                       surfaceFlags                            surfaceFlagsClear                       compileFlags                            compileFlagsClear */
+               
+               /* default */
+               { "default",            Q_CONT_SOLID,                           -1,                                                     0,                                                      -1,                                                     C_SOLID,                                        -1 },
+               
+               
+               /* ydnar */
+               { "lightgrid",          0,                                                      0,                                                      0,                                                      0,                                                      C_LIGHTGRID,                            0 },
+               { "antiportal",         0,                                                      0,                                                      0,                                                      0,                                                      C_ANTIPORTAL,                           0 },
+               { "skip",                       0,                                                      0,                                                      0,                                                      0,                                                      C_SKIP,                                         0 },
+               
+               
+               /* compiler */
+               { "origin",                     Q_CONT_ORIGIN,                          Q_CONT_SOLID,                           0,                                                      0,                                                      C_ORIGIN | C_TRANSLUCENT,       C_SOLID },
+               { "areaportal",         Q_CONT_AREAPORTAL,                      Q_CONT_SOLID,                           0,                                                      0,                                                      C_AREAPORTAL | C_TRANSLUCENT,   C_SOLID },
+               { "trans",                      Q_CONT_TRANSLUCENT,                     0,                                                      0,                                                      0,                                                      C_TRANSLUCENT,                          0 },
+               { "detail",                     Q_CONT_DETAIL,                          0,                                                      0,                                                      0,                                                      C_DETAIL,                                       0 },
+               { "structural",         Q_CONT_STRUCTURAL,                      0,                                                      0,                                                      0,                                                      C_STRUCTURAL,                           0 },
+               { "hint",                       0,                                                      0,                                                      Q_SURF_HINT,                            0,                                                      C_HINT,                                         0 },
+               { "nodraw",                     0,                                                      0,                                                      Q_SURF_NODRAW,                          0,                                                      C_NODRAW,                                       0 },
+               
+               { "alphashadow",        0,                                                      0,                                                      Q_SURF_ALPHASHADOW,                     0,                                                      C_ALPHASHADOW | C_TRANSLUCENT,  0 },
+               { "lightfilter",        0,                                                      0,                                                      Q_SURF_LIGHTFILTER,                     0,                                                      C_LIGHTFILTER | C_TRANSLUCENT,  0 },
+               { "nolightmap",         0,                                                      0,                                                      Q_SURF_VERTEXLIT,                       0,                                                      C_VERTEXLIT,                            0 },
+               { "pointlight",         0,                                                      0,                                                      Q_SURF_VERTEXLIT,                       0,                                                      C_VERTEXLIT,                            0 },
+               
+               
+               /* game */
+               { "nonsolid",           0,                                                      Q_CONT_SOLID,                           Q_SURF_NONSOLID,                        0,                                                      0,                                                      C_SOLID },
+               
+               { "trigger",            Q_CONT_TRIGGER,                         Q_CONT_SOLID,                           0,                                                      0,                                                      C_TRANSLUCENT,                          C_SOLID },
+               
+               { "water",                      Q_CONT_WATER,                           Q_CONT_SOLID,                           0,                                                      0,                                                      C_LIQUID | C_TRANSLUCENT,       C_SOLID },
+               { "slime",                      Q_CONT_SLIME,                           Q_CONT_SOLID,                           0,                                                      0,                                                      C_LIQUID | C_TRANSLUCENT,       C_SOLID },
+               { "lava",                       Q_CONT_LAVA,                            Q_CONT_SOLID,                           0,                                                      0,                                                      C_LIQUID | C_TRANSLUCENT,       C_SOLID },
+               
+               { "playerclip",         Q_CONT_PLAYERCLIP,                      Q_CONT_SOLID,                           0,                                                      0,                                                      C_DETAIL | C_TRANSLUCENT,       C_SOLID },
+               { "monsterclip",        Q_CONT_MONSTERCLIP,                     Q_CONT_SOLID,                           0,                                                      0,                                                      C_DETAIL | C_TRANSLUCENT,       C_SOLID },
+               { "nodrop",                     Q_CONT_NODROP,                          Q_CONT_SOLID,                           0,                                                      0,                                                      C_TRANSLUCENT,                          C_SOLID },
+               
+               { "clusterportal",      Q_CONT_CLUSTERPORTAL,           Q_CONT_SOLID,                           0,                                                      0,                                                      C_TRANSLUCENT,                          C_SOLID },
+               { "donotenter",         Q_CONT_DONOTENTER,                      Q_CONT_SOLID,                           0,                                                      0,                                                      C_TRANSLUCENT,                          C_SOLID },
+               { "botclip",            Q_CONT_BOTCLIP,                         Q_CONT_SOLID,                           0,                                                      0,                                                      C_TRANSLUCENT,                          C_SOLID },
+               
+               { "fog",                        Q_CONT_FOG,                                     Q_CONT_SOLID,                           0,                                                      0,                                                      C_FOG,                                          C_SOLID },
+               { "sky",                        0,                                                      0,                                                      Q_SURF_SKY,                                     0,                                                      C_SKY,                                          0 },
+               
+               { "slick",                      0,                                                      0,                                                      Q_SURF_SLICK,                           0,                                                      0,                                                      0 },
+               
+               { "noimpact",           0,                                                      0,                                                      Q_SURF_NOIMPACT,                        0,                                                      0,                                                      0 },
+               { "nomarks",            0,                                                      0,                                                      Q_SURF_NOMARKS,                         0,                                                      C_NOMARKS,                                      0 },
+               { "ladder",                     0,                                                      0,                                                      Q_SURF_LADDER,                          0,                                                      0,                                                      0 },
+               { "nodamage",           0,                                                      0,                                                      Q_SURF_NODAMAGE,                        0,                                                      0,                                                      0 },
+               { "metalsteps",         0,                                                      0,                                                      Q_SURF_METALSTEPS,                      0,                                                      0,                                                      0 },
+               { "flesh",                      0,                                                      0,                                                      Q_SURF_FLESH,                           0,                                                      0,                                                      0 },
+               { "nosteps",            0,                                                      0,                                                      Q_SURF_NOSTEPS,                         0,                                                      0,                                                      0 },
+               { "nodlight",           0,                                                      0,                                                      Q_SURF_NODLIGHT,                        0,                                                      0,                                                      0 },
+               { "dust",                       0,                                                      0,                                                      Q_SURF_DUST,                            0,                                                      0,                                                      0 },
+               { "rq3_gravel",         0,      0,      REACTION_SURF_GRAVEL,           0,      0,      0 },
+               { "rq3_wood",           0,      0,      REACTION_SURF_WOOD,             0,      0,      0 },
+               { "rq3_carpet",         0,      0,      REACTION_SURF_CARPET,           0,      0,      0 },
+               { "rq3_metal2",         0,      0,      REACTION_SURF_METAL2,           0,      0,      0 },
+               { "rq3_glass",          0,      0,      REACTION_SURF_GLASS,            0,      0,      0 },
+               { "rq3_grass",          0,      0,      REACTION_SURF_GRASS,            0,      0,      0 },
+               { "rq3_snow",           0,      0,      REACTION_SURF_SNOW,             0,      0,      0 },
+               { "rq3_mud",            0,      0,      REACTION_SURF_MUD,              0,      0,      0 },
+               { "rq3_wood2",          0,      0,      REACTION_SURF_WOOD2,            0,      0,      0 },
+               { "rq3_hardmetal",      0,      0,      REACTION_SURF_HARDMETAL,        0,      0,      0 },
+               { "rq3_leaves",         0,      0,      REACTION_SURF_LEAVES,           0,      0,      0 },
+               { "rq3_cement",         0,      0,      REACTION_SURF_CEMENT,           0,      0,      0 },
+               { "rq3_marble",         0,      0,      REACTION_SURF_MARBLE,           0,      0,      0 },
+               { "rq3_snow2",          0,      0,      REACTION_SURF_SNOW2,            0,      0,      0 },
+               { "rq3_hardsteps",      0,      0,      REACTION_SURF_HARDSTEPS,        0,      0,      0 },
+               { "rq3_sand",           0,      0,      REACTION_SURF_SAND,             0,      0,      0 },
+               
+               /* null */
+               { NULL, 0, 0, 0, 0, 0, 0 }
+       }
+}
+
+
+
+/* end marker */
+#endif
index a703faacf53e8fff145e897ef42351055e3e62af..9323b8c8e3b7a4430244b7b6c12354b92466c6df 100644 (file)
@@ -2184,20 +2184,20 @@ int LightMain( int argc, char **argv )
                else if( !strcmp( argv[ i ], "-griddirectionality" ) )
                {
                        f = atof( argv[ i + 1 ] );
-                       if(f < 0) f = 0;
-                       if(f > gridAmbientDirectionality) f = gridAmbientDirectionality;
+                       if(f > 1) f = 1;
+                       if(f < gridAmbientDirectionality) gridAmbientDirectionality = f;
                        Sys_Printf( "Grid directionality is %f\n", f );
-                       gridDirectionality *= f;
+                       gridDirectionality = f;
                        i++;
                }
 
                else if( !strcmp( argv[ i ], "-gridambientdirectionality" ) )
                {
                        f = atof( argv[ i + 1 ] );
-                       if(f > gridDirectionality) f = gridDirectionality;
-                       if(f > 1) f = 1;
+                       if(f < -1) f = -1;
+                       if(f > gridDirectionality) gridDirectionality = f;
                        Sys_Printf( "Grid ambient directionality is %f\n", f );
-                       gridAmbientDirectionality *= f;
+                       gridAmbientDirectionality = f;
                        i++;
                }
                
index 2deb142989b4c6c76becbe0fce027f6be8449ed2..074a4a437732d5621022af0037d2b15c074687ca 100644 (file)
@@ -989,8 +989,8 @@ int AnalyzeBSP( int argc, char **argv )
                lump = (byte*) header + offset;
                lumpInt = LittleLong( (int) *((int*) lump) );
                lumpFloat = LittleFloat( (float) *((float*) lump) );
-               memcpy( lumpString, (char*) lump, (length < 1024 ? length : 1024) );
-               lumpString[ 1024 ] = '\0';
+               memcpy( lumpString, (char*) lump, (length < sizeof(lumpString) ? length : sizeof(lumpString)-1) );
+               lumpString[ sizeof(lumpString)-1 ] = '\0';
                
                /* print basic lump info */
                Sys_Printf( "Lump:          %d\n", i );
@@ -1537,19 +1537,20 @@ int ConvertBSPMain( int argc, char **argv )
        int             (*convertFunc)( char * );
        game_t  *convertGame;
        char            ext[1024];
-       qboolean        map_allowed, force_bsp;
+       qboolean        map_allowed, force_bsp, force_map;
        
        
        /* set default */
        convertFunc = ConvertBSPToASE;
        convertGame = NULL;
-       map_allowed = qtrue;
+       map_allowed = qfalse;
        force_bsp = qfalse;
+       force_map = qfalse;
        
        /* arg checking */
        if( argc < 1 )
        {
-               Sys_Printf( "Usage: q3map -scale <value> [-v] <mapname>\n" );
+               Sys_Printf( "Usage: q3map -convert -format <ase|obj|map_bp|map> [-shadesasbitmap|-lightmapsastexcoord|-deluxemapsastexcoord] [-readbsp|-readmap [-meta|-patchmeta]] <mapname>\n" );
                return 0;
        }
        
@@ -1565,6 +1566,11 @@ int ConvertBSPMain( int argc, char **argv )
                                convertFunc = ConvertBSPToASE;
                                map_allowed = qfalse;
                        }
+                       else if( !Q_stricmp( argv[ i ], "obj" ) )
+                       {
+                               convertFunc = ConvertBSPToOBJ;
+                               map_allowed = qfalse;
+                       }
                        else if( !Q_stricmp( argv[ i ], "map_bp" ) )
                        {
                                convertFunc = ConvertBSPToMap_BP;
@@ -1597,8 +1603,17 @@ int ConvertBSPMain( int argc, char **argv )
                }
                else if( !strcmp( argv[ i ],  "-shadersasbitmap" ) )
                        shadersAsBitmap = qtrue;
-               else if( !strcmp( argv[ i ],  "-forcereadbsp" ) )
+               else if( !strcmp( argv[ i ],  "-lightmapsastexcoord" ) )
+                       lightmapsAsTexcoord = qtrue;
+               else if( !strcmp( argv[ i ],  "-deluxemapsastexcoord" ) )
+               {
+                       lightmapsAsTexcoord = qtrue;
+                       deluxemap = qtrue;
+               }
+               else if( !strcmp( argv[ i ],  "-readbsp" ) )
                        force_bsp = qtrue;
+               else if( !strcmp( argv[ i ],  "-readmap" ) )
+                       force_map = qtrue;
                else if( !strcmp( argv[ i ],  "-meta" ) )
                        meta = qtrue;
                else if( !strcmp( argv[ i ],  "-patchmeta" ) )
@@ -1613,7 +1628,11 @@ int ConvertBSPMain( int argc, char **argv )
        /* clean up map name */
        strcpy(source, ExpandArg(argv[i]));
        ExtractFileExtension(source, ext);
-       if(!Q_stricmp(ext, "map") && !force_bsp)
+
+       if(!map_allowed && !force_map)
+               force_bsp = qtrue;
+
+       if(force_map || (!force_bsp && !Q_stricmp(ext, "map") && map_allowed))
        {
                if(!map_allowed)
                        Sys_Printf("WARNING: the requested conversion should not be done from .map files. Compile a .bsp first.\n");
index d61f51be26e60237469ee828c37579ba0dc28bad..95bb3d1f74141968c369d8fe3ccd34b72fc45afc 100644 (file)
@@ -59,9 +59,6 @@ PlaneEqual()
 ydnar: replaced with variable epsilon for djbob
 */
 
-#define        NORMAL_EPSILON  0.00001
-#define        DIST_EPSILON    0.01
-
 qboolean PlaneEqual( plane_t *p, vec3_t normal, vec_t dist )
 {
        float   ne, de;
@@ -72,10 +69,14 @@ qboolean PlaneEqual( plane_t *p, vec3_t normal, vec_t dist )
        de = distanceEpsilon;
        
        /* compare */
-       if( fabs( p->dist - dist ) <= de &&
-               fabs( p->normal[ 0 ] - normal[ 0 ] ) <= ne &&
-               fabs( p->normal[ 1 ] - normal[ 1 ] ) <= ne &&
-               fabs( p->normal[ 2 ] - normal[ 2 ] ) <= ne )
+       // We check equality of each component since we're using '<', not '<='
+       // (the epsilons may be zero).  We want to use '<' intead 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) &&
+                       (p->normal[0] == normal[0] || fabs(p->normal[0] - normal[0]) < ne) &&
+                       (p->normal[1] == normal[1] || fabs(p->normal[1] - normal[1]) < ne) &&
+                       (p->normal[2] == normal[2] || fabs(p->normal[2] - normal[2]) < ne))
                return qtrue;
        
        /* different */
@@ -152,28 +153,91 @@ int CreateNewFloatPlane (vec3_t normal, vec_t dist)
 
 /*
 SnapNormal()
-snaps a near-axial normal vector
+Snaps a near-axial normal vector.
+Returns qtrue if and only if the normal was adjusted.
 */
 
-void SnapNormal( vec3_t normal )
+qboolean SnapNormal( vec3_t normal )
 {
+#if Q3MAP2_EXPERIMENTAL_SNAP_NORMAL_FIX
+       int             i;
+       qboolean        adjusted = qfalse;
+
+       // A change from the original SnapNormal() is that we snap each
+       // component that's close to 0.  So for example if a normal is
+       // (0.707, 0.707, 0.0000001), it will get snapped to lie perfectly in the
+       // XY plane (its Z component will be set to 0 and its length will be
+       // normalized).  The original SnapNormal() didn't snap such vectors - it
+       // only snapped vectors that were near a perfect axis.
+
+       for (i = 0; i < 3; i++)
+       {
+               if (normal[i] != 0.0 && -normalEpsilon < normal[i] && normal[i] < normalEpsilon)
+               {
+                       normal[i] = 0.0;
+                       adjusted = qtrue;
+               }
+       }
+
+       if (adjusted)
+       {
+               VectorNormalize(normal, normal);
+               return qtrue;
+       }
+       return qfalse;
+#else
        int             i;
 
+       // I would suggest that you uncomment the following code and look at the
+       // results:
+
+       /*
+       Sys_Printf("normalEpsilon is %f\n", normalEpsilon);
+       for (i = 0;; i++)
+       {
+               normal[0] = 1.0;
+               normal[1] = 0.0;
+               normal[2] = i * 0.000001;
+               VectorNormalize(normal, normal);
+               if (1.0 - normal[0] >= normalEpsilon) {
+                       Sys_Printf("(%f %f %f)\n", normal[0], normal[1], normal[2]);
+                       Error("SnapNormal: test completed");
+               }
+       }
+       */
+
+       // When the normalEpsilon is 0.00001, the loop will break out when normal is
+       // (0.999990 0.000000 0.004469).  In other words, this is the vector closest
+       // to axial that will NOT be snapped.  Anything closer will be snaped.  Now,
+       // 0.004469 is close to 1/225.  The length of a circular quarter-arc of radius
+       // 1 is PI/2, or about 1.57.  And 0.004469/1.57 is about 0.0028, or about
+       // 1/350.  Expressed a different way, 1/350 is also about 0.26/90.
+       // This means is that a normal with an angle that is within 1/4 of a degree
+       // from axial will be "snapped".  My belief is that the person who wrote the
+       // code below did not intend it this way.  I think the person intended that
+       // the epsilon be measured against the vector components close to 0, not 1.0.
+       // I think the logic should be: if 2 of the normal components are within
+       // epsilon of 0, then the vector can be snapped to be perfectly axial.
+       // We may consider adjusting the epsilon to a larger value when we make this
+       // code fix.
+
        for( i = 0; i < 3; i++ )
        {
                if( fabs( normal[ i ] - 1 ) < normalEpsilon )
                {
                        VectorClear( normal );
                        normal[ i ] = 1;
-                       break;
+                       return qtrue;
                }
                if( fabs( normal[ i ] - -1 ) < normalEpsilon )
                {
                        VectorClear( normal );
                        normal[ i ] = -1;
-                       break;
+                       return qtrue;
                }
        }
+       return qfalse;
+#endif
 }
 
 
@@ -192,18 +256,70 @@ void SnapPlane( vec3_t normal, vec_t *dist, vec3_t center )
   SnapPlane reenabled by namespace because of multiple reports of
   q3map2-crashes which were triggered by this patch.
 */
-       // div0: ensure the point "center" stays on the plane (actually, this
-       // rotates the plane around the point center).
-       // if center lies on the plane, it is guaranteed to stay on the plane by
-       // this fix.
-       vec_t centerDist = DotProduct(normal, center);
        SnapNormal( normal );
-       *dist += (DotProduct(normal, center) - centerDist);
+
+       // TODO: Rambetter has some serious comments here as well.  First off,
+       // in the case where a normal is non-axial, there is nothing special
+       // about integer distances.  I would think that snapping a distance might
+       // make sense for axial normals, but I'm not so sure about snapping
+       // non-axial normals.  A shift by 0.01 in a plane, multiplied by a clipping
+       // against another plane that is 5 degrees off, and we introduce 0.1 error
+       // easily.  A 0.1 error in a vertex is where problems start to happen, such
+       // as disappearing triangles.
+
+       // Second, assuming we have snapped the normal above, let's say that the
+       // plane we just snapped was defined for some points that are actually
+       // quite far away from normal * dist.  Well, snapping the normal in this
+       // case means that we've just moved those points by potentially many units!
+       // Therefore, if we are going to snap the normal, we need to know the
+       // points we're snapping for so that the plane snaps with those points in
+       // mind (points remain close to the plane).
+
+       // I would like to know exactly which problems SnapPlane() is trying to
+       // solve so that we can better engineer it (I'm not saying that SnapPlane()
+       // should be removed altogether).  Fix all this snapping code at some point!
 
        if( fabs( *dist - Q_rint( *dist ) ) < distanceEpsilon )
                *dist = Q_rint( *dist );
 }
 
+/*
+SnapPlaneImproved()
+snaps a plane to normal/distance epsilons, improved code
+*/
+void SnapPlaneImproved(vec3_t normal, vec_t *dist, int numPoints, const vec3_t *points)
+{
+       int     i;
+       vec3_t  center;
+       vec_t   distNearestInt;
+
+       if (SnapNormal(normal))
+       {
+               if (numPoints > 0)
+               {
+                       // Adjust the dist so that the provided points don't drift away.
+                       VectorClear(center);
+                       for (i = 0; i < numPoints; i++)
+                       {
+                               VectorAdd(center, points[i], center);
+                       }
+                       for (i = 0; i < 3; i++) { center[i] = center[i] / numPoints; }
+                       *dist = DotProduct(normal, center);
+               }
+       }
+
+       if (VectorIsOnAxis(normal))
+       {
+               // Only snap distance if the normal is an axis.  Otherwise there
+               // is nothing "natural" about snapping the distance to an integer.
+               distNearestInt = Q_rint(*dist);
+               if (-distanceEpsilon < *dist - distNearestInt && *dist - distNearestInt < distanceEpsilon)
+               {
+                       *dist = distNearestInt;
+               }
+       }
+}
+
 
 
 /*
@@ -221,16 +337,15 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points )
        int pidx;
        plane_t *p;
        vec_t   d;
-       vec3_t centerofweight;
        vec3_t normal;
 
-       VectorClear(centerofweight);
-       for(i = 0; i < numPoints; ++i)
-               VectorMA(centerofweight, 1.0 / numPoints, points[i], centerofweight);
-       
-       /* hash the plane */
        VectorCopy(innormal, normal);
-       SnapPlane( normal, &dist, centerofweight );
+#if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX
+       SnapPlaneImproved(normal, &dist, numPoints, (const vec3_t *) points);
+#else
+       SnapPlane( normal, &dist );
+#endif
+       /* hash the plane */
        hash = (PLANE_HASHES - 1) & (int) fabs( dist );
        
        /* search the border bins as well */
@@ -251,9 +366,15 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points )
                        /* ydnar: test supplied points against this plane */
                        for( j = 0; j < numPoints; j++ )
                        {
+                               // 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.
                                d = DotProduct( points[ j ], p->normal ) - p->dist;
-                               if( fabs( d ) > distanceEpsilon )
-                                       break;
+                               d = fabs(d);
+                               if (d != 0.0 && d >= distanceEpsilon)
+                                       break; // Point is too far from plane.
                        }
                        
                        /* found a matching plane */
@@ -273,15 +394,12 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points )
        plane_t *p;
        vec3_t normal;
        
-
-       vec3_t centerofweight;
-
-       VectorClear(centerofweight);
-       for(i = 0; i < numPoints; ++i)
-               VectorMA(centerofweight, 1.0 / numPoints, points[i], centerofweight);
-
        VectorCopy(innormal, normal);
-       SnapPlane( normal, &dist, centerofweight );
+#if Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX
+       SnapPlaneImproved(normal, &dist, numPoints, (const vec3_t *) points);
+#else
+       SnapPlane( normal, &dist );
+#endif
        for( i = 0, p = mapplanes; i < nummapplanes; i++, p++ )
        {
                if( !PlaneEqual( p, normal, dist ) )
@@ -301,6 +419,9 @@ int FindFloatPlane( vec3_t innormal, vec_t dist, int numPoints, vec3_t *points )
                /* 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.
        }
        
        return CreateNewFloatPlane( normal, dist );
@@ -317,6 +438,28 @@ takes 3 points and finds the plane they lie in
 
 int MapPlaneFromPoints( vec3_t *p )
 {
+#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES
+       vec3_accu_t     paccu[3];
+       vec3_accu_t     t1, t2, normalAccu;
+       vec3_t          normal;
+       vec_t           dist;
+
+       VectorCopyRegularToAccu(p[0], paccu[0]);
+       VectorCopyRegularToAccu(p[1], paccu[1]);
+       VectorCopyRegularToAccu(p[2], paccu[2]);
+
+       VectorSubtractAccu(paccu[0], paccu[1], t1);
+       VectorSubtractAccu(paccu[2], paccu[1], t2);
+       CrossProductAccu(t1, t2, normalAccu);
+       VectorNormalizeAccu(normalAccu, normalAccu);
+       // TODO: A 32 bit float for the plane distance isn't enough resolution
+       // if the plane is 2^16 units away from the origin (the "epsilon" approaches
+       // 0.01 in that case).
+       dist = (vec_t) DotProductAccu(paccu[0], normalAccu);
+       VectorCopyAccuToRegular(normalAccu, normal);
+
+       return FindFloatPlane(normal, dist, 3, p);
+#else
        vec3_t  t1, t2, normal;
        vec_t   dist;
        
@@ -332,6 +475,7 @@ int MapPlaneFromPoints( vec3_t *p )
        
        /* store the plane */
        return FindFloatPlane( normal, dist, 3, p );
+#endif
 }
 
 
index 05213cf1ae545ab0efb29ec2d6801f11ee95e291..a56134c82777066c33851d4a8e33f60e6ad6c22a 100644 (file)
@@ -229,7 +229,6 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
        char                            *skinfilecontent;
        int                                     skinfilesize;
        char                            *skinfileptr, *skinfilenextptr;
-       FILE                            *skinfilehandle;
        
        
        /* get model */
@@ -240,7 +239,6 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
        /* load skin file */
        snprintf(skinfilename, sizeof(skinfilename), "%s_%d.skin", name, skin);
        skinfilename[sizeof(skinfilename)-1] = 0;
-       skinfilehandle = fopen(skinfilename, "r");
        skinfilesize = vfsLoadFile(skinfilename, (void**) &skinfilecontent, 0);
        if(skinfilesize < 0 && skin != 0)
        {
@@ -530,19 +528,6 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap
                                        
                                        /* copy xyz */
                                        VectorCopy( dv->xyz, points[ j ] );
-                                       VectorCopy( dv->xyz, backs[ j ] );
-                                       
-                                       /* find nearest axial to normal and push back points opposite */
-                                       /* note: this doesn't work as well as simply using the plane of the triangle, below */
-                                       for( k = 0; k < 3; k++ )
-                                       {
-                                               if( fabs( dv->normal[ k ] ) >= fabs( dv->normal[ (k + 1) % 3 ] ) &&
-                                                       fabs( dv->normal[ k ] ) >= fabs( dv->normal[ (k + 2) % 3 ] ) )
-                                               {
-                                                       backs[ j ][ k ] += dv->normal[ k ] < 0.0f ? 64.0f : -64.0f;
-                                                       break;
-                                               }
-                                       }
                                }
 
                                VectorCopy( points[0], points[3] ); // for cyclic usage
index e6b4d959b7d06f16dff3f7b17204edb0d7ad9e89..83383e2287ba3cdae523ab375748b7cb2387b046 100644 (file)
@@ -305,6 +305,8 @@ adds a game path to the list
 
 void AddGamePath( char *path )
 {
+       int     i;
+
        /* dummy check */
        if( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS )
                return;
@@ -314,6 +316,19 @@ void AddGamePath( char *path )
        strcpy( gamePaths[ numGamePaths ], path );
        CleanPath( gamePaths[ numGamePaths ] );
        numGamePaths++;
+
+       /* don't add it if it's already there */
+       for (i = 0; i < numGamePaths - 1; i++)
+       {
+               if (strcmp(gamePaths[i], gamePaths[numGamePaths - 1]) == 0)
+               {
+                       free(gamePaths[numGamePaths - 1]);
+                       gamePaths[numGamePaths - 1] = NULL;
+                       numGamePaths--;
+                       break;
+               }
+       }
+       
 }
 
 
index cc3e0d9d392dd509131ae96e97a3ff82b30e7a5e..2efc1db47c0ea1bcad12fa27bcae6d214038cf92 100644 (file)
@@ -725,7 +725,11 @@ qboolean FloodEntities( tree_t *tree )
                r = PlaceOccupant( headnode, origin, e, skybox );
                if( r )
                        inside = qtrue;
-               if( (!r || tree->outside_node.occupied) && !tripped )
+               if( !r )
+               {
+                       Sys_Printf( "Entity %i, Brush %i: Entity in solid\n", e->mapEntityNum, 0);
+               }
+               else if( tree->outside_node.occupied && !tripped )
                {
                        xml_Select( "Entity leaked", e->mapEntityNum, 0, qfalse );
                        tripped = qtrue;
index baa29c7c31b15f32937e2cf1de37e65afa129db9..e912d15b26865f6b98d6ad01ddf6d6f1838606bd 100644 (file)
@@ -122,6 +122,12 @@ constants
 
 ------------------------------------------------------------------------------- */
 
+/* temporary hacks and tests (please keep off in SVN to prevent anyone's legacy map from screwing up) */
+/* 2011-01-10 TTimo says we should turn these on in SVN, so turning on now */
+#define Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES  1
+#define Q3MAP2_EXPERIMENTAL_SNAP_NORMAL_FIX            1
+#define Q3MAP2_EXPERIMENTAL_SNAP_PLANE_FIX             1
+
 /* general */
 #define MAX_QPATH                              64
 
@@ -1530,6 +1536,9 @@ int                                                       ConvertBSPToMap_BP( char *bspName );
 /* convert_ase.c */
 int                                                    ConvertBSPToASE( char *bspName );
 
+/* convert_obj.c */
+int                                                    ConvertBSPToOBJ( char *bspName );
+
 
 /* brush.c */
 sideRef_t                                      *AllocSideRef( side_t *side, sideRef_t *next );
@@ -1947,6 +1956,8 @@ Q_EXTERN game_t                           games[]
                                                                ,
                                                                #include "game_qfusion.h"       /* qfusion game */
                                                                ,
+                                                               #include "game_reaction.h" /* must be after game_quake3.h */
+                                                               ,
                                                                #include "game_darkplaces.h"    /* vortex: darkplaces q1 engine */
                                                                ,
                                                                #include "game_dq.h"    /* vortex: deluxe quake game ( darkplaces q1 engine) */
@@ -2023,8 +2034,31 @@ Q_EXTERN qboolean                        debugPortals Q_ASSIGN( qfalse );
 Q_EXTERN qboolean           lightmapTriangleCheck Q_ASSIGN(qfalse);
 Q_EXTERN qboolean           lightmapExtraVisClusterNudge Q_ASSIGN(qfalse);
 Q_EXTERN qboolean           lightmapFill Q_ASSIGN(qfalse);
+
+#if Q3MAP2_EXPERIMENTAL_SNAP_NORMAL_FIX
+// Increasing the normalEpsilon to compensate for new logic in SnapNormal(), where
+// this epsilon is now used to compare against 0 components instead of the 1 or -1
+// components.  Unfortunately, normalEpsilon is also used in PlaneEqual().  So changing
+// this will affect anything that calls PlaneEqual() as well (which are, at the time
+// of this writing, FindFloatPlane() and AddBrushBevels()).
+Q_EXTERN double                                normalEpsilon Q_ASSIGN(0.00005);
+#else
 Q_EXTERN double                                normalEpsilon Q_ASSIGN( 0.00001 );
+#endif
+
+#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES
+// NOTE: This distanceEpsilon is too small if parts of the map are at maximum world
+// extents (in the range of plus or minus 2^16).  The smallest epsilon at values
+// close to 2^16 is about 0.007, which is greater than distanceEpsilon.  Therefore,
+// maps should be constrained to about 2^15, otherwise slightly undesirable effects
+// may result.  The 0.01 distanceEpsilon used previously is just too coarse in my
+// opinion.  The real fix for this problem is to have 64 bit distances and then make
+// this epsilon even smaller, or to constrain world coordinates to plus minus 2^15
+// (or even 2^14).
+Q_EXTERN double                                distanceEpsilon Q_ASSIGN(0.005);
+#else
 Q_EXTERN double                                distanceEpsilon Q_ASSIGN( 0.01 );
+#endif
 
 
 /* bsp */
@@ -2272,6 +2306,7 @@ Q_EXTERN float                            linearScale Q_ASSIGN( 1.0f / 8000.0f );
 
 // for .ase conversion
 Q_EXTERN qboolean                      shadersAsBitmap Q_ASSIGN( qfalse );
+Q_EXTERN qboolean                      lightmapsAsTexcoord Q_ASSIGN( qfalse );
 
 Q_EXTERN light_t                       *lights;
 Q_EXTERN int                           numPointLights;