* divVerent's patch for the brush primitives surface dialog (fixed segfault due to...
authormattn <mattn>
Thu, 10 Jul 2008 08:30:47 +0000 (08:30 +0000)
committermattn <mattn>
Thu, 10 Jul 2008 08:30:47 +0000 (08:30 +0000)
* Quote http://zerowing.idsoftware.com/pipermail/gtkradiant/2008-July/011094.html : Attached to this message is a patch for a "somewhat working" brush
primitives surface dialog. It is an ugly hack, as it converts between
fake texdef notations and brush primitives whenever values are needed.
Had to fix an accuracy bug: the surface dialog rounded all rotation
values to integer angles, which SEVERELY broke things for me (changed
the Gtk spin object to use 4 digits, which is enough for me).

Also, I changed the fake texdef / brush primitives conversions to use
long double internally, as float's roundoff errors were quite visible to
me when testing.

Hope the remaining roundoff errors from converting back and forth won't
kill me, but it worked for a simple map example.

Also, I had to separate out "Snap to grid" and "Don't clamp" into two
separare options. They now mean:

- Snap to grid: snaps drag/etc. actions to the grid
- Don't clamp: disable brush point snapping during many operations, like
  merely shifting brushes, editing texturing parameters, map loading,
  etc.

The reason is that I do need the grid, but I don't want to get my
objects messed up by the snapping in my map. As I am using free
rotations, this DOES change quite much.

The config.py change is needed for compilation on Debian stable;
Debian's scons does not use the CFLAGS variable, but just CCFLAGS and
CXXFLAGS. In newer scons versions, CFLAGS is _shared_ flags for C and
C++, so if you want to require these, you don't need to include the
CFLAGS in CXXFLAGS too.

git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@301 8a3a26a2-13c4-0310-b231-cf6edde360e5

config.py
include/isurfaceplugin.h
plugins/surface/surfacedialog.cpp
radiant/brush_primit.cpp
radiant/drag.cpp
radiant/mainframe.cpp
radiant/preferences.cpp
radiant/preferences.h
radiant/select.cpp
radiant/surfaceplugin.cpp
radiant/xywindow.cpp

index f461e02daeb8b751c9ede682538aedacdbd9913e..48b54c9481cc6073d4698d708cfab4a89ae74ce4 100644 (file)
--- a/config.py
+++ b/config.py
@@ -236,7 +236,7 @@ class Config:
                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 61e2fdbab80d209fd768c31eb572f57d5c1bd3d2..c31b5791bd55a1d1f7f68a4550a60e931c104d25 100644 (file)
@@ -62,6 +62,7 @@ public:
   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 591cf7cb311324714cf6c37daa38d186ea64c191..59311bed24fbe79541eaf1dcbef94ab2a989099b 100644 (file)
@@ -1027,7 +1027,7 @@ GtkWidget* create_SurfaceInspector (void)
   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 @@ GtkWidget* create_SurfaceInspector (void)
   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 @@ GtkWidget* create_SurfaceInspector (void)
   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 3ca213526765d978adee04bf7c06f81d9a5091ce..589ab9b9f43ccf6ac23a6820c215f6624e1b84e4 100644 (file)
@@ -186,11 +186,11 @@ void TexMatToFakeTexCoords( vec_t texMat[2][3], float shift[2], float *rot, floa
 {
 #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 @@ void TexMatToFakeTexCoords( vec_t texMat[2][3], float shift[2], float *rot, floa
                        *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 @@ void TexMatToFakeTexCoords( vec_t texMat[2][3], float shift[2], float *rot, floa
 // 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 74b8d434dc11e7440e57fae3fca28728f6aec06f..509b5cce8f86454b35ca71338be5055b63543cb5 100644 (file)
@@ -770,7 +770,7 @@ void Drag_MouseMoved (int x, int y, int buttons)
                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 965ef47bbf05a78fde2c09b4109a2e98e80cd124..7edd170a7443266be9c834e35525b9e55fd51d75 100644 (file)
@@ -3824,7 +3824,7 @@ void MainFrame::SetButtonMenuStates()
   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 @@ void MainFrame::OnPrefs()
     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::OnGrid (unsigned int nID)
 
 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 be4cd3ac6ccfa5fa0ffc16e43e9acfbb4c6499ff..c9fb13bd7e4c542a2b60855340cd79d6f4159e64 100644 (file)
@@ -96,6 +96,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #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 @@ PrefsDlg::PrefsDlg ()
   m_bWideToolbar = TRUE;
   m_bPluginToolbar = TRUE;
   m_bNoClamp = FALSE;
+  m_bSnap = TRUE;
   m_strUserPath = "";
   m_nRotation = 0;
   m_bChaseMouse = FALSE;
@@ -2336,6 +2338,12 @@ void PrefsDlg::BuildDialog ()
   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);
@@ -2906,6 +2914,7 @@ void PrefsDlg::LoadPrefs ()
   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 41e7efed330d380711a1ea84ffa59008abbe5883..8a9cc63d6fe37f11f7faa51783c16dcc4f6a1374 100644 (file)
@@ -579,6 +579,7 @@ public:
   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 5fd4c72833f4a3df93d37b066e4acc952ecd3c37..ec1cf866bae2776c9756fccb2cc95735385cc3df 100644 (file)
@@ -735,7 +735,7 @@ void Select_GetMid (vec3_t mid)
        vec3_t  mins, maxs;
        int             i;
 
-  if (g_PrefsDlg.m_bNoClamp)
+  if (!g_PrefsDlg.m_bSnap)
   {
     Select_GetTrueMid(mid);
     return;
index c71defc02be42054f3fe2f1ba91c2845ce3d814c..0e04f9895b36d0013cd5910faa2b506d095bad36 100644 (file)
@@ -73,6 +73,7 @@ void SI_GetSelFacesTexdef(texdef_to_face_t *allocd_block_texdef)
   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 @@ void SI_GetSelFacesTexdef(texdef_to_face_t *allocd_block_texdef)
         {
             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 @@ void SI_GetSelFacesTexdef(texdef_to_face_t *allocd_block_texdef)
     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 @@ void SI_GetSelFacesTexdef(texdef_to_face_t *allocd_block_texdef)
       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 @@ void SI_SetTexdef_FaceList(texdef_to_face_t* texdef_face_list, bool b_SetUndoPoi
       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 @@ void SI_SetTexdef_FaceList(texdef_to_face_t* texdef_face_list, bool b_SetUndoPoi
     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 @@ void SI_SetTexdef_FaceList(texdef_to_face_t* texdef_face_list, bool b_SetUndoPoi
         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_SetTexdef_FaceList(texdef_to_face_t* texdef_face_list, bool b_SetUndoPoi
 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 @@ void SI_FaceList_FitTexture(texdef_to_face_t* si_texdef_face_list, int nHeight,
     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 6d58e8236b9e7a2aa838f1a0941f1777b479cbb1..ef974f73ac6b51ab72a479f0b487a1a556a48b96 100644 (file)
@@ -1501,7 +1501,7 @@ qboolean XYWnd::DragDelta (int x, int y, vec3_t move)
   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::XY_Init()
 
 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);
   }
 }