From: Rudolf Polzer Date: Mon, 14 Feb 2011 18:42:28 +0000 (+0100) Subject: Merge remote-tracking branch 'origin/divVerent/weird-shift-a' X-Git-Tag: xonotic-v0.5.0~43^2~1 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=commitdiff_plain;h=de28d9de1d75fd0a8ce419d695962c502aa6a3e3;hp=4f075a2ec1f51c723a5fc79eb9774f72211368c4 Merge remote-tracking branch 'origin/divVerent/weird-shift-a' --- diff --git a/Makefile b/Makefile index cd0c002a..b0a1d4a2 100644 --- 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 \ diff --git a/docs/index.html b/docs/index.html index 45a168ec..68811708 100644 --- a/docs/index.html +++ b/docs/index.html @@ -11,6 +11,6 @@ -

put here links

+

Xonotic Mapping Wiki

diff --git a/libs/mathlib.h b/libs/mathlib.h index d206d330..382933d7 100644 --- a/libs/mathlib.h +++ b/libs/mathlib.h @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // mathlib.h #include +#include #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 diff --git a/libs/mathlib/mathlib.c b/libs/mathlib/mathlib.c index c549cb10..98fb972a 100644 --- a/libs/mathlib/mathlib.c +++ b/libs/mathlib/mathlib.c @@ -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; +} + + diff --git a/radiant/console.cpp b/radiant/console.cpp index db7997e1..cff963f2 100644 --- a/radiant/console.cpp +++ b/radiant/console.cpp @@ -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) { diff --git a/radiant/main.cpp b/radiant/main.cpp index 15baa3c0..a7c22426 100644 --- a/radiant/main.cpp +++ b/radiant/main.cpp @@ -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 diff --git a/radiant/map.cpp b/radiant/map.cpp index 7b8c570d..57245990 100644 --- a/radiant/map.cpp +++ b/radiant/map.cpp @@ -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("\""); diff --git a/radiant/xywindow.cpp b/radiant/xywindow.cpp index ff7852e7..7352b386 100644 --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@ -2965,9 +2965,9 @@ void XYWindow_Construct() GlobalCommands_insert("NextView", FreeCaller(), Accelerator(GDK_Tab, (GdkModifierType)GDK_CONTROL_MASK)); GlobalCommands_insert("ZoomIn", FreeCaller(), Accelerator(GDK_Delete)); GlobalCommands_insert("ZoomOut", FreeCaller(), Accelerator(GDK_Insert)); - GlobalCommands_insert("ViewTop", FreeCaller()); - GlobalCommands_insert("ViewSide", FreeCaller()); - GlobalCommands_insert("ViewFront", FreeCaller()); + GlobalCommands_insert("ViewTop", FreeCaller(), Accelerator(GDK_KP_Home)); + GlobalCommands_insert("ViewSide", FreeCaller(), Accelerator(GDK_KP_Page_Down)); + GlobalCommands_insert("ViewFront", FreeCaller(), Accelerator(GDK_KP_End)); GlobalCommands_insert("Zoom100", FreeCaller()); GlobalCommands_insert("CenterXYView", FreeCaller(), 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 index 00000000..599ec3d4 --- /dev/null +++ b/regression_tests/q3map2/base_winding/README.txt @@ -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 index 00000000..20fbaee3 --- /dev/null +++ b/regression_tests/q3map2/base_winding/base_winding_logging.patch @@ -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 index 00000000..237278a2 --- /dev/null +++ b/regression_tests/q3map2/base_winding/maps/base_winding.map @@ -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 index 00000000..6525380d --- /dev/null +++ b/regression_tests/q3map2/coarse_snap_normal/README.txt @@ -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 index 00000000..9be4523b --- /dev/null +++ b/regression_tests/q3map2/coarse_snap_normal/maps/coarse_snap_normal.map @@ -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 index 00000000..f9aa3d6d --- /dev/null +++ b/regression_tests/q3map2/decal_misalignment/README.txt @@ -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 index 00000000..b764bf20 --- /dev/null +++ b/regression_tests/q3map2/decal_misalignment/maps/decal_misalignment.map @@ -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 index 00000000..af31c07d --- /dev/null +++ b/regression_tests/q3map2/decal_misalignment/scripts/radiant_regression_tests.shader @@ -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 index 00000000..b060d083 --- /dev/null +++ b/regression_tests/q3map2/degenerate_winding/README.txt @@ -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 index 00000000..808de186 --- /dev/null +++ b/regression_tests/q3map2/degenerate_winding/maps/degenerate_winding.map @@ -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 index 00000000..b36f2db3 --- /dev/null +++ b/regression_tests/q3map2/degenerate_winding2/README.txt @@ -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 index 00000000..70abf7cc --- /dev/null +++ b/regression_tests/q3map2/degenerate_winding2/maps/degenerate_winding2.map @@ -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 index 00000000..3aa08fc9 --- /dev/null +++ b/regression_tests/q3map2/degenerate_winding3/README.txt @@ -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 index 00000000..1817265b --- /dev/null +++ b/regression_tests/q3map2/degenerate_winding3/maps/degenerate_winding3.map @@ -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 index 00000000..a65d9203 --- /dev/null +++ b/regression_tests/q3map2/disappearing_sliver/README.txt @@ -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 index 00000000..82528868 --- /dev/null +++ b/regression_tests/q3map2/disappearing_sliver/maps/disappearing_sliver.map @@ -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 index 00000000..a1babe91 --- /dev/null +++ b/regression_tests/q3map2/disappearing_sliver/winding_logging.patch @@ -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 index 00000000..ffa12be5 --- /dev/null +++ b/regression_tests/q3map2/disappearing_sliver2/README.txt @@ -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 index 00000000..53e18710 --- /dev/null +++ b/regression_tests/q3map2/disappearing_sliver2/maps/disappearing_sliver2.map @@ -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 index 00000000..70bb752a --- /dev/null +++ b/regression_tests/q3map2/disappearing_sliver3/NOTES.txt @@ -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 index 00000000..839bd692 --- /dev/null +++ b/regression_tests/q3map2/disappearing_sliver3/README.txt @@ -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 index 00000000..a56c649d --- /dev/null +++ b/regression_tests/q3map2/disappearing_sliver3/maps/disappearing_sliver3.map @@ -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 index 00000000..8c2ef028 --- /dev/null +++ b/regression_tests/q3map2/duplicate_plane/README.txt @@ -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 index 00000000..d1913b42 --- /dev/null +++ b/regression_tests/q3map2/duplicate_plane/maps/duplicate_plane.map @@ -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 index 00000000..c3c2f88d --- /dev/null +++ b/regression_tests/q3map2/model_clipping_45_degrees/README.txt @@ -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 index 00000000..f358dba6 --- /dev/null +++ b/regression_tests/q3map2/model_clipping_45_degrees/maps/model_clipping_45_degrees.map @@ -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 index 00000000..dfb0d41d --- /dev/null +++ b/regression_tests/q3map2/model_clipping_45_degrees/models/mapobjects/wedges/wedge_45.ase @@ -0,0 +1,368 @@ +*3DSMAX_ASCIIEXPORT 200 +*COMMENT "Generated by Q3Map2 (ydnar) -convert -format ase" +*SCENE { + *SCENE_FILENAME "wedge_45.bsp" + *SCENE_FIRSTFRAME 0 + *SCENE_LASTFRAME 100 + *SCENE_FRAMESPEED 30 + *SCENE_TICKSPERFRAME 160 + *SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000 + *SCENE_AMBIENT_STATIC 0.0000 0.0000 0.0000 +} +*MATERIAL_LIST { + *MATERIAL_COUNT 2 + *MATERIAL 0 { + *MATERIAL_NAME "textures/radiant_regression_tests/tile_model" + *MATERIAL_CLASS "Standard" + *MATERIAL_DIFFUSE 1.000000 1.000000 0.833333 + *MATERIAL_SHADING Phong + *MAP_DIFFUSE { + *MAP_NAME "textures/radiant_regression_tests/tile_model" + *MAP_CLASS "Bitmap" + *MAP_SUBNO 1 + *MAP_AMOUNT 1.0 + *MAP_TYPE Screen + *BITMAP "..\textures\radiant_regression_tests\tile_model.tga" + *BITMAP_FILTER Pyramidal + } + } + *MATERIAL 1 { + *MATERIAL_NAME "noshader" + *MATERIAL_CLASS "Standard" + *MATERIAL_DIFFUSE 1.000000 1.000000 1.000000 + *MATERIAL_SHADING Phong + *MAP_DIFFUSE { + *MAP_NAME "noshader" + *MAP_CLASS "Bitmap" + *MAP_SUBNO 1 + *MAP_AMOUNT 1.0 + *MAP_TYPE Screen + *BITMAP "..\noshader.tga" + *BITMAP_FILTER Pyramidal + } + } +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf0" + *NODE_TM { + *NODE_NAME "mat0model0surf0" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 128.000000 0.000000 0.000000 + *MESH_VERTEX 1 64.000000 0.000000 64.000000 + *MESH_VERTEX 2 128.000000 128.000000 0.000000 + *MESH_VERTEX 3 64.000000 128.000000 64.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.707107 0.000000 0.707107 + *MESH_FACENORMAL 1 0.707107 0.000000 0.707107 + *MESH_VERTEXNORMAL 0 0.707107 0.000000 0.707107 + *MESH_VERTEXNORMAL 1 0.707107 0.000000 0.707107 + *MESH_VERTEXNORMAL 2 0.707107 0.000000 0.707107 + *MESH_VERTEXNORMAL 3 0.707107 0.000000 0.707107 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 1.000000 -1.000000 1.000000 + *MESH_TVERT 1 -1.000000 -1.000000 1.000000 + *MESH_TVERT 2 1.000000 3.000000 1.000000 + *MESH_TVERT 3 -1.000000 3.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf1" + *NODE_TM { + *NODE_NAME "mat0model0surf1" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 0.000000 128.000000 64.000000 + *MESH_VERTEX 1 0.000000 128.000000 0.000000 + *MESH_VERTEX 2 64.000000 128.000000 64.000000 + *MESH_VERTEX 3 128.000000 128.000000 0.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.707107 0.000000 0.707107 + *MESH_FACENORMAL 1 0.707107 0.000000 0.707107 + *MESH_VERTEXNORMAL 0 0.000000 1.000000 0.000000 + *MESH_VERTEXNORMAL 1 0.000000 1.000000 0.000000 + *MESH_VERTEXNORMAL 2 0.000000 1.000000 0.000000 + *MESH_VERTEXNORMAL 3 0.000000 1.000000 0.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 -2.000000 2.000000 1.000000 + *MESH_TVERT 1 -2.000000 0.000000 1.000000 + *MESH_TVERT 2 0.000000 2.000000 1.000000 + *MESH_TVERT 3 2.000000 0.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf2" + *NODE_TM { + *NODE_NAME "mat0model0surf2" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 64.000000 0.000000 64.000000 + *MESH_VERTEX 1 0.000000 0.000000 64.000000 + *MESH_VERTEX 2 64.000000 128.000000 64.000000 + *MESH_VERTEX 3 0.000000 128.000000 64.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.707107 0.000000 0.707107 + *MESH_FACENORMAL 1 0.707107 0.000000 0.707107 + *MESH_VERTEXNORMAL 0 0.000000 0.000000 1.000000 + *MESH_VERTEXNORMAL 1 0.000000 0.000000 1.000000 + *MESH_VERTEXNORMAL 2 0.000000 0.000000 1.000000 + *MESH_VERTEXNORMAL 3 0.000000 0.000000 1.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 1.000000 -1.000000 1.000000 + *MESH_TVERT 1 -1.000000 -1.000000 1.000000 + *MESH_TVERT 2 1.000000 3.000000 1.000000 + *MESH_TVERT 3 -1.000000 3.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf3" + *NODE_TM { + *NODE_NAME "mat0model0surf3" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 0.000000 0.000000 64.000000 + *MESH_VERTEX 1 0.000000 0.000000 0.000000 + *MESH_VERTEX 2 0.000000 128.000000 64.000000 + *MESH_VERTEX 3 0.000000 128.000000 0.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.707107 0.000000 0.707107 + *MESH_FACENORMAL 1 0.707107 0.000000 0.707107 + *MESH_VERTEXNORMAL 0 -1.000000 0.000000 0.000000 + *MESH_VERTEXNORMAL 1 -1.000000 0.000000 0.000000 + *MESH_VERTEXNORMAL 2 -1.000000 0.000000 0.000000 + *MESH_VERTEXNORMAL 3 -1.000000 0.000000 0.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 -2.000000 2.000000 1.000000 + *MESH_TVERT 1 -2.000000 0.000000 1.000000 + *MESH_TVERT 2 2.000000 2.000000 1.000000 + *MESH_TVERT 3 2.000000 0.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf4" + *NODE_TM { + *NODE_NAME "mat0model0surf4" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 128.000000 0.000000 0.000000 + *MESH_VERTEX 1 0.000000 0.000000 0.000000 + *MESH_VERTEX 2 64.000000 0.000000 64.000000 + *MESH_VERTEX 3 0.000000 0.000000 64.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.707107 0.000000 0.707107 + *MESH_FACENORMAL 1 0.707107 0.000000 0.707107 + *MESH_VERTEXNORMAL 0 0.000000 -1.000000 0.000000 + *MESH_VERTEXNORMAL 1 0.000000 -1.000000 0.000000 + *MESH_VERTEXNORMAL 2 0.000000 -1.000000 0.000000 + *MESH_VERTEXNORMAL 3 0.000000 -1.000000 0.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 2.000000 0.000000 1.000000 + *MESH_TVERT 1 -2.000000 0.000000 1.000000 + *MESH_TVERT 2 0.000000 2.000000 1.000000 + *MESH_TVERT 3 -2.000000 2.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf5" + *NODE_TM { + *NODE_NAME "mat0model0surf5" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 0.000000 128.000000 0.000000 + *MESH_VERTEX 1 0.000000 0.000000 0.000000 + *MESH_VERTEX 2 128.000000 128.000000 0.000000 + *MESH_VERTEX 3 128.000000 0.000000 0.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.707107 0.000000 0.707107 + *MESH_FACENORMAL 1 0.707107 0.000000 0.707107 + *MESH_VERTEXNORMAL 0 0.000000 0.000000 -1.000000 + *MESH_VERTEXNORMAL 1 0.000000 0.000000 -1.000000 + *MESH_VERTEXNORMAL 2 0.000000 0.000000 -1.000000 + *MESH_VERTEXNORMAL 3 0.000000 0.000000 -1.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 -2.000000 3.000000 1.000000 + *MESH_TVERT 1 -2.000000 -1.000000 1.000000 + *MESH_TVERT 2 2.000000 3.000000 1.000000 + *MESH_TVERT 3 2.000000 -1.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} 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 index 00000000..4e23fd49 --- /dev/null +++ b/regression_tests/q3map2/model_clipping_45_degrees/models/mapobjects/wedges/wedge_shallow.ase @@ -0,0 +1,368 @@ +*3DSMAX_ASCIIEXPORT 200 +*COMMENT "Generated by Q3Map2 (ydnar) -convert -format ase" +*SCENE { + *SCENE_FILENAME "wedge_shallow.bsp" + *SCENE_FIRSTFRAME 0 + *SCENE_LASTFRAME 100 + *SCENE_FRAMESPEED 30 + *SCENE_TICKSPERFRAME 160 + *SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000 + *SCENE_AMBIENT_STATIC 0.0000 0.0000 0.0000 +} +*MATERIAL_LIST { + *MATERIAL_COUNT 2 + *MATERIAL 0 { + *MATERIAL_NAME "textures/radiant_regression_tests/tile_model" + *MATERIAL_CLASS "Standard" + *MATERIAL_DIFFUSE 1.000000 1.000000 0.833333 + *MATERIAL_SHADING Phong + *MAP_DIFFUSE { + *MAP_NAME "textures/radiant_regression_tests/tile_model" + *MAP_CLASS "Bitmap" + *MAP_SUBNO 1 + *MAP_AMOUNT 1.0 + *MAP_TYPE Screen + *BITMAP "..\textures\radiant_regression_tests\tile_model.tga" + *BITMAP_FILTER Pyramidal + } + } + *MATERIAL 1 { + *MATERIAL_NAME "noshader" + *MATERIAL_CLASS "Standard" + *MATERIAL_DIFFUSE 1.000000 1.000000 1.000000 + *MATERIAL_SHADING Phong + *MAP_DIFFUSE { + *MAP_NAME "noshader" + *MAP_CLASS "Bitmap" + *MAP_SUBNO 1 + *MAP_AMOUNT 1.0 + *MAP_TYPE Screen + *BITMAP "..\noshader.tga" + *BITMAP_FILTER Pyramidal + } + } +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf0" + *NODE_TM { + *NODE_NAME "mat0model0surf0" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 160.000000 0.000000 0.000000 + *MESH_VERTEX 1 64.000000 0.000000 64.000000 + *MESH_VERTEX 2 160.000000 128.000000 0.000000 + *MESH_VERTEX 3 64.000000 128.000000 64.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.554700 0.000000 0.832050 + *MESH_FACENORMAL 1 0.554700 0.000000 0.832050 + *MESH_VERTEXNORMAL 0 0.554700 0.000000 0.832050 + *MESH_VERTEXNORMAL 1 0.554700 0.000000 0.832050 + *MESH_VERTEXNORMAL 2 0.554700 0.000000 0.832050 + *MESH_VERTEXNORMAL 3 0.554700 0.000000 0.832050 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 2.000000 -1.000000 1.000000 + *MESH_TVERT 1 -1.000000 -1.000000 1.000000 + *MESH_TVERT 2 2.000000 3.000000 1.000000 + *MESH_TVERT 3 -1.000000 3.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf1" + *NODE_TM { + *NODE_NAME "mat0model0surf1" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 0.000000 128.000000 64.000000 + *MESH_VERTEX 1 0.000000 128.000000 0.000000 + *MESH_VERTEX 2 64.000000 128.000000 64.000000 + *MESH_VERTEX 3 160.000000 128.000000 0.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.554700 0.000000 0.832050 + *MESH_FACENORMAL 1 0.554700 0.000000 0.832050 + *MESH_VERTEXNORMAL 0 0.000000 1.000000 0.000000 + *MESH_VERTEXNORMAL 1 0.000000 1.000000 0.000000 + *MESH_VERTEXNORMAL 2 0.000000 1.000000 0.000000 + *MESH_VERTEXNORMAL 3 0.000000 1.000000 0.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 -2.000000 2.000000 1.000000 + *MESH_TVERT 1 -2.000000 0.000000 1.000000 + *MESH_TVERT 2 0.000000 2.000000 1.000000 + *MESH_TVERT 3 3.000000 0.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf2" + *NODE_TM { + *NODE_NAME "mat0model0surf2" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 64.000000 0.000000 64.000000 + *MESH_VERTEX 1 0.000000 0.000000 64.000000 + *MESH_VERTEX 2 64.000000 128.000000 64.000000 + *MESH_VERTEX 3 0.000000 128.000000 64.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.554700 0.000000 0.832050 + *MESH_FACENORMAL 1 0.554700 0.000000 0.832050 + *MESH_VERTEXNORMAL 0 0.000000 0.000000 1.000000 + *MESH_VERTEXNORMAL 1 0.000000 0.000000 1.000000 + *MESH_VERTEXNORMAL 2 0.000000 0.000000 1.000000 + *MESH_VERTEXNORMAL 3 0.000000 0.000000 1.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 1.000000 -1.000000 1.000000 + *MESH_TVERT 1 -1.000000 -1.000000 1.000000 + *MESH_TVERT 2 1.000000 3.000000 1.000000 + *MESH_TVERT 3 -1.000000 3.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf3" + *NODE_TM { + *NODE_NAME "mat0model0surf3" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 0.000000 0.000000 64.000000 + *MESH_VERTEX 1 0.000000 0.000000 0.000000 + *MESH_VERTEX 2 0.000000 128.000000 64.000000 + *MESH_VERTEX 3 0.000000 128.000000 0.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.554700 0.000000 0.832050 + *MESH_FACENORMAL 1 0.554700 0.000000 0.832050 + *MESH_VERTEXNORMAL 0 -1.000000 0.000000 0.000000 + *MESH_VERTEXNORMAL 1 -1.000000 0.000000 0.000000 + *MESH_VERTEXNORMAL 2 -1.000000 0.000000 0.000000 + *MESH_VERTEXNORMAL 3 -1.000000 0.000000 0.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 -2.000000 2.000000 1.000000 + *MESH_TVERT 1 -2.000000 0.000000 1.000000 + *MESH_TVERT 2 2.000000 2.000000 1.000000 + *MESH_TVERT 3 2.000000 0.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf4" + *NODE_TM { + *NODE_NAME "mat0model0surf4" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 160.000000 0.000000 0.000000 + *MESH_VERTEX 1 0.000000 0.000000 0.000000 + *MESH_VERTEX 2 64.000000 0.000000 64.000000 + *MESH_VERTEX 3 0.000000 0.000000 64.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.554700 0.000000 0.832050 + *MESH_FACENORMAL 1 0.554700 0.000000 0.832050 + *MESH_VERTEXNORMAL 0 0.000000 -1.000000 0.000000 + *MESH_VERTEXNORMAL 1 0.000000 -1.000000 0.000000 + *MESH_VERTEXNORMAL 2 0.000000 -1.000000 0.000000 + *MESH_VERTEXNORMAL 3 0.000000 -1.000000 0.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 3.000000 0.000000 1.000000 + *MESH_TVERT 1 -2.000000 0.000000 1.000000 + *MESH_TVERT 2 0.000000 2.000000 1.000000 + *MESH_TVERT 3 -2.000000 2.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf5" + *NODE_TM { + *NODE_NAME "mat0model0surf5" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 0.000000 128.000000 0.000000 + *MESH_VERTEX 1 0.000000 0.000000 0.000000 + *MESH_VERTEX 2 160.000000 128.000000 0.000000 + *MESH_VERTEX 3 160.000000 0.000000 0.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.554700 0.000000 0.832050 + *MESH_FACENORMAL 1 0.554700 0.000000 0.832050 + *MESH_VERTEXNORMAL 0 0.000000 0.000000 -1.000000 + *MESH_VERTEXNORMAL 1 0.000000 0.000000 -1.000000 + *MESH_VERTEXNORMAL 2 0.000000 0.000000 -1.000000 + *MESH_VERTEXNORMAL 3 0.000000 0.000000 -1.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 -2.000000 3.000000 1.000000 + *MESH_TVERT 1 -2.000000 -1.000000 1.000000 + *MESH_TVERT 2 3.000000 3.000000 1.000000 + *MESH_TVERT 3 3.000000 -1.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} 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 index 00000000..0e8727e0 --- /dev/null +++ b/regression_tests/q3map2/model_clipping_45_degrees/models/mapobjects/wedges/wedge_steep.ase @@ -0,0 +1,368 @@ +*3DSMAX_ASCIIEXPORT 200 +*COMMENT "Generated by Q3Map2 (ydnar) -convert -format ase" +*SCENE { + *SCENE_FILENAME "wedge_steep.bsp" + *SCENE_FIRSTFRAME 0 + *SCENE_LASTFRAME 100 + *SCENE_FRAMESPEED 30 + *SCENE_TICKSPERFRAME 160 + *SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000 + *SCENE_AMBIENT_STATIC 0.0000 0.0000 0.0000 +} +*MATERIAL_LIST { + *MATERIAL_COUNT 2 + *MATERIAL 0 { + *MATERIAL_NAME "textures/radiant_regression_tests/tile_model" + *MATERIAL_CLASS "Standard" + *MATERIAL_DIFFUSE 1.000000 1.000000 0.833333 + *MATERIAL_SHADING Phong + *MAP_DIFFUSE { + *MAP_NAME "textures/radiant_regression_tests/tile_model" + *MAP_CLASS "Bitmap" + *MAP_SUBNO 1 + *MAP_AMOUNT 1.0 + *MAP_TYPE Screen + *BITMAP "..\textures\radiant_regression_tests\tile_model.tga" + *BITMAP_FILTER Pyramidal + } + } + *MATERIAL 1 { + *MATERIAL_NAME "noshader" + *MATERIAL_CLASS "Standard" + *MATERIAL_DIFFUSE 1.000000 1.000000 1.000000 + *MATERIAL_SHADING Phong + *MAP_DIFFUSE { + *MAP_NAME "noshader" + *MAP_CLASS "Bitmap" + *MAP_SUBNO 1 + *MAP_AMOUNT 1.0 + *MAP_TYPE Screen + *BITMAP "..\noshader.tga" + *BITMAP_FILTER Pyramidal + } + } +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf0" + *NODE_TM { + *NODE_NAME "mat0model0surf0" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 112.000000 0.000000 0.000000 + *MESH_VERTEX 1 64.000000 0.000000 64.000000 + *MESH_VERTEX 2 112.000000 128.000000 0.000000 + *MESH_VERTEX 3 64.000000 128.000000 64.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.800000 0.000000 0.600000 + *MESH_FACENORMAL 1 0.800000 0.000000 0.600000 + *MESH_VERTEXNORMAL 0 0.800000 0.000000 0.600000 + *MESH_VERTEXNORMAL 1 0.800000 0.000000 0.600000 + *MESH_VERTEXNORMAL 2 0.800000 0.000000 0.600000 + *MESH_VERTEXNORMAL 3 0.800000 0.000000 0.600000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 -2.000000 0.000000 1.000000 + *MESH_TVERT 1 -2.000000 2.000000 1.000000 + *MESH_TVERT 2 2.000000 0.000000 1.000000 + *MESH_TVERT 3 2.000000 2.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf1" + *NODE_TM { + *NODE_NAME "mat0model0surf1" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 0.000000 128.000000 64.000000 + *MESH_VERTEX 1 0.000000 128.000000 0.000000 + *MESH_VERTEX 2 64.000000 128.000000 64.000000 + *MESH_VERTEX 3 112.000000 128.000000 0.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.800000 0.000000 0.600000 + *MESH_FACENORMAL 1 0.800000 0.000000 0.600000 + *MESH_VERTEXNORMAL 0 0.000000 1.000000 0.000000 + *MESH_VERTEXNORMAL 1 0.000000 1.000000 0.000000 + *MESH_VERTEXNORMAL 2 0.000000 1.000000 0.000000 + *MESH_VERTEXNORMAL 3 0.000000 1.000000 0.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 -1.000000 2.000000 1.000000 + *MESH_TVERT 1 -1.000000 0.000000 1.000000 + *MESH_TVERT 2 1.000000 2.000000 1.000000 + *MESH_TVERT 3 2.500000 0.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf2" + *NODE_TM { + *NODE_NAME "mat0model0surf2" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 64.000000 0.000000 64.000000 + *MESH_VERTEX 1 0.000000 0.000000 64.000000 + *MESH_VERTEX 2 64.000000 128.000000 64.000000 + *MESH_VERTEX 3 0.000000 128.000000 64.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.800000 0.000000 0.600000 + *MESH_FACENORMAL 1 0.800000 0.000000 0.600000 + *MESH_VERTEXNORMAL 0 0.000000 0.000000 1.000000 + *MESH_VERTEXNORMAL 1 0.000000 0.000000 1.000000 + *MESH_VERTEXNORMAL 2 0.000000 0.000000 1.000000 + *MESH_VERTEXNORMAL 3 0.000000 0.000000 1.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 1.000000 -1.000000 1.000000 + *MESH_TVERT 1 -1.000000 -1.000000 1.000000 + *MESH_TVERT 2 1.000000 3.000000 1.000000 + *MESH_TVERT 3 -1.000000 3.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf3" + *NODE_TM { + *NODE_NAME "mat0model0surf3" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 0.000000 0.000000 64.000000 + *MESH_VERTEX 1 0.000000 0.000000 0.000000 + *MESH_VERTEX 2 0.000000 128.000000 64.000000 + *MESH_VERTEX 3 0.000000 128.000000 0.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.800000 0.000000 0.600000 + *MESH_FACENORMAL 1 0.800000 0.000000 0.600000 + *MESH_VERTEXNORMAL 0 -1.000000 0.000000 0.000000 + *MESH_VERTEXNORMAL 1 -1.000000 0.000000 0.000000 + *MESH_VERTEXNORMAL 2 -1.000000 0.000000 0.000000 + *MESH_VERTEXNORMAL 3 -1.000000 0.000000 0.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 -2.000000 2.000000 1.000000 + *MESH_TVERT 1 -2.000000 0.000000 1.000000 + *MESH_TVERT 2 2.000000 2.000000 1.000000 + *MESH_TVERT 3 2.000000 0.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf4" + *NODE_TM { + *NODE_NAME "mat0model0surf4" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 112.000000 0.000000 0.000000 + *MESH_VERTEX 1 0.000000 0.000000 0.000000 + *MESH_VERTEX 2 64.000000 0.000000 64.000000 + *MESH_VERTEX 3 0.000000 0.000000 64.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.800000 0.000000 0.600000 + *MESH_FACENORMAL 1 0.800000 0.000000 0.600000 + *MESH_VERTEXNORMAL 0 0.000000 -1.000000 0.000000 + *MESH_VERTEXNORMAL 1 0.000000 -1.000000 0.000000 + *MESH_VERTEXNORMAL 2 0.000000 -1.000000 0.000000 + *MESH_VERTEXNORMAL 3 0.000000 -1.000000 0.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 2.500000 0.000000 1.000000 + *MESH_TVERT 1 -1.000000 0.000000 1.000000 + *MESH_TVERT 2 1.000000 2.000000 1.000000 + *MESH_TVERT 3 -1.000000 2.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} +*GEOMOBJECT { + *NODE_NAME "mat0model0surf5" + *NODE_TM { + *NODE_NAME "mat0model0surf5" + *INHERIT_POS 0 0 0 + *INHERIT_ROT 0 0 0 + *INHERIT_SCL 0 0 0 + *TM_ROW0 1.0 0 0 + *TM_ROW1 0 1.0 0 + *TM_ROW2 0 0 1.0 + *TM_ROW3 0 0 0 + *TM_POS 0.000000 0.000000 0.000000 + } + *MESH { + *TIMEVALUE 0 + *MESH_NUMVERTEX 4 + *MESH_NUMFACES 2 + *COMMENT "SURFACETYPE MST_PLANAR" + *MESH_VERTEX_LIST { + *MESH_VERTEX 0 0.000000 128.000000 0.000000 + *MESH_VERTEX 1 0.000000 0.000000 0.000000 + *MESH_VERTEX 2 112.000000 128.000000 0.000000 + *MESH_VERTEX 3 112.000000 0.000000 0.000000 + } + *MESH_NORMALS { + *MESH_FACENORMAL 0 0.800000 0.000000 0.600000 + *MESH_FACENORMAL 1 0.800000 0.000000 0.600000 + *MESH_VERTEXNORMAL 0 0.000000 0.000000 -1.000000 + *MESH_VERTEXNORMAL 1 0.000000 0.000000 -1.000000 + *MESH_VERTEXNORMAL 2 0.000000 0.000000 -1.000000 + *MESH_VERTEXNORMAL 3 0.000000 0.000000 -1.000000 + } + *MESH_FACE_LIST { + *MESH_FACE 0 A: 0 B: 2 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + *MESH_FACE 1 A: 2 B: 3 C: 1 AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING 0 *MESH_MTLID 0 + } + *MESH_NUMTVERTEX 4 + *MESH_TVERTLIST { + *MESH_TVERT 0 -1.000000 3.000000 1.000000 + *MESH_TVERT 1 -1.000000 -1.000000 1.000000 + *MESH_TVERT 2 2.500000 3.000000 1.000000 + *MESH_TVERT 3 2.500000 -1.000000 1.000000 + } + *MESH_NUMTVFACES 2 + *MESH_TFACELIST { + *MESH_TFACE 0 0 2 1 + *MESH_TFACE 1 2 3 1 + } + } + *PROP_MOTIONBLUR 0 + *PROP_CASTSHADOW 1 + *PROP_RECVSHADOW 1 + *MATERIAL_REF 0 +} 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 index 00000000..a2c31ed6 --- /dev/null +++ b/regression_tests/q3map2/model_clipping_45_degrees/scripts/radiant_regression_tests.shader @@ -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 index 00000000..b09e2c31 --- /dev/null +++ b/regression_tests/q3map2/piercing_triangle/README.txt @@ -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 index 00000000..8dc3552f --- /dev/null +++ b/regression_tests/q3map2/piercing_triangle/maps/piercing_triangle.map @@ -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 index 00000000..c76d574f --- /dev/null +++ b/regression_tests/q3map2/plane_aliasing/README.txt @@ -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 index 00000000..070d7ba9 --- /dev/null +++ b/regression_tests/q3map2/plane_aliasing/maps/plane_aliasing.map @@ -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 index 00000000..05f30d2f --- /dev/null +++ b/regression_tests/q3map2/segmentation_fault/README.txt @@ -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 index 00000000..610e7850 --- /dev/null +++ b/regression_tests/q3map2/segmentation_fault/maps/segmentation_fault.map @@ -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 index 00000000..d66196be --- /dev/null +++ b/regression_tests/q3map2/snap_plane/README.txt @@ -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 index 00000000..c2b490c5 --- /dev/null +++ b/regression_tests/q3map2/snap_plane/maps/snap_plane.map @@ -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 index 00000000..3c54feb5 --- /dev/null +++ b/regression_tests/q3map2/sparkly_seam/README.txt @@ -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 index 00000000..4b021372 --- /dev/null +++ b/regression_tests/q3map2/sparkly_seam/maps/sparkly_seam.map @@ -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" +} diff --git a/tools/quake3/common/polylib.c b/tools/quake3/common/polylib.c index fc8805e7..34dd173e 100644 --- a/tools/quake3/common/polylib.c +++ b/tools/quake3/common/polylib.c @@ -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 diff --git a/tools/quake3/common/polylib.h b/tools/quake3/common/polylib.h index d78c780d..1f4495d9 100644 --- a/tools/quake3/common/polylib.h +++ b/tools/quake3/common/polylib.h @@ -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); diff --git a/tools/quake3/q3map2/brush.c b/tools/quake3/q3map2/brush.c index 2517ca63..b7c50f4c 100644 --- a/tools/quake3/q3map2/brush.c +++ b/tools/quake3/q3map2/brush.c @@ -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 ; inumsides ; 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]); diff --git a/tools/quake3/q3map2/convert_ase.c b/tools/quake3/q3map2/convert_ase.c index 59cc3d9c..56262311 100644 --- a/tools/quake3/q3map2/convert_ase.c +++ b/tools/quake3/q3map2/convert_ase.c @@ -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 index 00000000..08e75e11 --- /dev/null +++ b/tools/quake3/q3map2/convert_obj.c @@ -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; +} + + + diff --git a/tools/quake3/q3map2/game_etut.h b/tools/quake3/q3map2/game_etut.h index 87d32b55..8add5bbe 100644 --- a/tools/quake3/q3map2/game_etut.h +++ b/tools/quake3/q3map2/game_etut.h @@ -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 index 00000000..c81e7245 --- /dev/null +++ b/tools/quake3/q3map2/game_reaction.h @@ -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 diff --git a/tools/quake3/q3map2/light.c b/tools/quake3/q3map2/light.c index a703faac..9323b8c8 100644 --- a/tools/quake3/q3map2/light.c +++ b/tools/quake3/q3map2/light.c @@ -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++; } diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 2deb1429..074a4a43 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -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 [-v] \n" ); + Sys_Printf( "Usage: q3map -convert -format [-shadesasbitmap|-lightmapsastexcoord|-deluxemapsastexcoord] [-readbsp|-readmap [-meta|-patchmeta]] \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"); diff --git a/tools/quake3/q3map2/map.c b/tools/quake3/q3map2/map.c index d61f51be..95bb3d1f 100644 --- a/tools/quake3/q3map2/map.c +++ b/tools/quake3/q3map2/map.c @@ -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 } diff --git a/tools/quake3/q3map2/model.c b/tools/quake3/q3map2/model.c index 05213cf1..a56134c8 100644 --- a/tools/quake3/q3map2/model.c +++ b/tools/quake3/q3map2/model.c @@ -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 diff --git a/tools/quake3/q3map2/path_init.c b/tools/quake3/q3map2/path_init.c index e6b4d959..83383e22 100644 --- a/tools/quake3/q3map2/path_init.c +++ b/tools/quake3/q3map2/path_init.c @@ -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; + } + } + } diff --git a/tools/quake3/q3map2/portals.c b/tools/quake3/q3map2/portals.c index cc3e0d9d..2efc1db4 100644 --- a/tools/quake3/q3map2/portals.c +++ b/tools/quake3/q3map2/portals.c @@ -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; diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index baa29c7c..e912d15b 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -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;