r3798 - in branches/nexuiz-2.0: . data/qcsrc/server misc/gtkradiant misc/gtkradiant/singlepatches

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Wed Jul 9 10:20:31 EDT 2008


Author: div0
Date: 2008-07-09 10:20:30 -0400 (Wed, 09 Jul 2008)
New Revision: 3798

Added:
   branches/nexuiz-2.0/misc/gtkradiant/singlepatches/gtkradiant-bp2texdeffix.diff
   branches/nexuiz-2.0/misc/gtkradiant/singlepatches/gtkradiant-bpsurfacedialog.diff
Modified:
   branches/nexuiz-2.0/.patchsets
   branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
   branches/nexuiz-2.0/misc/gtkradiant/gtkradiant-nexuiz-patchset.diff
Log:
r3796 | div0 | 2008-07-09 08:02:58 +0200 (Wed, 09 Jul 2008) | 2 lines
fix ctf bug with flag touching after dead
r3797 | div0 | 2008-07-09 14:25:30 +0200 (Wed, 09 Jul 2008) | 2 lines
add brush primitives fixes

Modified: branches/nexuiz-2.0/.patchsets
===================================================================
--- branches/nexuiz-2.0/.patchsets	2008-07-09 12:25:30 UTC (rev 3797)
+++ branches/nexuiz-2.0/.patchsets	2008-07-09 14:20:30 UTC (rev 3798)
@@ -1,2 +1,2 @@
 master = svn://svn.icculus.org/nexuiz/trunk
-revisions_applied = 1-3760,3762-3773,3787-3788,3790-3790
+revisions_applied = 1-3760,3762-3773,3787-3788,3790-3790,3796-3797

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2008-07-09 12:25:30 UTC (rev 3797)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2008-07-09 14:20:30 UTC (rev 3798)
@@ -488,7 +488,7 @@
 		// Instead, prepare the victim for his death...
 		targ.armorvalue = 0;
 		targ.spawnshieldtime = 0;
-		targ.health = 1;
+		targ.health = 0.9; // this is < 1
 		targ.flags -= targ.flags & FL_GODMODE;
 		damage = 100000;
 	}

Modified: branches/nexuiz-2.0/misc/gtkradiant/gtkradiant-nexuiz-patchset.diff
===================================================================
--- branches/nexuiz-2.0/misc/gtkradiant/gtkradiant-nexuiz-patchset.diff	2008-07-09 12:25:30 UTC (rev 3797)
+++ branches/nexuiz-2.0/misc/gtkradiant/gtkradiant-nexuiz-patchset.diff	2008-07-09 14:20:30 UTC (rev 3798)
@@ -111,6 +111,654 @@
  		/* skip unparsed rest of line and continue */
  		_pico_parse_skip_rest( p );
  	}
+Index: radiant/brush_primit.cpp
+===================================================================
+--- radiant/brush_primit.cpp	(revision 297)
++++ radiant/brush_primit.cpp	(working copy)
+@@ -388,8 +388,9 @@
+ //	ConvertTexMatWithQTexture( &f->brushprimit_texdef, NULL, &f->brushprimit_texdef, f->d_texture );
+ }
+ 
+-void BrushPrimitFaceToFace(face_t *face)
++void BrushPrimitFaceToFace(face_t *f)
+ {
++  /*
+   // we have parsed brush primitives and need conversion back to standard format
+   // NOTE: converting back is a quick hack, there's some information lost and we can't do anything about it
+   // FIXME: if we normalize the texture matrix to a standard 2x2 size, we end up with wrong scaling
+@@ -399,6 +400,28 @@
+   TexMatToFakeTexCoords( aux.coords, face->texdef.shift, &face->texdef.rotate, face->texdef.scale );
+   face->texdef.scale[0]/=2.0;
+   face->texdef.scale[1]/=2.0;
++  */
++    vec3_t texX,texY;
++    vec3_t proj;
++    vec_t ST[3][5];
++
++    ComputeAxisBase(f->plane.normal,texX,texY);
++    VectorCopy(f->plane.normal,proj);
++    VectorScale(proj,f->plane.dist,proj);
++    VectorCopy(proj,ST[0]);
++    VectorCopy(texX,ST[1]);
++    VectorAdd(ST[1],proj,ST[1]);
++    VectorCopy(texY,ST[2]);
++    VectorAdd(ST[2],proj,ST[2]);
++
++	ST[0][3] = f->brushprimit_texdef.coords[0][2];
++	ST[0][4] = f->brushprimit_texdef.coords[1][2];
++	ST[1][3] = f->brushprimit_texdef.coords[0][0] + ST[0][3];
++	ST[1][4] = f->brushprimit_texdef.coords[1][0] + ST[0][4];
++	ST[2][3] = f->brushprimit_texdef.coords[0][1] + ST[0][3];
++	ST[2][4] = f->brushprimit_texdef.coords[1][1] + ST[0][4];
++
++	Face_TexdefFromTextureCoordinates(ST[0], ST[1], ST[2], f->d_texture, f);
+ }
+ 
+ // TEXTURE LOCKING -----------------------------------------------------------------------------------------------------
+Index: radiant/brush.cpp
+===================================================================
+--- radiant/brush.cpp	(revision 297)
++++ radiant/brush.cpp	(working copy)
+@@ -423,7 +423,93 @@
+ 	}
+ }
+ 
++long double HighestImpactSign(long double a, long double b)
++{
++	// returns the sign of the value with larger abs
++	if(a+b > 0)
++		return +1;
++	else
++		return -1;
++}
++
++void Face_TexdefFromTextureVectors (face_t *f, long double STfromXYZ[2][4], vec3_t pvecs[2], int sv, int tv)
++{
++	texdef_t *td;
++	qtexture_t *q;
++	int j;
++	long double ang;
++
++    td = &f->texdef;
++    q = f->d_texture;
++
++	// undo the texture transform
++    for (j=0 ; j<4 ; j++) {
++        STfromXYZ[0][j] *= q->width;
++        STfromXYZ[1][j] *= q->height;
++    }
++
++    // shift
++    td->shift[0] = STfromXYZ[0][3];
++    td->shift[1] = STfromXYZ[1][3];
++
+ /*
++	SOLVE:
++		STfromXYZ[0][sv] = (cosv * pvecs[0][sv] - sinv * pvecs[0][tv]) / td->scale[0];
++		STfromXYZ[0][tv] = (sinv * pvecs[0][sv] + cosv * pvecs[0][tv]) / td->scale[0];
++		STfromXYZ[1][sv] = (cosv * pvecs[1][sv] - sinv * pvecs[1][tv]) / td->scale[1];
++		STfromXYZ[1][tv] = (sinv * pvecs[1][sv] + cosv * pvecs[1][tv]) / td->scale[1];
++	FOR:
++		sinv, cosv, td->scale[0], td->scale[1]
++	WE KNOW:
++		sinv^2 + cosv^2 = 1
++		pvecs[0][sv] is +/-1
++		pvecs[0][tv] is 0
++		pvecs[1][sv] is 0
++		pvecs[1][tv] is +/-1
++	THUS:
++		STfromXYZ[0][sv] = +cosv * pvecs[0][sv] / td->scale[0];
++		STfromXYZ[0][tv] = +sinv * pvecs[0][sv] / td->scale[0];
++		STfromXYZ[1][sv] = -sinv * pvecs[1][tv] / td->scale[1];
++		STfromXYZ[1][tv] = +cosv * pvecs[1][tv] / td->scale[1];
++*/
++
++	td->scale[0] = sqrt(STfromXYZ[0][sv]*STfromXYZ[0][sv] + STfromXYZ[0][tv]*STfromXYZ[0][tv]);
++	td->scale[1] = sqrt(STfromXYZ[1][sv]*STfromXYZ[1][sv] + STfromXYZ[1][tv]*STfromXYZ[1][tv]);
++
++	if(td->scale[0]) td->scale[0] = 1 / td->scale[0]; // avoid NaNs
++	if(td->scale[1]) td->scale[1] = 1 / td->scale[1];
++
++	long double sign0tv = (STfromXYZ[0][tv] > 0) ? +1 : -1;
++	ang = atan2( sign0tv * STfromXYZ[0][tv], sign0tv * STfromXYZ[0][sv]); // atan2(y, x) with y positive is in [0, PI[
++
++	// STOP
++	// We have until now ignored the fact that td->scale[0] or td->scale[1] may
++	// have either sign (+ or -). Due to roundoff errors, our choice of
++	// sign0tv may even have been wrong in a sense. 
++	// sign0tv may NOT indicate the appropriate sign for td->scale[0] (namely,
++	// if cosv is near zero)!
++	// let's look at the signs again
++	//   sign0sv =  signcosv * pvecs[0][sv] / td->scale[0]sign
++	//   sign0tv =             pvecs[0][sv] / td->scale[0]sign
++	//   sign1sv = -1        * pvecs[1][tv] / td->scale[1]sign
++	//   sign1tv =  signcosv * pvecs[1][tv] / td->scale[1]sign
++	// -->
++	//   td->scale[1]sign =  sign1tv * signcosv * pvecs[1][tv]
++	//   td->scale[1]sign = -sign1sv * signsinv * pvecs[1][tv]
++	//   td->scale[0]sign =  sign0tv * signsinv * pvecs[0][sv]
++	//   td->scale[0]sign =  sign0sv * signcosv * pvecs[0][sv]
++	// which to choose?
++	// the one with the larger impact on the original texcoords, of course
++	// to minimize the effect of roundoff errors that may flip the signs!
++	
++	td->scale[0] *= HighestImpactSign(STfromXYZ[0][tv] * +sin(ang), STfromXYZ[0][sv] * cos(ang)) * pvecs[0][sv];
++	td->scale[1] *= HighestImpactSign(STfromXYZ[1][sv] * -sin(ang), STfromXYZ[1][tv] * cos(ang)) * pvecs[1][tv];
++
++	td->rotate = ang * 180 / Q_PI; // FIXME possibly snap this to 0/90/180 (270 can't happen)?
++}
++
++
++/*
+ ================
+ Face_MakePlane
+ ================
+@@ -462,6 +548,135 @@
+ 	xyzst[4] = DotProduct (xyzst, STfromXYZ[1]) + STfromXYZ[1][3];
+ }
+ 
++long double SarrusDetScalar(long double a1, long double b1, long double c1, long double a2, long double b2, long double c2, long double a3, long double b3, long double c3)
++{
++	return a1 * b2 * c3 + a2 * b3 * c1 + a3 * b1 * c2
++	     - a1 * c2 * b3 - a2 * c3 * b1 - a3 * c1 * b2;
++}
++
++void SarrusSolve(long double a1, long double b1, long double c1, long double d1, long double a2, long double b2, long double c2, long double d2, long double a3, long double b3, long double c3, long double d3, long double *a, long double *b, long double *c)
++{
++	long double det;
++	det = SarrusDetScalar(a1, b1, c1,
++	                      a2, b2, c2,
++						  a3, b3, c3);
++	*a =  SarrusDetScalar(d1, b1, c1,
++	                      d2, b2, c2,
++						  d3, b3, c3) / det;
++	*b =  SarrusDetScalar(a1, d1, c1,
++	                      a2, d2, c2,
++						  a3, d3, c3) / det;
++	*c =  SarrusDetScalar(a1, b1, d1,
++	                      a2, b2, d2,
++						  a3, b3, d3) / det;
++}
++
++void Face_TexdefFromTextureCoordinates ( float *xyzst1, float *xyzst2, float *xyzst3, qtexture_t *q, face_t *f)
++{
++	vec3_t		pvecs[2];
++	int sv, tv, uv;
++
++    long double   STfromXYZ[2][4];
++
++    // get natural texture axis
++    TextureAxisFromPlane(&f->plane, pvecs[0], pvecs[1]);
++
++    if (pvecs[0][0])
++        sv = 0;
++    else if (pvecs[0][1])
++        sv = 1;
++    else
++        sv = 2;
++
++    if (pvecs[1][0])
++        tv = 0;
++    else if (pvecs[1][1])
++        tv = 1;
++    else
++        tv = 2;
++
++	uv = 3 - sv - tv; // the "other one"
++
++    // find the STfromXYZ 4-vectors
++	/*
++	SARRUS-SOLVE:
++		xyzst1[3] == xyzst1[sv] * STfromXYZ[0][sv] + xyzst1[tv] * STfromXYZ[0][tv] + STfromXYZ[0][3];
++		xyzst2[3] == xyzst2[sv] * STfromXYZ[0][sv] + xyzst2[tv] * STfromXYZ[0][tv] + STfromXYZ[0][3];
++		xyzst3[3] == xyzst3[sv] * STfromXYZ[0][sv] + xyzst3[tv] * STfromXYZ[0][tv] + STfromXYZ[0][3];
++	FOR: STfromXYZ[0]
++	GIVEN: one coord of them (uv) is empty (see Face_TextureVectors)
++	SARRUS-SOLVE:
++		xyzst1[4] == xyzst1[sv] * STfromXYZ[1][sv] + xyzst1[tv] * STfromXYZ[1][tv] + STfromXYZ[1][3];
++		xyzst2[4] == xyzst2[sv] * STfromXYZ[1][sv] + xyzst2[tv] * STfromXYZ[1][tv] + STfromXYZ[1][3];
++		xyzst3[4] == xyzst3[sv] * STfromXYZ[1][sv] + xyzst3[tv] * STfromXYZ[1][tv] + STfromXYZ[1][3];
++	FOR: STfromXYZ[1]
++	GIVEN: one coord of them (uv) is empty (see Face_TextureVectors)
++	*/
++
++	STfromXYZ[0][uv] = 0;
++	SarrusSolve(
++		xyzst1[sv],        xyzst1[tv],        1,               xyzst1[3],
++		xyzst2[sv],        xyzst2[tv],        1,               xyzst2[3],
++		xyzst3[sv],        xyzst3[tv],        1,               xyzst3[3],
++		&STfromXYZ[0][sv], &STfromXYZ[0][tv], &STfromXYZ[0][3]
++	);
++
++	STfromXYZ[1][uv] = 0;
++	SarrusSolve(
++		xyzst1[sv],        xyzst1[tv],        1,               xyzst1[4],
++		xyzst2[sv],        xyzst2[tv],        1,               xyzst2[4],
++		xyzst3[sv],        xyzst3[tv],        1,               xyzst3[4],
++		&STfromXYZ[1][sv], &STfromXYZ[1][tv], &STfromXYZ[1][3]
++	);
++
++	/*
++	printf("%s\n", q->name);
++
++	printf("%f == %Lf\n", xyzst1[3], DotProduct (xyzst1, STfromXYZ[0]) + STfromXYZ[0][3]);
++	printf("%f == %Lf\n", xyzst2[3], DotProduct (xyzst2, STfromXYZ[0]) + STfromXYZ[0][3]);
++	printf("%f == %Lf\n", xyzst3[3], DotProduct (xyzst3, STfromXYZ[0]) + STfromXYZ[0][3]);
++	printf("%f == %Lf\n", xyzst1[4], DotProduct (xyzst1, STfromXYZ[1]) + STfromXYZ[1][3]);
++	printf("%f == %Lf\n", xyzst2[4], DotProduct (xyzst2, STfromXYZ[1]) + STfromXYZ[1][3]);
++	printf("%f == %Lf\n", xyzst3[4], DotProduct (xyzst3, STfromXYZ[1]) + STfromXYZ[1][3]);
++
++    float   newSTfromXYZ[2][4];
++
++	printf("old: %Lf,%Lf,%Lf,%Lf %Lf,%Lf,%Lf,%Lf\n",
++		STfromXYZ[0][0], STfromXYZ[0][1], STfromXYZ[0][2], STfromXYZ[0][3],
++		STfromXYZ[1][0], STfromXYZ[1][1], STfromXYZ[1][2], STfromXYZ[1][3]);
++	*/
++
++	Face_TexdefFromTextureVectors (f,  STfromXYZ, pvecs, sv, tv);
++
++	/*
++	Face_TextureVectors(f, newSTfromXYZ);
++
++	printf("new: %f,%f,%f,%f %f,%f,%f,%f\n",
++		newSTfromXYZ[0][0], newSTfromXYZ[0][1], newSTfromXYZ[0][2], newSTfromXYZ[0][3],
++		newSTfromXYZ[1][0], newSTfromXYZ[1][1], newSTfromXYZ[1][2], newSTfromXYZ[1][3]);
++
++	float newxyzst1[5];
++	float newxyzst2[5];
++	float newxyzst3[5];
++	VectorCopy(xyzst1, newxyzst1);
++	VectorCopy(xyzst2, newxyzst2);
++	VectorCopy(xyzst3, newxyzst3);
++	EmitTextureCoordinates (newxyzst1, q, f);
++	EmitTextureCoordinates (newxyzst2, q, f);
++	EmitTextureCoordinates (newxyzst3, q, f);
++	printf("Face_TexdefFromTextureCoordinates: %f,%f %f,%f %f,%f -> %f,%f %f,%f %f,%f\n",
++		xyzst1[3], xyzst1[4],
++		xyzst2[3], xyzst2[4],
++		xyzst3[3], xyzst3[4],
++		newxyzst1[3], newxyzst1[4],
++		newxyzst2[3], newxyzst2[4],
++		newxyzst3[3], newxyzst3[4]);
++	// TODO why do these differ, but not the previous ones? this makes no sense whatsoever
++	*/
++}
++
++
++
+ //==========================================================================
+ 
+ /*
+Index: radiant/qe3.h
+===================================================================
+--- radiant/qe3.h	(revision 297)
++++ radiant/qe3.h	(working copy)
+@@ -535,6 +535,7 @@
+ void EmitBrushPrimitTextureCoordinates(face_t *, winding_t *);
+ // EmitTextureCoordinates, is old code used for brush to brush primitive conversion
+ void EmitTextureCoordinates ( float *xyzst, qtexture_t *q, face_t *f);
++void Face_TexdefFromTextureCoordinates ( float *xyzst1, float *xyzst2, float *xyzst3, qtexture_t *q, face_t *f);
+ //void BrushPrimit_Parse(brush_t *);
+ // compute a fake shift scale rot representation from the texture matrix
+ void TexMatToFakeTexCoords( vec_t texMat[2][3], float shift[2], float *rot, float scale[2] );
+Index: config.py
+===================================================================
+--- config.py	(revision 297)
++++ config.py	(working copy)
+@@ -236,7 +236,7 @@
+ 		if ( useZ ):
+ 			env.Append( LIBS = 'z' )
+ 
+-		env.Append( CFLAGS = baseflags )
++		env.Append( CCFLAGS = baseflags )
+ 		env.Append( CXXFLAGS = baseflags + [ '-fpermissive', '-fvisibility-inlines-hidden' ] )
+ 		env.Append( CPPPATH = [ 'include', 'libs' ] )
+ 		env.Append( CPPDEFINES = [ 'Q_NO_STLPORT' ] )
+Index: plugins/surface/surfacedialog.cpp
+===================================================================
+--- plugins/surface/surfacedialog.cpp	(revision 297)
++++ plugins/surface/surfacedialog.cpp	(working copy)
+@@ -1027,7 +1027,7 @@
+   gtk_widget_set_sensitive( GTK_WIDGET( vscale_value_spinbutton ), FALSE );
+ 
+   rotate_value_spinbutton_adj = gtk_adjustment_new (0.0, -360.0, 360.0, 1.0, 10.0, 10.0);
+-  rotate_value_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_value_spinbutton_adj), 1, 0);
++  rotate_value_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_value_spinbutton_adj), 1, 4);
+   gtk_widget_show (rotate_value_spinbutton);
+   gtk_table_attach (GTK_TABLE (table1), rotate_value_spinbutton, 1, 2, 10, 11,
+                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+@@ -1078,7 +1078,7 @@
+   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (vscale_offset_spinbutton), TRUE);
+ 
+   rotate_offset_spinbutton_adj = gtk_adjustment_new (0.0, -360.0, 360.0, 1.0, 10.0, 10.0);
+-  rotate_offset_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_offset_spinbutton_adj), 0, 2);
++  rotate_offset_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_offset_spinbutton_adj), 0, 4);
+   gtk_widget_show (rotate_offset_spinbutton);
+   gtk_table_attach (GTK_TABLE (table1), rotate_offset_spinbutton, 2, 3, 10, 11,
+                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+@@ -1121,7 +1121,7 @@
+   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (vscale_step_spinbutton), GTK_UPDATE_IF_VALID);
+ 
+   rotate_step_spinbutton_adj = gtk_adjustment_new (0.0, -360.0, 360.0, 1.0, 10.0, 10.0);
+-  rotate_step_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_step_spinbutton_adj), 1, 2);
++  rotate_step_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_step_spinbutton_adj), 1, 4);
+   gtk_widget_show (rotate_step_spinbutton);
+   gtk_table_attach (GTK_TABLE (table1), rotate_step_spinbutton, 3, 4, 10, 11,
+                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+Index: radiant/preferences.h
+===================================================================
+--- radiant/preferences.h	(revision 297)
++++ radiant/preferences.h	(working copy)
+@@ -579,6 +579,7 @@
+   bool  m_bPluginToolbar;
+   bool  m_bNoClamp;
+ 	//++timo this is most likely broken, I don't know what it's supposed to do
++  bool  m_bSnap;
+   Str   m_strUserPath;
+   int   m_nRotation;
+   bool  m_bChaseMouse;
+Index: radiant/mainframe.cpp
+===================================================================
+--- radiant/mainframe.cpp	(revision 297)
++++ radiant/mainframe.cpp	(working copy)
+@@ -3824,7 +3824,7 @@
+   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_opengllighting"));
+   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_PrefsDlg.m_bGLLighting) ? TRUE : FALSE);
+   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_snaptogrid"));
+-  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (!g_PrefsDlg.m_bNoClamp) ? TRUE : FALSE);
++  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_PrefsDlg.m_bSnap) ? TRUE : FALSE);
+ 
+   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_view_cubicclipping"));
+   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_PrefsDlg.m_bCubicClipping) ? TRUE : FALSE);
+@@ -4658,7 +4658,7 @@
+     GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_snaptogrid"));
+     g_bIgnoreCommands++;
+     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
+-                                    (!g_PrefsDlg.m_bNoClamp) ? TRUE : FALSE);
++                                    (g_PrefsDlg.m_bSnap) ? TRUE : FALSE);
+     g_bIgnoreCommands--;
+   }
+ }
+@@ -5686,12 +5686,12 @@
+ 
+ void MainFrame::OnSnaptogrid()
+ {
+-  g_PrefsDlg.m_bNoClamp ^= 1;
++  g_PrefsDlg.m_bSnap ^= 1;
+   g_PrefsDlg.SavePrefs ();
+ 
+   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_snaptogrid"));
+   g_bIgnoreCommands++;
+-  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bNoClamp ? FALSE : TRUE);
++  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bSnap ? TRUE : FALSE);
+   g_bIgnoreCommands--;
+ }
+ 
+Index: radiant/preferences.cpp
+===================================================================
+--- radiant/preferences.cpp	(revision 297)
++++ radiant/preferences.cpp	(working copy)
+@@ -96,6 +96,7 @@
+ #define WIDETOOLBAR_KEY         "WideToolBar"
+ #define PLUGINTOOLBAR_KEY "PluginToolBar"
+ #define NOCLAMP_KEY             "NoClamp"
++#define SNAP_KEY                "Snap"
+ #define PREFAB_KEY              "PrefabPath"
+ #define USERINI_KEY             "UserINIPath"
+ #define ROTATION_KEY            "Rotation"
+@@ -635,6 +636,7 @@
+   m_bWideToolbar = TRUE;
+   m_bPluginToolbar = TRUE;
+   m_bNoClamp = FALSE;
++  m_bSnap = TRUE;
+   m_strUserPath = "";
+   m_nRotation = 0;
+   m_bChaseMouse = FALSE;
+@@ -2342,6 +2344,12 @@
+   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
+   AddDialogData (check, &m_bNoClamp, DLG_CHECK_BOOL);
+ 
++  // Snap to grid
++  check = gtk_check_button_new_with_label (_("Snap to grid"));
++  gtk_widget_show (check);
++  gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
++  AddDialogData (check, &m_bSnap, DLG_CHECK_BOOL);
++
+   // Select patch by bounding box
+   check = gtk_check_button_new_with_label (_("Select patches by bounding box"));
+   gtk_widget_show (check);
+@@ -2912,6 +2920,7 @@
+   m_nShader = m_nLatchedShader;
+ 
+   mLocalPrefs.GetPref(NOCLAMP_KEY,            &m_bNoClamp,                    FALSE);
++  mLocalPrefs.GetPref(SNAP_KEY,               &m_bSnap,                       TRUE);
+   mLocalPrefs.GetPref(USERINI_KEY,            &m_strUserPath,                 "");
+   mLocalPrefs.GetPref(ROTATION_KEY,           &m_nRotation,                   45);
+   mLocalPrefs.GetPref(CHASEMOUSE_KEY,         &m_bChaseMouse,                 TRUE);
+Index: radiant/surfaceplugin.cpp
+===================================================================
+--- radiant/surfaceplugin.cpp	(revision 297)
++++ radiant/surfaceplugin.cpp	(working copy)
+@@ -73,6 +73,7 @@
+   face_t	*f;
+   brush_t	*b;
+   texdef_to_face_t *position, *prev_pos;
++  brushprimit_texdef_t bp;
+ 
+   if(selected_brushes.next != &selected_brushes)
+   {
+@@ -85,8 +86,14 @@
+         {
+             position->face = f;
+             position->brush = b;
+-            position->texdef = f->texdef;
+-            position->orig_texdef = f->texdef;
++			position->texdef = f->texdef;
++			if(g_qeglobals.m_bBrushPrimitMode)
++			{
++				ConvertTexMatWithQTexture(&f->brushprimit_texdef, QERApp_Shader_ForName( f->texdef.GetName() )->getTexture(), &bp, NULL);
++				TexMatToFakeTexCoords(bp.coords, position->texdef.shift, &position->texdef.rotate, position->texdef.scale);
++				position->orig_bp_texdef = bp;
++			}
++			position->orig_texdef = position->texdef;
+             prev_pos->next = position;
+             prev_pos = position;
+             position++;
+@@ -103,7 +110,13 @@
+     position->face = f;
+     position->brush = b;
+     position->texdef = f->texdef;
+-    position->orig_texdef = f->texdef;
++	if(g_qeglobals.m_bBrushPrimitMode)
++	{
++		ConvertTexMatWithQTexture(&f->brushprimit_texdef, QERApp_Shader_ForName( f->texdef.GetName() )->getTexture(), &bp, NULL);
++		TexMatToFakeTexCoords(bp.coords, position->texdef.shift, &position->texdef.rotate, position->texdef.scale);
++		position->orig_bp_texdef = bp;
++	}
++    position->orig_texdef = position->texdef;
+     prev_pos = position;
+     for(i=1; i<g_ptrSelectedFaces.GetSize(); i++)
+     {
+@@ -113,7 +126,13 @@
+       position->face = f;
+       position->brush = b;
+       position->texdef = f->texdef;
+-      position->orig_texdef = f->texdef;
++	  if(g_qeglobals.m_bBrushPrimitMode)
++	  {
++		  ConvertTexMatWithQTexture(&f->brushprimit_texdef, QERApp_Shader_ForName( f->texdef.GetName() )->getTexture(), &bp, NULL);
++		  TexMatToFakeTexCoords(bp.coords, position->texdef.shift, &position->texdef.rotate, position->texdef.scale);
++		  position->orig_bp_texdef = bp;
++	  }
++      position->orig_texdef = position->texdef;
+       prev_pos->next = position;
+       prev_pos = position;
+     }
+@@ -187,7 +206,7 @@
+       if (b_isQuake2)
+         SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->orig_texdef, bFit_to_Scale);
+       else
+-        SetFaceTexdef(texdef_to_face->face, &texdef_to_face->orig_texdef, NULL);
++        SetFaceTexdef(texdef_to_face->face, &texdef_to_face->orig_texdef, &texdef_to_face->orig_bp_texdef, bFit_to_Scale);
+ 
+       Undo_Start("set facelist texdefs");
+ 
+@@ -204,7 +223,11 @@
+     if (b_isQuake2)
+       SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->texdef,  bFit_to_Scale);
+     else
+-      SetFaceTexdef(texdef_to_face->face, &texdef_to_face->texdef, NULL , bFit_to_Scale);
++	{
++	  brushprimit_texdef_t brushprimit_texdef;
++	  FakeTexCoordsToTexMat(texdef_to_face->texdef.shift, texdef_to_face->texdef.rotate, texdef_to_face->texdef.scale, brushprimit_texdef.coords);
++      SetFaceTexdef(texdef_to_face->face, &texdef_to_face->texdef, &brushprimit_texdef , bFit_to_Scale);
++	}
+     Brush_Build(texdef_to_face->brush);
+     if(bFit_to_Scale)
+       texdef_to_face->texdef = texdef_to_face->face->texdef;
+@@ -222,7 +245,10 @@
+         Undo_End();
+ 	// Over-write the orig_texdef list, cementing the change.
+ 	for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next)
++	{
+ 	  texdef_to_face->orig_texdef = texdef_to_face->texdef;
++	  texdef_to_face->orig_bp_texdef = texdef_to_face->face->brushprimit_texdef;
++	}
+       }
+   }
+ 
+@@ -232,6 +258,7 @@
+ void SI_FaceList_FitTexture(texdef_to_face_t* si_texdef_face_list, int nHeight, int nWidth)
+ {
+   texdef_to_face_t* temp_texdef_face_list;
++  brushprimit_texdef_t bp;
+ 
+   if (!si_texdef_face_list)
+     return;
+@@ -241,6 +268,12 @@
+     Face_FitTexture(temp_texdef_face_list->face, nHeight, nWidth);
+     Brush_Build(temp_texdef_face_list->brush,true,true,false,false);
+     // Write changes to our working Texdef list
++	
++	if(g_qeglobals.m_bBrushPrimitMode)
++	{
++		ConvertTexMatWithQTexture(&temp_texdef_face_list->face->brushprimit_texdef, QERApp_Shader_ForName( temp_texdef_face_list->face->texdef.GetName() )->getTexture(), &bp, NULL);
++		TexMatToFakeTexCoords(bp.coords, temp_texdef_face_list->face->texdef.shift, &temp_texdef_face_list->face->texdef.rotate, temp_texdef_face_list->face->texdef.scale);
++	}
+     temp_texdef_face_list->texdef = temp_texdef_face_list->face->texdef;
+   }
+ 
+Index: radiant/drag.cpp
+===================================================================
+--- radiant/drag.cpp	(revision 297)
++++ radiant/drag.cpp	(working copy)
+@@ -770,7 +770,7 @@
+ 		for (i=0 ; i<3 ; i++)
+ 		{
+ 			move[i] = drag_xvec[i]*(x - pressx)	+ drag_yvec[i]*(y - pressy);
+-			if (!g_PrefsDlg.m_bNoClamp)
++			if (g_PrefsDlg.m_bSnap)
+ 			{
+ 				move[i] = floor(move[i]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
+ 			}
+Index: radiant/xywindow.cpp
+===================================================================
+--- radiant/xywindow.cpp	(revision 297)
++++ radiant/xywindow.cpp	(working copy)
+@@ -1501,7 +1501,7 @@
+   for (i=0 ; i<3 ; i++)
+   {
+     delta[i] = xvec[i] * (x - m_nPressx) + yvec[i] * (y - m_nPressy);
+-    if (!g_PrefsDlg.m_bNoClamp)
++    if (g_PrefsDlg.m_bSnap)
+     {
+       delta[i] = floor(delta[i] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
+     }
+@@ -2135,13 +2135,13 @@
+ 
+ void XYWnd::SnapToPoint (int x, int y, vec3_t point)
+ {
+-  if (g_PrefsDlg.m_bNoClamp)
++  if (g_PrefsDlg.m_bSnap)
+   {
+-    XY_ToPoint(x, y, point);
++    XY_ToGridPoint(x, y, point);
+   }
+   else
+   {
+-    XY_ToGridPoint(x, y, point);
++    XY_ToPoint(x, y, point);
+   }
+ }
+ 
+Index: radiant/brush_primit.cpp
+===================================================================
+--- radiant/brush_primit.cpp	(revision 297)
++++ radiant/brush_primit.cpp	(working copy)
+@@ -186,11 +186,11 @@
+ {
+ #ifdef DBG_BP
+ 	// check this matrix is orthogonal
+-	if (fabs(texMat[0][0]*texMat[0][1]+texMat[1][0]*texMat[1][1])>ZERO_EPSILON)
++	if (fabs(texMat[0][0]*1.0L*texMat[0][1]+texMat[1][0]*1.0L*texMat[1][1])>ZERO_EPSILON)
+ 		Sys_Printf("Warning : non orthogonal texture matrix in TexMatToFakeTexCoords\n");
+ #endif
+-	scale[0]=sqrt(texMat[0][0]*texMat[0][0]+texMat[1][0]*texMat[1][0]);
+-	scale[1]=sqrt(texMat[0][1]*texMat[0][1]+texMat[1][1]*texMat[1][1]);
++	scale[0]=sqrt(texMat[0][0]*1.0L*texMat[0][0]+texMat[1][0]*1.0L*texMat[1][0]);
++	scale[1]=sqrt(texMat[0][1]*1.0L*texMat[0][1]+texMat[1][1]*1.0L*texMat[1][1]);
+ #ifdef DBG_BP
+ 	if (scale[0]<ZERO_EPSILON || scale[1]<ZERO_EPSILON)
+ 		Sys_Printf("Warning : unexpected scale==0 in TexMatToFakeTexCoords\n");
+@@ -210,7 +210,7 @@
+ 			*rot=-90.0f;
+ 	}
+ 	else
+-	*rot = RAD2DEG( atan2( texMat[1][0], texMat[0][0] ) );
++	*rot = RAD2DEG( atan2( texMat[1][0]*1.0L, texMat[0][0]*1.0L ) );
+ 	shift[0] = -texMat[0][2];
+ 	shift[1] = texMat[1][2];
+ }
+@@ -219,10 +219,10 @@
+ // the matrix returned must be understood as a qtexture_t with width=2 height=2 ( the default one )
+ void FakeTexCoordsToTexMat( float shift[2], float rot, float scale[2], vec_t texMat[2][3] )
+ {
+-	texMat[0][0] = scale[0] * cos( DEG2RAD( rot ) );
+-	texMat[1][0] = scale[0] * sin( DEG2RAD( rot ) );
+-	texMat[0][1] = -1.0f * scale[1] * sin( DEG2RAD( rot ) );
+-	texMat[1][1] = scale[1] * cos( DEG2RAD( rot ) );
++	texMat[0][0] = scale[0] *1.0L* cos( DEG2RAD( 1.0L*rot ) );
++	texMat[1][0] = scale[0] *1.0L* sin( DEG2RAD( 1.0L*rot ) );
++	texMat[0][1] = -scale[1] *1.0L* sin( DEG2RAD( 1.0L*rot ) );
++	texMat[1][1] = scale[1] *1.0L* cos( DEG2RAD( 1.0L*rot ) );
+ 	texMat[0][2] = -shift[0];
+ 	texMat[1][2] = shift[1];
+ }
+Index: radiant/select.cpp
+===================================================================
+--- radiant/select.cpp	(revision 297)
++++ radiant/select.cpp	(working copy)
+@@ -735,7 +735,7 @@
+ 	vec3_t	mins, maxs;
+ 	int		i;
+ 
+-  if (g_PrefsDlg.m_bNoClamp)
++  if (!g_PrefsDlg.m_bSnap)
+   {
+     Select_GetTrueMid(mid);
+     return;
+Index: include/isurfaceplugin.h
+===================================================================
+--- include/isurfaceplugin.h	(revision 297)
++++ include/isurfaceplugin.h	(working copy)
+@@ -62,6 +62,7 @@
+   face_t *face;     // Face of Texdef
+   texdef_t texdef;  // Working texdef
+   texdef_t orig_texdef;  // Original, for baselining changes
++  brushprimit_texdef_t orig_bp_texdef; // Original, for undo
+ };
+ 
+ 
 Index: tools/quake3/q3map2/convert_map.c
 ===================================================================
 --- tools/quake3/q3map2/convert_map.c	(revision 290)
@@ -1608,4 +2256,4 @@
 +++ include/version.default	(working copy)
 @@ -1 +1 @@
 -1.4.0
-+1.4.0-div0-obj
++1.4.0-div0-obj-bp2texdeffix-bpsurfacedialog

Copied: branches/nexuiz-2.0/misc/gtkradiant/singlepatches/gtkradiant-bp2texdeffix.diff (from rev 3797, trunk/misc/gtkradiant/singlepatches/gtkradiant-bp2texdeffix.diff)
===================================================================
--- branches/nexuiz-2.0/misc/gtkradiant/singlepatches/gtkradiant-bp2texdeffix.diff	                        (rev 0)
+++ branches/nexuiz-2.0/misc/gtkradiant/singlepatches/gtkradiant-bp2texdeffix.diff	2008-07-09 14:20:30 UTC (rev 3798)
@@ -0,0 +1,290 @@
+Index: radiant/brush_primit.cpp
+===================================================================
+--- radiant/brush_primit.cpp	(revision 297)
++++ radiant/brush_primit.cpp	(working copy)
+@@ -388,8 +388,9 @@
+ //	ConvertTexMatWithQTexture( &f->brushprimit_texdef, NULL, &f->brushprimit_texdef, f->d_texture );
+ }
+ 
+-void BrushPrimitFaceToFace(face_t *face)
++void BrushPrimitFaceToFace(face_t *f)
+ {
++  /*
+   // we have parsed brush primitives and need conversion back to standard format
+   // NOTE: converting back is a quick hack, there's some information lost and we can't do anything about it
+   // FIXME: if we normalize the texture matrix to a standard 2x2 size, we end up with wrong scaling
+@@ -399,6 +400,28 @@
+   TexMatToFakeTexCoords( aux.coords, face->texdef.shift, &face->texdef.rotate, face->texdef.scale );
+   face->texdef.scale[0]/=2.0;
+   face->texdef.scale[1]/=2.0;
++  */
++    vec3_t texX,texY;
++    vec3_t proj;
++    vec_t ST[3][5];
++
++    ComputeAxisBase(f->plane.normal,texX,texY);
++    VectorCopy(f->plane.normal,proj);
++    VectorScale(proj,f->plane.dist,proj);
++    VectorCopy(proj,ST[0]);
++    VectorCopy(texX,ST[1]);
++    VectorAdd(ST[1],proj,ST[1]);
++    VectorCopy(texY,ST[2]);
++    VectorAdd(ST[2],proj,ST[2]);
++
++	ST[0][3] = f->brushprimit_texdef.coords[0][2];
++	ST[0][4] = f->brushprimit_texdef.coords[1][2];
++	ST[1][3] = f->brushprimit_texdef.coords[0][0] + ST[0][3];
++	ST[1][4] = f->brushprimit_texdef.coords[1][0] + ST[0][4];
++	ST[2][3] = f->brushprimit_texdef.coords[0][1] + ST[0][3];
++	ST[2][4] = f->brushprimit_texdef.coords[1][1] + ST[0][4];
++
++	Face_TexdefFromTextureCoordinates(ST[0], ST[1], ST[2], f->d_texture, f);
+ }
+ 
+ // TEXTURE LOCKING -----------------------------------------------------------------------------------------------------
+Index: radiant/brush.cpp
+===================================================================
+--- radiant/brush.cpp	(revision 297)
++++ radiant/brush.cpp	(working copy)
+@@ -423,7 +423,93 @@
+ 	}
+ }
+ 
++long double HighestImpactSign(long double a, long double b)
++{
++	// returns the sign of the value with larger abs
++	if(a+b > 0)
++		return +1;
++	else
++		return -1;
++}
++
++void Face_TexdefFromTextureVectors (face_t *f, long double STfromXYZ[2][4], vec3_t pvecs[2], int sv, int tv)
++{
++	texdef_t *td;
++	qtexture_t *q;
++	int j;
++	long double ang;
++
++    td = &f->texdef;
++    q = f->d_texture;
++
++	// undo the texture transform
++    for (j=0 ; j<4 ; j++) {
++        STfromXYZ[0][j] *= q->width;
++        STfromXYZ[1][j] *= q->height;
++    }
++
++    // shift
++    td->shift[0] = STfromXYZ[0][3];
++    td->shift[1] = STfromXYZ[1][3];
++
+ /*
++	SOLVE:
++		STfromXYZ[0][sv] = (cosv * pvecs[0][sv] - sinv * pvecs[0][tv]) / td->scale[0];
++		STfromXYZ[0][tv] = (sinv * pvecs[0][sv] + cosv * pvecs[0][tv]) / td->scale[0];
++		STfromXYZ[1][sv] = (cosv * pvecs[1][sv] - sinv * pvecs[1][tv]) / td->scale[1];
++		STfromXYZ[1][tv] = (sinv * pvecs[1][sv] + cosv * pvecs[1][tv]) / td->scale[1];
++	FOR:
++		sinv, cosv, td->scale[0], td->scale[1]
++	WE KNOW:
++		sinv^2 + cosv^2 = 1
++		pvecs[0][sv] is +/-1
++		pvecs[0][tv] is 0
++		pvecs[1][sv] is 0
++		pvecs[1][tv] is +/-1
++	THUS:
++		STfromXYZ[0][sv] = +cosv * pvecs[0][sv] / td->scale[0];
++		STfromXYZ[0][tv] = +sinv * pvecs[0][sv] / td->scale[0];
++		STfromXYZ[1][sv] = -sinv * pvecs[1][tv] / td->scale[1];
++		STfromXYZ[1][tv] = +cosv * pvecs[1][tv] / td->scale[1];
++*/
++
++	td->scale[0] = sqrt(STfromXYZ[0][sv]*STfromXYZ[0][sv] + STfromXYZ[0][tv]*STfromXYZ[0][tv]);
++	td->scale[1] = sqrt(STfromXYZ[1][sv]*STfromXYZ[1][sv] + STfromXYZ[1][tv]*STfromXYZ[1][tv]);
++
++	if(td->scale[0]) td->scale[0] = 1 / td->scale[0]; // avoid NaNs
++	if(td->scale[1]) td->scale[1] = 1 / td->scale[1];
++
++	long double sign0tv = (STfromXYZ[0][tv] > 0) ? +1 : -1;
++	ang = atan2( sign0tv * STfromXYZ[0][tv], sign0tv * STfromXYZ[0][sv]); // atan2(y, x) with y positive is in [0, PI[
++
++	// STOP
++	// We have until now ignored the fact that td->scale[0] or td->scale[1] may
++	// have either sign (+ or -). Due to roundoff errors, our choice of
++	// sign0tv may even have been wrong in a sense. 
++	// sign0tv may NOT indicate the appropriate sign for td->scale[0] (namely,
++	// if cosv is near zero)!
++	// let's look at the signs again
++	//   sign0sv =  signcosv * pvecs[0][sv] / td->scale[0]sign
++	//   sign0tv =             pvecs[0][sv] / td->scale[0]sign
++	//   sign1sv = -1        * pvecs[1][tv] / td->scale[1]sign
++	//   sign1tv =  signcosv * pvecs[1][tv] / td->scale[1]sign
++	// -->
++	//   td->scale[1]sign =  sign1tv * signcosv * pvecs[1][tv]
++	//   td->scale[1]sign = -sign1sv * signsinv * pvecs[1][tv]
++	//   td->scale[0]sign =  sign0tv * signsinv * pvecs[0][sv]
++	//   td->scale[0]sign =  sign0sv * signcosv * pvecs[0][sv]
++	// which to choose?
++	// the one with the larger impact on the original texcoords, of course
++	// to minimize the effect of roundoff errors that may flip the signs!
++	
++	td->scale[0] *= HighestImpactSign(STfromXYZ[0][tv] * +sin(ang), STfromXYZ[0][sv] * cos(ang)) * pvecs[0][sv];
++	td->scale[1] *= HighestImpactSign(STfromXYZ[1][sv] * -sin(ang), STfromXYZ[1][tv] * cos(ang)) * pvecs[1][tv];
++
++	td->rotate = ang * 180 / Q_PI; // FIXME possibly snap this to 0/90/180 (270 can't happen)?
++}
++
++
++/*
+ ================
+ Face_MakePlane
+ ================
+@@ -462,6 +548,135 @@
+ 	xyzst[4] = DotProduct (xyzst, STfromXYZ[1]) + STfromXYZ[1][3];
+ }
+ 
++long double SarrusDetScalar(long double a1, long double b1, long double c1, long double a2, long double b2, long double c2, long double a3, long double b3, long double c3)
++{
++	return a1 * b2 * c3 + a2 * b3 * c1 + a3 * b1 * c2
++	     - a1 * c2 * b3 - a2 * c3 * b1 - a3 * c1 * b2;
++}
++
++void SarrusSolve(long double a1, long double b1, long double c1, long double d1, long double a2, long double b2, long double c2, long double d2, long double a3, long double b3, long double c3, long double d3, long double *a, long double *b, long double *c)
++{
++	long double det;
++	det = SarrusDetScalar(a1, b1, c1,
++	                      a2, b2, c2,
++						  a3, b3, c3);
++	*a =  SarrusDetScalar(d1, b1, c1,
++	                      d2, b2, c2,
++						  d3, b3, c3) / det;
++	*b =  SarrusDetScalar(a1, d1, c1,
++	                      a2, d2, c2,
++						  a3, d3, c3) / det;
++	*c =  SarrusDetScalar(a1, b1, d1,
++	                      a2, b2, d2,
++						  a3, b3, d3) / det;
++}
++
++void Face_TexdefFromTextureCoordinates ( float *xyzst1, float *xyzst2, float *xyzst3, qtexture_t *q, face_t *f)
++{
++	vec3_t		pvecs[2];
++	int sv, tv, uv;
++
++    long double   STfromXYZ[2][4];
++
++    // get natural texture axis
++    TextureAxisFromPlane(&f->plane, pvecs[0], pvecs[1]);
++
++    if (pvecs[0][0])
++        sv = 0;
++    else if (pvecs[0][1])
++        sv = 1;
++    else
++        sv = 2;
++
++    if (pvecs[1][0])
++        tv = 0;
++    else if (pvecs[1][1])
++        tv = 1;
++    else
++        tv = 2;
++
++	uv = 3 - sv - tv; // the "other one"
++
++    // find the STfromXYZ 4-vectors
++	/*
++	SARRUS-SOLVE:
++		xyzst1[3] == xyzst1[sv] * STfromXYZ[0][sv] + xyzst1[tv] * STfromXYZ[0][tv] + STfromXYZ[0][3];
++		xyzst2[3] == xyzst2[sv] * STfromXYZ[0][sv] + xyzst2[tv] * STfromXYZ[0][tv] + STfromXYZ[0][3];
++		xyzst3[3] == xyzst3[sv] * STfromXYZ[0][sv] + xyzst3[tv] * STfromXYZ[0][tv] + STfromXYZ[0][3];
++	FOR: STfromXYZ[0]
++	GIVEN: one coord of them (uv) is empty (see Face_TextureVectors)
++	SARRUS-SOLVE:
++		xyzst1[4] == xyzst1[sv] * STfromXYZ[1][sv] + xyzst1[tv] * STfromXYZ[1][tv] + STfromXYZ[1][3];
++		xyzst2[4] == xyzst2[sv] * STfromXYZ[1][sv] + xyzst2[tv] * STfromXYZ[1][tv] + STfromXYZ[1][3];
++		xyzst3[4] == xyzst3[sv] * STfromXYZ[1][sv] + xyzst3[tv] * STfromXYZ[1][tv] + STfromXYZ[1][3];
++	FOR: STfromXYZ[1]
++	GIVEN: one coord of them (uv) is empty (see Face_TextureVectors)
++	*/
++
++	STfromXYZ[0][uv] = 0;
++	SarrusSolve(
++		xyzst1[sv],        xyzst1[tv],        1,               xyzst1[3],
++		xyzst2[sv],        xyzst2[tv],        1,               xyzst2[3],
++		xyzst3[sv],        xyzst3[tv],        1,               xyzst3[3],
++		&STfromXYZ[0][sv], &STfromXYZ[0][tv], &STfromXYZ[0][3]
++	);
++
++	STfromXYZ[1][uv] = 0;
++	SarrusSolve(
++		xyzst1[sv],        xyzst1[tv],        1,               xyzst1[4],
++		xyzst2[sv],        xyzst2[tv],        1,               xyzst2[4],
++		xyzst3[sv],        xyzst3[tv],        1,               xyzst3[4],
++		&STfromXYZ[1][sv], &STfromXYZ[1][tv], &STfromXYZ[1][3]
++	);
++
++	/*
++	printf("%s\n", q->name);
++
++	printf("%f == %Lf\n", xyzst1[3], DotProduct (xyzst1, STfromXYZ[0]) + STfromXYZ[0][3]);
++	printf("%f == %Lf\n", xyzst2[3], DotProduct (xyzst2, STfromXYZ[0]) + STfromXYZ[0][3]);
++	printf("%f == %Lf\n", xyzst3[3], DotProduct (xyzst3, STfromXYZ[0]) + STfromXYZ[0][3]);
++	printf("%f == %Lf\n", xyzst1[4], DotProduct (xyzst1, STfromXYZ[1]) + STfromXYZ[1][3]);
++	printf("%f == %Lf\n", xyzst2[4], DotProduct (xyzst2, STfromXYZ[1]) + STfromXYZ[1][3]);
++	printf("%f == %Lf\n", xyzst3[4], DotProduct (xyzst3, STfromXYZ[1]) + STfromXYZ[1][3]);
++
++    float   newSTfromXYZ[2][4];
++
++	printf("old: %Lf,%Lf,%Lf,%Lf %Lf,%Lf,%Lf,%Lf\n",
++		STfromXYZ[0][0], STfromXYZ[0][1], STfromXYZ[0][2], STfromXYZ[0][3],
++		STfromXYZ[1][0], STfromXYZ[1][1], STfromXYZ[1][2], STfromXYZ[1][3]);
++	*/
++
++	Face_TexdefFromTextureVectors (f,  STfromXYZ, pvecs, sv, tv);
++
++	/*
++	Face_TextureVectors(f, newSTfromXYZ);
++
++	printf("new: %f,%f,%f,%f %f,%f,%f,%f\n",
++		newSTfromXYZ[0][0], newSTfromXYZ[0][1], newSTfromXYZ[0][2], newSTfromXYZ[0][3],
++		newSTfromXYZ[1][0], newSTfromXYZ[1][1], newSTfromXYZ[1][2], newSTfromXYZ[1][3]);
++
++	float newxyzst1[5];
++	float newxyzst2[5];
++	float newxyzst3[5];
++	VectorCopy(xyzst1, newxyzst1);
++	VectorCopy(xyzst2, newxyzst2);
++	VectorCopy(xyzst3, newxyzst3);
++	EmitTextureCoordinates (newxyzst1, q, f);
++	EmitTextureCoordinates (newxyzst2, q, f);
++	EmitTextureCoordinates (newxyzst3, q, f);
++	printf("Face_TexdefFromTextureCoordinates: %f,%f %f,%f %f,%f -> %f,%f %f,%f %f,%f\n",
++		xyzst1[3], xyzst1[4],
++		xyzst2[3], xyzst2[4],
++		xyzst3[3], xyzst3[4],
++		newxyzst1[3], newxyzst1[4],
++		newxyzst2[3], newxyzst2[4],
++		newxyzst3[3], newxyzst3[4]);
++	// TODO why do these differ, but not the previous ones? this makes no sense whatsoever
++	*/
++}
++
++
++
+ //==========================================================================
+ 
+ /*
+Index: radiant/qe3.h
+===================================================================
+--- radiant/qe3.h	(revision 297)
++++ radiant/qe3.h	(working copy)
+@@ -535,6 +535,7 @@
+ void EmitBrushPrimitTextureCoordinates(face_t *, winding_t *);
+ // EmitTextureCoordinates, is old code used for brush to brush primitive conversion
+ void EmitTextureCoordinates ( float *xyzst, qtexture_t *q, face_t *f);
++void Face_TexdefFromTextureCoordinates ( float *xyzst1, float *xyzst2, float *xyzst3, qtexture_t *q, face_t *f);
+ //void BrushPrimit_Parse(brush_t *);
+ // compute a fake shift scale rot representation from the texture matrix
+ void TexMatToFakeTexCoords( vec_t texMat[2][3], float shift[2], float *rot, float scale[2] );

Copied: branches/nexuiz-2.0/misc/gtkradiant/singlepatches/gtkradiant-bpsurfacedialog.diff (from rev 3797, trunk/misc/gtkradiant/singlepatches/gtkradiant-bpsurfacedialog.diff)
===================================================================
--- branches/nexuiz-2.0/misc/gtkradiant/singlepatches/gtkradiant-bpsurfacedialog.diff	                        (rev 0)
+++ branches/nexuiz-2.0/misc/gtkradiant/singlepatches/gtkradiant-bpsurfacedialog.diff	2008-07-09 14:20:30 UTC (rev 3798)
@@ -0,0 +1,358 @@
+Index: config.py
+===================================================================
+--- config.py	(revision 297)
++++ config.py	(working copy)
+@@ -236,7 +236,7 @@
+ 		if ( useZ ):
+ 			env.Append( LIBS = 'z' )
+ 
+-		env.Append( CFLAGS = baseflags )
++		env.Append( CCFLAGS = baseflags )
+ 		env.Append( CXXFLAGS = baseflags + [ '-fpermissive', '-fvisibility-inlines-hidden' ] )
+ 		env.Append( CPPPATH = [ 'include', 'libs' ] )
+ 		env.Append( CPPDEFINES = [ 'Q_NO_STLPORT' ] )
+Index: plugins/surface/surfacedialog.cpp
+===================================================================
+--- plugins/surface/surfacedialog.cpp	(revision 297)
++++ plugins/surface/surfacedialog.cpp	(working copy)
+@@ -1027,7 +1027,7 @@
+   gtk_widget_set_sensitive( GTK_WIDGET( vscale_value_spinbutton ), FALSE );
+ 
+   rotate_value_spinbutton_adj = gtk_adjustment_new (0.0, -360.0, 360.0, 1.0, 10.0, 10.0);
+-  rotate_value_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_value_spinbutton_adj), 1, 0);
++  rotate_value_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_value_spinbutton_adj), 1, 4);
+   gtk_widget_show (rotate_value_spinbutton);
+   gtk_table_attach (GTK_TABLE (table1), rotate_value_spinbutton, 1, 2, 10, 11,
+                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+@@ -1078,7 +1078,7 @@
+   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (vscale_offset_spinbutton), TRUE);
+ 
+   rotate_offset_spinbutton_adj = gtk_adjustment_new (0.0, -360.0, 360.0, 1.0, 10.0, 10.0);
+-  rotate_offset_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_offset_spinbutton_adj), 0, 2);
++  rotate_offset_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_offset_spinbutton_adj), 0, 4);
+   gtk_widget_show (rotate_offset_spinbutton);
+   gtk_table_attach (GTK_TABLE (table1), rotate_offset_spinbutton, 2, 3, 10, 11,
+                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+@@ -1121,7 +1121,7 @@
+   gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (vscale_step_spinbutton), GTK_UPDATE_IF_VALID);
+ 
+   rotate_step_spinbutton_adj = gtk_adjustment_new (0.0, -360.0, 360.0, 1.0, 10.0, 10.0);
+-  rotate_step_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_step_spinbutton_adj), 1, 2);
++  rotate_step_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (rotate_step_spinbutton_adj), 1, 4);
+   gtk_widget_show (rotate_step_spinbutton);
+   gtk_table_attach (GTK_TABLE (table1), rotate_step_spinbutton, 3, 4, 10, 11,
+                     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+Index: radiant/preferences.h
+===================================================================
+--- radiant/preferences.h	(revision 297)
++++ radiant/preferences.h	(working copy)
+@@ -579,6 +579,7 @@
+   bool  m_bPluginToolbar;
+   bool  m_bNoClamp;
+ 	//++timo this is most likely broken, I don't know what it's supposed to do
++  bool  m_bSnap;
+   Str   m_strUserPath;
+   int   m_nRotation;
+   bool  m_bChaseMouse;
+Index: radiant/mainframe.cpp
+===================================================================
+--- radiant/mainframe.cpp	(revision 297)
++++ radiant/mainframe.cpp	(working copy)
+@@ -3824,7 +3824,7 @@
+   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_view_opengllighting"));
+   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_PrefsDlg.m_bGLLighting) ? TRUE : FALSE);
+   item  = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_snaptogrid"));
+-  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (!g_PrefsDlg.m_bNoClamp) ? TRUE : FALSE);
++  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), (g_PrefsDlg.m_bSnap) ? TRUE : FALSE);
+ 
+   item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "tb_view_cubicclipping"));
+   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (item), (g_PrefsDlg.m_bCubicClipping) ? TRUE : FALSE);
+@@ -4658,7 +4658,7 @@
+     GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_snaptogrid"));
+     g_bIgnoreCommands++;
+     gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
+-                                    (!g_PrefsDlg.m_bNoClamp) ? TRUE : FALSE);
++                                    (g_PrefsDlg.m_bSnap) ? TRUE : FALSE);
+     g_bIgnoreCommands--;
+   }
+ }
+@@ -5686,12 +5686,12 @@
+ 
+ void MainFrame::OnSnaptogrid()
+ {
+-  g_PrefsDlg.m_bNoClamp ^= 1;
++  g_PrefsDlg.m_bSnap ^= 1;
+   g_PrefsDlg.SavePrefs ();
+ 
+   GtkWidget *item = GTK_WIDGET (g_object_get_data (G_OBJECT (m_pWidget), "menu_snaptogrid"));
+   g_bIgnoreCommands++;
+-  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bNoClamp ? FALSE : TRUE);
++  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_PrefsDlg.m_bSnap ? TRUE : FALSE);
+   g_bIgnoreCommands--;
+ }
+ 
+Index: radiant/preferences.cpp
+===================================================================
+--- radiant/preferences.cpp	(revision 297)
++++ radiant/preferences.cpp	(working copy)
+@@ -96,6 +96,7 @@
+ #define WIDETOOLBAR_KEY         "WideToolBar"
+ #define PLUGINTOOLBAR_KEY "PluginToolBar"
+ #define NOCLAMP_KEY             "NoClamp"
++#define SNAP_KEY                "Snap"
+ #define PREFAB_KEY              "PrefabPath"
+ #define USERINI_KEY             "UserINIPath"
+ #define ROTATION_KEY            "Rotation"
+@@ -635,6 +636,7 @@
+   m_bWideToolbar = TRUE;
+   m_bPluginToolbar = TRUE;
+   m_bNoClamp = FALSE;
++  m_bSnap = TRUE;
+   m_strUserPath = "";
+   m_nRotation = 0;
+   m_bChaseMouse = FALSE;
+@@ -2342,6 +2344,12 @@
+   gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
+   AddDialogData (check, &m_bNoClamp, DLG_CHECK_BOOL);
+ 
++  // Snap to grid
++  check = gtk_check_button_new_with_label (_("Snap to grid"));
++  gtk_widget_show (check);
++  gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
++  AddDialogData (check, &m_bSnap, DLG_CHECK_BOOL);
++
+   // Select patch by bounding box
+   check = gtk_check_button_new_with_label (_("Select patches by bounding box"));
+   gtk_widget_show (check);
+@@ -2912,6 +2920,7 @@
+   m_nShader = m_nLatchedShader;
+ 
+   mLocalPrefs.GetPref(NOCLAMP_KEY,            &m_bNoClamp,                    FALSE);
++  mLocalPrefs.GetPref(SNAP_KEY,               &m_bSnap,                       TRUE);
+   mLocalPrefs.GetPref(USERINI_KEY,            &m_strUserPath,                 "");
+   mLocalPrefs.GetPref(ROTATION_KEY,           &m_nRotation,                   45);
+   mLocalPrefs.GetPref(CHASEMOUSE_KEY,         &m_bChaseMouse,                 TRUE);
+Index: radiant/surfaceplugin.cpp
+===================================================================
+--- radiant/surfaceplugin.cpp	(revision 297)
++++ radiant/surfaceplugin.cpp	(working copy)
+@@ -73,6 +73,7 @@
+   face_t	*f;
+   brush_t	*b;
+   texdef_to_face_t *position, *prev_pos;
++  brushprimit_texdef_t bp;
+ 
+   if(selected_brushes.next != &selected_brushes)
+   {
+@@ -85,8 +86,14 @@
+         {
+             position->face = f;
+             position->brush = b;
+-            position->texdef = f->texdef;
+-            position->orig_texdef = f->texdef;
++			position->texdef = f->texdef;
++			if(g_qeglobals.m_bBrushPrimitMode)
++			{
++				ConvertTexMatWithQTexture(&f->brushprimit_texdef, QERApp_Shader_ForName( f->texdef.GetName() )->getTexture(), &bp, NULL);
++				TexMatToFakeTexCoords(bp.coords, position->texdef.shift, &position->texdef.rotate, position->texdef.scale);
++				position->orig_bp_texdef = bp;
++			}
++			position->orig_texdef = position->texdef;
+             prev_pos->next = position;
+             prev_pos = position;
+             position++;
+@@ -103,7 +110,13 @@
+     position->face = f;
+     position->brush = b;
+     position->texdef = f->texdef;
+-    position->orig_texdef = f->texdef;
++	if(g_qeglobals.m_bBrushPrimitMode)
++	{
++		ConvertTexMatWithQTexture(&f->brushprimit_texdef, QERApp_Shader_ForName( f->texdef.GetName() )->getTexture(), &bp, NULL);
++		TexMatToFakeTexCoords(bp.coords, position->texdef.shift, &position->texdef.rotate, position->texdef.scale);
++		position->orig_bp_texdef = bp;
++	}
++    position->orig_texdef = position->texdef;
+     prev_pos = position;
+     for(i=1; i<g_ptrSelectedFaces.GetSize(); i++)
+     {
+@@ -113,7 +126,13 @@
+       position->face = f;
+       position->brush = b;
+       position->texdef = f->texdef;
+-      position->orig_texdef = f->texdef;
++	  if(g_qeglobals.m_bBrushPrimitMode)
++	  {
++		  ConvertTexMatWithQTexture(&f->brushprimit_texdef, QERApp_Shader_ForName( f->texdef.GetName() )->getTexture(), &bp, NULL);
++		  TexMatToFakeTexCoords(bp.coords, position->texdef.shift, &position->texdef.rotate, position->texdef.scale);
++		  position->orig_bp_texdef = bp;
++	  }
++      position->orig_texdef = position->texdef;
+       prev_pos->next = position;
+       prev_pos = position;
+     }
+@@ -187,7 +206,7 @@
+       if (b_isQuake2)
+         SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->orig_texdef, bFit_to_Scale);
+       else
+-        SetFaceTexdef(texdef_to_face->face, &texdef_to_face->orig_texdef, NULL);
++        SetFaceTexdef(texdef_to_face->face, &texdef_to_face->orig_texdef, &texdef_to_face->orig_bp_texdef, bFit_to_Scale);
+ 
+       Undo_Start("set facelist texdefs");
+ 
+@@ -204,7 +223,11 @@
+     if (b_isQuake2)
+       SetFaceTexdef_Q2(texdef_to_face->face, &texdef_to_face->texdef,  bFit_to_Scale);
+     else
+-      SetFaceTexdef(texdef_to_face->face, &texdef_to_face->texdef, NULL , bFit_to_Scale);
++	{
++	  brushprimit_texdef_t brushprimit_texdef;
++	  FakeTexCoordsToTexMat(texdef_to_face->texdef.shift, texdef_to_face->texdef.rotate, texdef_to_face->texdef.scale, brushprimit_texdef.coords);
++      SetFaceTexdef(texdef_to_face->face, &texdef_to_face->texdef, &brushprimit_texdef , bFit_to_Scale);
++	}
+     Brush_Build(texdef_to_face->brush);
+     if(bFit_to_Scale)
+       texdef_to_face->texdef = texdef_to_face->face->texdef;
+@@ -222,7 +245,10 @@
+         Undo_End();
+ 	// Over-write the orig_texdef list, cementing the change.
+ 	for(texdef_to_face = texdef_face_list; texdef_to_face; texdef_to_face = texdef_to_face->next)
++	{
+ 	  texdef_to_face->orig_texdef = texdef_to_face->texdef;
++	  texdef_to_face->orig_bp_texdef = texdef_to_face->face->brushprimit_texdef;
++	}
+       }
+   }
+ 
+@@ -232,6 +258,7 @@
+ void SI_FaceList_FitTexture(texdef_to_face_t* si_texdef_face_list, int nHeight, int nWidth)
+ {
+   texdef_to_face_t* temp_texdef_face_list;
++  brushprimit_texdef_t bp;
+ 
+   if (!si_texdef_face_list)
+     return;
+@@ -241,6 +268,12 @@
+     Face_FitTexture(temp_texdef_face_list->face, nHeight, nWidth);
+     Brush_Build(temp_texdef_face_list->brush,true,true,false,false);
+     // Write changes to our working Texdef list
++	
++	if(g_qeglobals.m_bBrushPrimitMode)
++	{
++		ConvertTexMatWithQTexture(&temp_texdef_face_list->face->brushprimit_texdef, QERApp_Shader_ForName( temp_texdef_face_list->face->texdef.GetName() )->getTexture(), &bp, NULL);
++		TexMatToFakeTexCoords(bp.coords, temp_texdef_face_list->face->texdef.shift, &temp_texdef_face_list->face->texdef.rotate, temp_texdef_face_list->face->texdef.scale);
++	}
+     temp_texdef_face_list->texdef = temp_texdef_face_list->face->texdef;
+   }
+ 
+Index: radiant/drag.cpp
+===================================================================
+--- radiant/drag.cpp	(revision 297)
++++ radiant/drag.cpp	(working copy)
+@@ -770,7 +770,7 @@
+ 		for (i=0 ; i<3 ; i++)
+ 		{
+ 			move[i] = drag_xvec[i]*(x - pressx)	+ drag_yvec[i]*(y - pressy);
+-			if (!g_PrefsDlg.m_bNoClamp)
++			if (g_PrefsDlg.m_bSnap)
+ 			{
+ 				move[i] = floor(move[i]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
+ 			}
+Index: radiant/xywindow.cpp
+===================================================================
+--- radiant/xywindow.cpp	(revision 297)
++++ radiant/xywindow.cpp	(working copy)
+@@ -1501,7 +1501,7 @@
+   for (i=0 ; i<3 ; i++)
+   {
+     delta[i] = xvec[i] * (x - m_nPressx) + yvec[i] * (y - m_nPressy);
+-    if (!g_PrefsDlg.m_bNoClamp)
++    if (g_PrefsDlg.m_bSnap)
+     {
+       delta[i] = floor(delta[i] / g_qeglobals.d_gridsize + 0.5) * g_qeglobals.d_gridsize;
+     }
+@@ -2135,13 +2135,13 @@
+ 
+ void XYWnd::SnapToPoint (int x, int y, vec3_t point)
+ {
+-  if (g_PrefsDlg.m_bNoClamp)
++  if (g_PrefsDlg.m_bSnap)
+   {
+-    XY_ToPoint(x, y, point);
++    XY_ToGridPoint(x, y, point);
+   }
+   else
+   {
+-    XY_ToGridPoint(x, y, point);
++    XY_ToPoint(x, y, point);
+   }
+ }
+ 
+Index: radiant/brush_primit.cpp
+===================================================================
+--- radiant/brush_primit.cpp	(revision 297)
++++ radiant/brush_primit.cpp	(working copy)
+@@ -186,11 +186,11 @@
+ {
+ #ifdef DBG_BP
+ 	// check this matrix is orthogonal
+-	if (fabs(texMat[0][0]*texMat[0][1]+texMat[1][0]*texMat[1][1])>ZERO_EPSILON)
++	if (fabs(texMat[0][0]*1.0L*texMat[0][1]+texMat[1][0]*1.0L*texMat[1][1])>ZERO_EPSILON)
+ 		Sys_Printf("Warning : non orthogonal texture matrix in TexMatToFakeTexCoords\n");
+ #endif
+-	scale[0]=sqrt(texMat[0][0]*texMat[0][0]+texMat[1][0]*texMat[1][0]);
+-	scale[1]=sqrt(texMat[0][1]*texMat[0][1]+texMat[1][1]*texMat[1][1]);
++	scale[0]=sqrt(texMat[0][0]*1.0L*texMat[0][0]+texMat[1][0]*1.0L*texMat[1][0]);
++	scale[1]=sqrt(texMat[0][1]*1.0L*texMat[0][1]+texMat[1][1]*1.0L*texMat[1][1]);
+ #ifdef DBG_BP
+ 	if (scale[0]<ZERO_EPSILON || scale[1]<ZERO_EPSILON)
+ 		Sys_Printf("Warning : unexpected scale==0 in TexMatToFakeTexCoords\n");
+@@ -210,7 +210,7 @@
+ 			*rot=-90.0f;
+ 	}
+ 	else
+-	*rot = RAD2DEG( atan2( texMat[1][0], texMat[0][0] ) );
++	*rot = RAD2DEG( atan2( texMat[1][0]*1.0L, texMat[0][0]*1.0L ) );
+ 	shift[0] = -texMat[0][2];
+ 	shift[1] = texMat[1][2];
+ }
+@@ -219,10 +219,10 @@
+ // the matrix returned must be understood as a qtexture_t with width=2 height=2 ( the default one )
+ void FakeTexCoordsToTexMat( float shift[2], float rot, float scale[2], vec_t texMat[2][3] )
+ {
+-	texMat[0][0] = scale[0] * cos( DEG2RAD( rot ) );
+-	texMat[1][0] = scale[0] * sin( DEG2RAD( rot ) );
+-	texMat[0][1] = -1.0f * scale[1] * sin( DEG2RAD( rot ) );
+-	texMat[1][1] = scale[1] * cos( DEG2RAD( rot ) );
++	texMat[0][0] = scale[0] *1.0L* cos( DEG2RAD( 1.0L*rot ) );
++	texMat[1][0] = scale[0] *1.0L* sin( DEG2RAD( 1.0L*rot ) );
++	texMat[0][1] = -scale[1] *1.0L* sin( DEG2RAD( 1.0L*rot ) );
++	texMat[1][1] = scale[1] *1.0L* cos( DEG2RAD( 1.0L*rot ) );
+ 	texMat[0][2] = -shift[0];
+ 	texMat[1][2] = shift[1];
+ }
+Index: radiant/select.cpp
+===================================================================
+--- radiant/select.cpp	(revision 297)
++++ radiant/select.cpp	(working copy)
+@@ -735,7 +735,7 @@
+ 	vec3_t	mins, maxs;
+ 	int		i;
+ 
+-  if (g_PrefsDlg.m_bNoClamp)
++  if (!g_PrefsDlg.m_bSnap)
+   {
+     Select_GetTrueMid(mid);
+     return;
+Index: include/isurfaceplugin.h
+===================================================================
+--- include/isurfaceplugin.h	(revision 297)
++++ include/isurfaceplugin.h	(working copy)
+@@ -62,6 +62,7 @@
+   face_t *face;     // Face of Texdef
+   texdef_t texdef;  // Working texdef
+   texdef_t orig_texdef;  // Original, for baselining changes
++  brushprimit_texdef_t orig_bp_texdef; // Original, for undo
+ };
+ 
+ 




More information about the nexuiz-commits mailing list