Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

DRAG.CPP

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 #include "stdafx.h"
00023 #include "qe3.h"
00024 
00025 /*
00026 
00027   drag either multiple brushes, or select plane points from
00028   a single brush.
00029 
00030 */
00031 
00032 qboolean    drag_ok;
00033 vec3_t  drag_xvec;
00034 vec3_t  drag_yvec;
00035 
00036 static  int buttonstate;
00037 int pressx, pressy;
00038 static  vec3_t pressdelta;
00039 static  vec3_t vPressStart;
00040 static  int buttonx, buttony;
00041 
00042 
00043 //int       num_move_points;
00044 //float *move_points[1024];
00045 
00046 int     lastx, lasty;
00047 
00048 qboolean    drag_first;
00049 
00050 
00051 void    AxializeVector (vec3_t v)
00052 {
00053     vec3_t  a;
00054     float   o;
00055     int     i;
00056 
00057     if (!v[0] && !v[1])
00058         return;
00059     if (!v[1] && !v[2])
00060         return;
00061     if (!v[0] && !v[2])
00062         return;
00063 
00064     for (i=0 ; i<3 ; i++)
00065         a[i] = fabs(v[i]);
00066     if (a[0] > a[1] && a[0] > a[2])
00067         i = 0;
00068     else if (a[1] > a[0] && a[1] > a[2])
00069         i = 1;
00070     else
00071         i = 2;
00072 
00073     o = v[i];
00074     VectorCopy (vec3_origin, v);
00075     if (o<0)
00076         v[i] = -1;
00077     else
00078         v[i] = 1;
00079     
00080 }
00081 
00082 
00083 /*
00084 ===========
00085 Drag_Setup
00086 ===========
00087 */
00088 void Drag_Setup (int x, int y, int buttons,
00089            vec3_t xaxis, vec3_t yaxis,
00090            vec3_t origin, vec3_t dir)
00091 {
00092     trace_t t;
00093     face_t  *f;
00094 
00095     drag_first = true;
00096     
00097     VectorCopy (vec3_origin, pressdelta);
00098     pressx = x;
00099     pressy = y;
00100 
00101     VectorCopy (xaxis, drag_xvec);
00102     AxializeVector (drag_xvec);
00103     VectorCopy (yaxis, drag_yvec);
00104     AxializeVector (drag_yvec);
00105 
00106     if (g_qeglobals.d_select_mode == sel_addpoint) {
00107         if (g_qeglobals.selectObject) {
00108             g_qeglobals.selectObject->addPoint(origin[0], origin[1], origin[2]);
00109         } else {
00110             clearSelection();
00111         }
00112         return;
00113     }
00114 
00115     if (g_qeglobals.d_select_mode == sel_editpoint) {
00116      
00117         if (g_qeglobals.selectObject) {
00118             if (g_qeglobals.selectObject->selectPointByRay(origin[0], origin[1], origin[2], dir[0], dir[1], dir[2], !(buttons == MK_SHIFT)) >= 0) {
00119                 drag_ok = true;
00120             } 
00121             return;
00122         } else {
00123             clearSelection();
00124         }
00125         Sys_UpdateWindows(W_ALL);
00126         Undo_Start("drag object point");
00127 
00128         return;
00129     }
00130 
00131 
00132     extern void SelectCurvePointByRay (vec3_t org, vec3_t dir, int buttons);
00133     if (g_qeglobals.d_select_mode == sel_curvepoint)
00134     {
00135         //if ((buttons == MK_LBUTTON))
00136         //  g_qeglobals.d_num_move_points = 0;
00137 
00138         SelectCurvePointByRay (origin, dir, buttons);   
00139         
00140         if (g_qeglobals.d_num_move_points || g_qeglobals.d_select_mode == sel_area)
00141         {
00142             drag_ok = true;
00143         }
00144     
00145         Sys_UpdateWindows(W_ALL);
00146 
00147         Undo_Start("drag curve point");
00148         Undo_AddBrushList(&selected_brushes);
00149 
00150         return;
00151     }
00152     else if (g_qeglobals.d_select_mode == sel_terrainpoint)
00153     {
00154         Terrain_SelectPointByRay( origin, dir, buttons );
00155         
00156         if (g_qeglobals.d_numterrapoints || g_qeglobals.d_select_mode == sel_area)
00157         {
00158             drag_ok = true;
00159         }
00160 
00161         Sys_UpdateWindows(W_ALL);
00162         
00163         Undo_Start("drag terrain point");
00164         Undo_AddBrushList(&selected_brushes);
00165         return;
00166     }
00167     else if (g_qeglobals.d_select_mode == sel_terraintexture)
00168     {
00169         Terrain_SelectPointByRay( origin, dir, buttons );
00170         
00171         if (g_qeglobals.d_numterrapoints || g_qeglobals.d_select_mode == sel_area)
00172         {
00173             drag_ok = true;
00174         }
00175 
00176         Sys_UpdateWindows(W_ALL);
00177         
00178         Undo_Start("drag terrain point");
00179         Undo_AddBrushList(&selected_brushes);
00180         return;
00181     }
00182     else
00183     {
00184         g_qeglobals.d_num_move_points = 0;
00185     }
00186 
00187     if (selected_brushes.next == &selected_brushes)
00188     {
00189         //in this case a new brush is created when the dragging
00190         //takes place in the XYWnd, An useless undo is created
00191         //when the dragging takes place in the CamWnd
00192         Undo_Start("create brush");
00193 
00194         Sys_Status("No selection to drag\n", 0);
00195         return;
00196     }
00197 
00198 
00199     if (g_qeglobals.d_select_mode == sel_vertex)
00200     {
00201         SelectVertexByRay (origin, dir);    
00202         if (g_qeglobals.d_num_move_points)
00203         {
00204             drag_ok = true;
00205             Undo_Start("drag vertex");
00206             Undo_AddBrushList(&selected_brushes);
00207             return;
00208         }
00209     }
00210 
00211     if (g_qeglobals.d_select_mode == sel_edge)
00212     {
00213         SelectEdgeByRay (origin, dir);  
00214         if (g_qeglobals.d_num_move_points)
00215         {
00216             drag_ok = true;
00217             Undo_Start("drag edge");
00218             Undo_AddBrushList(&selected_brushes);
00219             return;
00220         }
00221     }
00222 
00223 
00224     //
00225     // check for direct hit first
00226     //
00227     t = Test_Ray (origin, dir, true);
00228     if (t.selected)
00229     {
00230         drag_ok = true;
00231 
00232         Undo_Start("drag selection");
00233         Undo_AddBrushList(&selected_brushes);
00234 
00235         if (buttons == (MK_LBUTTON|MK_CONTROL) )
00236         {
00237             Sys_Printf ("Shear dragging face\n");
00238             Brush_SelectFaceForDragging (t.brush, t.face, true);
00239         }
00240         else if (buttons == (MK_LBUTTON|MK_CONTROL|MK_SHIFT) )
00241         {
00242             Sys_Printf ("Sticky dragging brush\n");
00243             for (f=t.brush->brush_faces ; f ; f=f->next)
00244                 Brush_SelectFaceForDragging (t.brush, f, false);
00245         }
00246         else
00247             Sys_Printf ("Dragging entire selection\n");
00248         
00249         return;
00250     }
00251 
00252     if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_edge)
00253         return;
00254 
00255     //
00256     // check for side hit
00257     //
00258     // multiple brushes selected?
00259     if (selected_brushes.next->next != &selected_brushes)
00260     {
00261         // yes, special handling
00262         bool bOK = (g_PrefsDlg.m_bALTEdge) ? (static_cast<bool>(::GetAsyncKeyState(VK_MENU))) : true;
00263         if (bOK)
00264         {
00265             for (brush_t* pBrush = selected_brushes.next ; pBrush != &selected_brushes ; pBrush = pBrush->next)
00266             {
00267                 if (buttons & MK_CONTROL)
00268                     Brush_SideSelect (pBrush, origin, dir, true);
00269                 else
00270                     Brush_SideSelect (pBrush, origin, dir, false);
00271             }
00272         }
00273         else
00274         {
00275             Sys_Printf ("press ALT to drag multiple edges\n");
00276             return;
00277         }
00278     }
00279     else
00280     {
00281         // single select.. trying to drag fixed entities handle themselves and just move
00282         if (buttons & MK_CONTROL)
00283             Brush_SideSelect (selected_brushes.next, origin, dir, true);
00284         else
00285             Brush_SideSelect (selected_brushes.next, origin, dir, false);
00286     }
00287 
00288     Sys_Printf ("Side stretch\n");
00289     drag_ok = true;
00290 
00291     Undo_Start("side stretch");
00292     Undo_AddBrushList(&selected_brushes);
00293 }
00294 
00295 entity_t *peLink;
00296 
00297 void UpdateTarget(vec3_t origin, vec3_t dir)
00298 {
00299     trace_t t;
00300     entity_t *pe;
00301     int i;
00302     char sz[128];
00303 
00304     t = Test_Ray (origin, dir, 0);
00305 
00306     if (!t.brush)
00307         return;
00308 
00309     pe = t.brush->owner;
00310 
00311     if (pe == NULL)
00312         return;
00313 
00314     // is this the first?
00315     if (peLink != NULL)
00316     {
00317 
00318         // Get the target id from out current target
00319         // if there is no id, make one
00320 
00321         i = IntForKey(pe, "target");
00322         if (i <= 0)
00323         {
00324             i = GetUniqueTargetId(1);
00325             sprintf(sz, "%d", i);
00326 
00327             SetKeyValue(pe, "target", sz);
00328         }
00329 
00330         // set the target # into our src
00331 
00332         sprintf(sz, "%d", i);
00333         SetKeyValue(peLink, "targetname", sz);
00334 
00335         Sys_UpdateWindows(W_ENTITY);
00336 
00337     }
00338 
00339     // promote the target to the src
00340 
00341     peLink = pe;
00342     
00343 }
00344 
00345 /*
00346 ===========
00347 Drag_Begin
00348 //++timo test three button mouse and three button emulation here ?
00349 ===========
00350 */
00351 void Drag_Begin (int x, int y, int buttons,
00352            vec3_t xaxis, vec3_t yaxis,
00353            vec3_t origin, vec3_t dir)
00354 {
00355     trace_t t;
00356     bool altdown;
00357 
00358     drag_ok = false;
00359     VectorCopy (vec3_origin, pressdelta);
00360     VectorCopy (vec3_origin, vPressStart);
00361     drag_first = true;
00362     peLink = NULL;
00363 
00364     altdown = static_cast<bool>(::GetAsyncKeyState(VK_MENU));
00365 
00366     // shift-LBUTTON = select entire brush
00367     if (buttons == (MK_LBUTTON | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint &&
00368         g_qeglobals.d_select_mode != sel_terrainpoint && g_qeglobals.d_select_mode != sel_terraintexture)
00369     {
00370         int nFlag = altdown ? SF_CYCLE : 0;
00371         if (dir[0] == 0 || dir[1] == 0 || dir[2] == 0)  // extremely low chance of this happening from camera
00372             Select_Ray (origin, dir, nFlag | SF_ENTITIES_FIRST);    // hack for XY
00373         else
00374             Select_Ray (origin, dir, nFlag);
00375         return;
00376     }
00377 
00378     // ctrl-alt-LBUTTON = multiple brush select without selecting whole entities
00379     if (buttons == (MK_LBUTTON | MK_CONTROL) && altdown && g_qeglobals.d_select_mode != sel_curvepoint &&
00380         g_qeglobals.d_select_mode != sel_terrainpoint && g_qeglobals.d_select_mode != sel_terraintexture)
00381     {
00382         if (dir[0] == 0 || dir[1] == 0 || dir[2] == 0)  // extremely low chance of this happening from camera
00383             Select_Ray (origin, dir, SF_ENTITIES_FIRST);    // hack for XY
00384         else
00385             Select_Ray (origin, dir, 0);
00386         return;
00387     }
00388 
00389     // ctrl-shift-LBUTTON = select single face
00390     if (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint &&
00391         g_qeglobals.d_select_mode != sel_terrainpoint && g_qeglobals.d_select_mode != sel_terraintexture)
00392     {
00393         Select_Deselect (!static_cast<bool>(::GetAsyncKeyState(VK_MENU)));
00394         Select_Ray (origin, dir, SF_SINGLEFACE);
00395         return;
00396     }
00397 
00398 
00399     // LBUTTON + all other modifiers = manipulate selection
00400     if (buttons & MK_LBUTTON)
00401     {
00402         //
00403         Drag_Setup (x, y, buttons, xaxis, yaxis, origin, dir);
00404         return;
00405     }
00406 
00407     int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON;
00408     // middle button = grab texture
00409     if (buttons == nMouseButton)
00410     {
00411         t = Test_Ray (origin, dir, false);
00412         if (t.face)
00413         {
00414             g_qeglobals.d_new_brush_bottom_z = t.brush->mins[2];
00415             g_qeglobals.d_new_brush_top_z = t.brush->maxs[2];
00416             // use a local brushprimit_texdef fitted to a default 2x2 texture
00417             brushprimit_texdef_t bp_local;
00418             ConvertTexMatWithQTexture( &t.face->brushprimit_texdef, t.face->d_texture, &bp_local, NULL );
00419             Texture_SetTexture ( &t.face->texdef, &bp_local, false, GETPLUGINTEXDEF(t.face));
00420             UpdateSurfaceDialog();
00421             UpdatePatchInspector();
00422         }
00423         else
00424             Sys_Printf ("Did not select a texture\n");
00425         return;
00426     }
00427 
00428     // ctrl-middle button = set entire brush to texture
00429     if (buttons == (nMouseButton|MK_CONTROL) )
00430     {
00431         t = Test_Ray (origin, dir, false);
00432         if (t.brush)
00433         {
00434             if (t.brush->brush_faces->texdef.name[0] == '(')
00435                 Sys_Printf ("Can't change an entity texture\n");
00436             else
00437             {
00438                 Brush_SetTexture (t.brush, &g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, false, static_cast<IPluginTexdef *>( g_qeglobals.d_texturewin.pTexdef ) );
00439                 Sys_UpdateWindows (W_ALL);
00440             }
00441         }
00442         else
00443             Sys_Printf ("Didn't hit a btrush\n");
00444         return;
00445     }
00446 
00447     // ctrl-shift-middle button = set single face to texture
00448     if (buttons == (nMouseButton|MK_SHIFT|MK_CONTROL) )
00449     {
00450         t = Test_Ray (origin, dir, false);
00451         if (t.brush)
00452         {
00453             if (t.brush->brush_faces->texdef.name[0] == '(')
00454                 Sys_Printf ("Can't change an entity texture\n");
00455             else
00456             {
00457                 SetFaceTexdef (t.brush, t.face, &g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef);
00458                 Brush_Build( t.brush );
00459                 Sys_UpdateWindows (W_ALL);
00460             }
00461         }
00462         else
00463             Sys_Printf ("Didn't hit a btrush\n");
00464         return;
00465     }
00466 
00467     if (buttons == (nMouseButton | MK_SHIFT))
00468     {
00469         Sys_Printf("Set brush face texture info\n");
00470         t = Test_Ray (origin, dir, false);
00471         if (t.brush)
00472         {
00473             if (t.brush->brush_faces->texdef.name[0] == '(')
00474       {
00475         if (t.brush->owner->eclass->nShowFlags & ECLASS_LIGHT)
00476         {
00477           CString strBuff;
00478           qtexture_t* pTex = Texture_ForName(g_qeglobals.d_texturewin.texdef.name);
00479           if (pTex)
00480           {
00481             vec3_t vColor;
00482             VectorCopy(pTex->color, vColor);
00483 
00484             float fLargest = 0.0f;
00485             for (int i = 0; i < 3; i++)
00486             {
00487                   if (vColor[i] > fLargest)
00488                       fLargest = vColor[i];
00489             }
00490                 
00491                 if (fLargest == 0.0f)
00492                 {
00493               vColor[0] = vColor[1] = vColor[2] = 1.0f;
00494             }
00495                 else
00496                 {
00497                     float fScale = 1.0f / fLargest;
00498               for (int i = 0; i < 3; i++)
00499               {
00500                 vColor[i] *= fScale;
00501               }
00502             }
00503             strBuff.Format("%f %f %f",pTex->color[0], pTex->color[1], pTex->color[2]);
00504             SetKeyValue(t.brush->owner, "_color", strBuff.GetBuffer(0));
00505                     Sys_UpdateWindows (W_ALL);
00506           }
00507         }
00508         else
00509         {
00510                   Sys_Printf ("Can't select an entity brush face\n");
00511         }
00512       }
00513             else
00514             {
00515         //strcpy(t.face->texdef.name,g_qeglobals.d_texturewin.texdef.name);
00516         t.face->texdef.SetName(g_qeglobals.d_texturewin.texdef.name);
00517                 Brush_Build(t.brush);
00518                 Sys_UpdateWindows (W_ALL);
00519             }
00520         }
00521         else
00522             Sys_Printf ("Didn't hit a brush\n");
00523         return;
00524     }
00525 
00526 }
00527 
00528 
00529 //
00530 //===========
00531 //MoveSelection
00532 //===========
00533 //
00534 void MoveSelection (vec3_t move)
00535 {
00536     int     i, success;
00537     brush_t *b;
00538     CString strStatus;
00539     vec3_t vTemp, vTemp2, end;
00540 
00541     if (!move[0] && !move[1] && !move[2])
00542         return;
00543 
00544     move[0] = (g_nScaleHow & SCALE_X) ? 0 : move[0];
00545     move[1] = (g_nScaleHow & SCALE_Y) ? 0 : move[1];
00546   move[2] = (g_nScaleHow & SCALE_Z) ? 0 : move[2];
00547 
00548     if (g_pParentWnd->ActiveXY()->RotateMode() || g_bPatchBendMode)
00549     {
00550         float fDeg = -move[2];
00551         float fAdj = move[2];
00552         int nAxis = 0;
00553         if (g_pParentWnd->ActiveXY()->GetViewType() == XY)
00554         {
00555             fDeg = -move[1];
00556             fAdj = move[1];
00557             nAxis = 2;
00558         }
00559         else 
00560             if (g_pParentWnd->ActiveXY()->GetViewType() == XZ)
00561         {
00562             fDeg = move[2];
00563             fAdj = move[2];
00564             nAxis = 1;
00565         }
00566         else
00567             nAxis = 0;
00568 
00569         g_pParentWnd->ActiveXY()->Rotation()[nAxis] += fAdj;
00570         strStatus.Format("%s x:: %.1f  y:: %.1f  z:: %.1f", (g_bPatchBendMode) ? "Bend angle" : "Rotation", g_pParentWnd->ActiveXY()->Rotation()[0], g_pParentWnd->ActiveXY()->Rotation()[1], g_pParentWnd->ActiveXY()->Rotation()[2]);
00571         g_pParentWnd->SetStatusText(2, strStatus);
00572 
00573         if (g_bPatchBendMode)
00574         {
00575             Patch_SelectBendNormal();
00576             Select_RotateAxis(nAxis, fDeg*2, false, true);
00577             Patch_SelectBendAxis();
00578             Select_RotateAxis(nAxis, fDeg, false, true);
00579         }
00580         else
00581         {
00582             Select_RotateAxis(nAxis, fDeg, false, true);
00583         }
00584         return;
00585     }
00586 
00587     if (g_pParentWnd->ActiveXY()->ScaleMode())
00588     {
00589         vec3_t v;
00590         v[0] = v[1] = v[2] = 1.0;
00591         if (move[1] > 0)
00592         {
00593             v[0] = 1.1;
00594             v[1] = 1.1;
00595             v[2] = 1.1;
00596         }
00597         else 
00598             if (move[1] < 0)
00599         {
00600             v[0] = 0.9;
00601             v[1] = 0.9;
00602             v[2] = 0.9;
00603         }
00604 
00605             Select_Scale((g_nScaleHow & SCALE_X) ? 1.0 : v[0],
00606                                      (g_nScaleHow & SCALE_Y) ? 1.0 : v[1],
00607                                  (g_nScaleHow & SCALE_Z) ? 1.0 : v[2]);
00608         Sys_UpdateWindows (W_ALL);
00609         return;
00610     }
00611 
00612 
00613     vec3_t vDistance;
00614     VectorSubtract(pressdelta, vPressStart, vDistance);
00615     strStatus.Format("Distance x: %.1f  y: %.1f  z: %.1f", vDistance[0], vDistance[1], vDistance[2]);
00616     g_pParentWnd->SetStatusText(3, strStatus);
00617 
00618     //
00619     // dragging only a part of the selection
00620     //
00621     //point object selection
00622     if (g_qeglobals.d_select_mode == sel_editpoint) {
00623         if (g_qeglobals.selectObject) {
00624             g_qeglobals.selectObject->updateSelection(move[0], move[1], move[2]);
00625         }
00626         return;
00627     }
00628 
00629 
00630     // this is fairly crappy way to deal with curvepoint and area selection
00631     // but it touches the smallest amount of code this way
00632     // 
00633     if (g_qeglobals.d_num_move_points || g_qeglobals.d_numterrapoints || g_qeglobals.d_select_mode == sel_area)
00634     {
00635         //area selection
00636         if (g_qeglobals.d_select_mode == sel_area)
00637         {
00638             VectorAdd(g_qeglobals.d_vAreaBR, move, g_qeglobals.d_vAreaBR);
00639             return;
00640         }
00641         //curve point selection
00642         if (g_qeglobals.d_select_mode == sel_curvepoint)
00643         {
00644             Patch_UpdateSelected(move);
00645             return;
00646         }
00647         //terrain point selection
00648         if ( ( g_qeglobals.d_select_mode == sel_terrainpoint ) || ( g_qeglobals.d_select_mode == sel_terraintexture ) )
00649         {
00650             Terrain_UpdateSelected(move);
00651             return;
00652         }
00653 
00654         //vertex selection
00655         if (g_qeglobals.d_select_mode == sel_vertex)
00656         {
00657             success = true;
00658             for (b = selected_brushes.next; b != &selected_brushes; b = b->next)
00659             {
00660                 success &= Brush_MoveVertex(b, g_qeglobals.d_move_points[0], move, end, true);
00661             }
00662             if (success)
00663                 VectorCopy(end, g_qeglobals.d_move_points[0]);
00664             return;
00665         }
00666         //all other selection types
00667         for (i=0 ; i<g_qeglobals.d_num_move_points ; i++)
00668             VectorAdd (g_qeglobals.d_move_points[i], move, g_qeglobals.d_move_points[i]);
00669         //VectorScale(move, .5, move);
00670         //for (i=0 ; i<g_qeglobals.d_num_move_points2 ; i++)
00671         //  VectorAdd (g_qeglobals.d_move_points2[i], move, g_qeglobals.d_move_points2[i]);
00672         for (b = selected_brushes.next; b != &selected_brushes; b = b->next)
00673         {
00674             VectorCopy(b->maxs, vTemp);
00675             VectorSubtract(vTemp, b->mins, vTemp);
00676             Brush_Build( b );
00677             for (i=0 ; i<3 ; i++)
00678                 if (b->mins[i] > b->maxs[i]
00679                 || b->maxs[i] - b->mins[i] > MAX_BRUSH_SIZE)
00680                     break;  // dragged backwards or fucked up
00681             if (i != 3)
00682                 break;
00683             if (b->patchBrush)
00684             {
00685                 VectorCopy(b->maxs, vTemp2);
00686                 VectorSubtract(vTemp2, b->mins, vTemp2);
00687                 VectorSubtract(vTemp2, vTemp, vTemp2);
00688                 //if (!Patch_DragScale(b->nPatchID, vTemp2, move))
00689                 if (!Patch_DragScale(b->pPatch, vTemp2, move))
00690                 {
00691                     b = NULL;
00692                     break;
00693                 }
00694             }
00695 
00696             if (b->terrainBrush)
00697             {
00698                 VectorCopy(b->maxs, vTemp2);
00699                 VectorSubtract(vTemp2, b->mins, vTemp2);
00700                 VectorSubtract(vTemp2, vTemp, vTemp2);
00701                 if (!Terrain_DragScale(b->pTerrain, vTemp2, move))
00702                 {
00703                     b = NULL;
00704                     break;
00705                 }
00706             }
00707         }
00708         // if any of the brushes were crushed out of existance
00709         // calcel the entire move
00710         if (b != &selected_brushes)
00711         {
00712             Sys_Printf ("Brush dragged backwards, move canceled\n");
00713             for (i=0 ; i<g_qeglobals.d_num_move_points ; i++)
00714                 VectorSubtract (g_qeglobals.d_move_points[i], move, g_qeglobals.d_move_points[i]);
00715 
00716             for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
00717                 Brush_Build( b );
00718         }
00719 
00720     }
00721     else
00722     {
00723         // reset face originals from vertex edit mode
00724         // this is dirty, but unfortunately necessary because Brush_Build
00725         // can remove windings
00726         for (b = selected_brushes.next; b != &selected_brushes; b = b->next)
00727         {
00728             Brush_ResetFaceOriginals(b);
00729         }
00730         //
00731         // if there are lots of brushes selected, just translate instead
00732         // of rebuilding the brushes
00733         //
00734         if (drag_yvec[2] == 0 && selected_brushes.next->next != &selected_brushes)
00735         {
00736             Select_Move (move);
00737             //VectorAdd (g_qeglobals.d_select_translate, move, g_qeglobals.d_select_translate);
00738         }
00739         else
00740         {
00741             Select_Move (move);
00742         }
00743     }
00744 }
00745 
00746 /*
00747 ===========
00748 Drag_MouseMoved
00749 ===========
00750 */
00751 void Drag_MouseMoved (int x, int y, int buttons)
00752 {
00753     vec3_t  move, delta;
00754     int     i;
00755 
00756     if (!buttons)
00757     {
00758         drag_ok = false;
00759         return;
00760     }
00761     if (!drag_ok)
00762         return;
00763 
00764     // clear along one axis
00765     if (buttons & MK_SHIFT)
00766     {
00767         drag_first = false;
00768         if (abs(x-pressx) > abs(y-pressy))
00769             y = pressy;
00770         else
00771             x = pressx;
00772     }
00773 
00774 
00775     for (i=0 ; i<3 ; i++)
00776     {
00777         move[i] = drag_xvec[i]*(x - pressx) + drag_yvec[i]*(y - pressy);
00778     if (!g_PrefsDlg.m_bNoClamp)
00779     {
00780           move[i] = floor(move[i]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
00781     }
00782     }
00783 
00784     VectorSubtract (move, pressdelta, delta);
00785     VectorCopy (move, pressdelta);
00786 
00787   MoveSelection (delta);
00788 
00789 }
00790 
00791 /*
00792 ===========
00793 Drag_MouseUp
00794 ===========
00795 */
00796 void Drag_MouseUp (int nButtons)
00797 {
00798     Sys_Status ("drag completed.", 0);
00799 
00800     if (g_qeglobals.d_select_mode == sel_area)
00801     {
00802         if ( OnlyTerrainSelected() )
00803             {
00804             Terrain_SelectAreaPoints();
00805             g_qeglobals.d_select_mode = sel_terrainpoint;
00806             Sys_UpdateWindows (W_ALL);
00807         }
00808         else
00809         {
00810             Patch_SelectAreaPoints();
00811             g_qeglobals.d_select_mode = sel_curvepoint;
00812             Sys_UpdateWindows (W_ALL);
00813         }
00814     }
00815     
00816     if (g_qeglobals.d_select_translate[0] || g_qeglobals.d_select_translate[1] || g_qeglobals.d_select_translate[2])
00817     {
00818         Select_Move (g_qeglobals.d_select_translate);
00819         VectorCopy (vec3_origin, g_qeglobals.d_select_translate);
00820         Sys_UpdateWindows (W_CAMERA);
00821     }
00822   
00823     g_pParentWnd->SetStatusText(3, "");
00824 
00825     //
00826     Undo_EndBrushList(&selected_brushes);
00827     Undo_End();
00828 }

Generated on Thu Aug 25 12:38:28 2005 for Quake III Arena by  doxygen 1.3.9.1