-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
-*/\r
-\r
-#include "stdafx.h"\r
-//#include "qe3.h"\r
-\r
-/*\r
-\r
- drag either multiple brushes, or select plane points from\r
- a single brush.\r
-\r
-*/\r
-\r
-extern int g_nPatchClickedView;\r
-\r
-qboolean drag_ok;\r
-vec3_t drag_xvec;\r
-vec3_t drag_yvec;\r
-\r
-//static int buttonstate;\r
-int pressx, pressy;\r
-static vec3_t pressdelta;\r
-static vec3_t vPressStart;\r
-//static int buttonx, buttony;\r
-\r
-\r
-//int num_move_points;\r
-//float *move_points[1024];\r
-\r
-int lastx, lasty;\r
-\r
-qboolean drag_first;\r
-\r
-\r
-void AxializeVector (vec3_t v)\r
-{\r
- vec3_t a;\r
- float o;\r
- int i;\r
-\r
- if (!v[0] && !v[1])\r
- return;\r
- if (!v[1] && !v[2])\r
- return;\r
- if (!v[0] && !v[2])\r
- return;\r
-\r
- for (i=0 ; i<3 ; i++)\r
- a[i] = fabs(v[i]);\r
- if (a[0] > a[1] && a[0] > a[2])\r
- i = 0;\r
- else if (a[1] > a[0] && a[1] > a[2])\r
- i = 1;\r
- else\r
- i = 2;\r
-\r
- o = v[i];\r
- VectorCopy (vec3_origin, v);\r
- if (o<0)\r
- v[i] = -1;\r
- else\r
- v[i] = 1;\r
- \r
-}\r
-\r
-/*\r
-===========\r
-Drag_Setup\r
-===========\r
-*/\r
-extern void SelectCurvePointByRay (vec3_t org, vec3_t dir, int buttons);\r
-\r
-void Drag_Setup (int x, int y, int buttons,\r
- vec3_t xaxis, vec3_t yaxis,\r
- vec3_t origin, vec3_t dir)\r
-{\r
- trace_t t;\r
- face_t *f;\r
-\r
- drag_first = true;\r
- \r
- VectorCopy (vec3_origin, pressdelta);\r
- pressx = x;\r
- pressy = y;\r
-\r
- // snap to nearest axis for camwindow drags\r
- VectorCopy (xaxis, drag_xvec);\r
- AxializeVector (drag_xvec);\r
- VectorCopy (yaxis, drag_yvec);\r
- AxializeVector (drag_yvec);\r
-\r
- if (g_qeglobals.d_select_mode == sel_curvepoint)\r
- {\r
- SelectCurvePointByRay (origin, dir, buttons); \r
-\r
- if(g_qeglobals.d_select_mode == sel_area)\r
- {\r
- drag_ok = true;\r
-\r
- if(g_nPatchClickedView == W_CAMERA ) {\r
- VectorSet( g_qeglobals.d_vAreaTL, x, y, 0 );\r
- VectorSet( g_qeglobals.d_vAreaBR, x, y, 0 );\r
- }\r
- }\r
- else if (g_qeglobals.d_num_move_points) // don't add an undo if there are no points selected\r
- {\r
- drag_ok = true;\r
- Sys_UpdateWindows(W_ALL);\r
- Undo_Start("drag curve point");\r
- Undo_AddBrushList(&selected_brushes);\r
- }\r
- return;\r
- }\r
- else\r
- {\r
- g_qeglobals.d_num_move_points = 0;\r
- }\r
-\r
- if (g_qeglobals.d_select_mode == sel_areatall)\r
- {\r
- VectorCopy(origin, g_qeglobals.d_vAreaTL);\r
- VectorCopy(origin, g_qeglobals.d_vAreaBR);\r
-\r
- Sys_UpdateWindows(W_ALL);\r
-\r
- drag_ok = true; \r
- return;\r
- }\r
-\r
- if (selected_brushes.next == &selected_brushes)\r
- {\r
- //in this case a new brush is created when the dragging\r
- //takes place in the XYWnd, An useless undo is created\r
- //when the dragging takes place in the CamWnd\r
- Undo_Start("create brush");\r
-\r
- Sys_Status("No selection to drag", 0);\r
- return;\r
- }\r
-\r
- if (g_qeglobals.d_select_mode == sel_vertex)\r
- {\r
- SelectVertexByRay (origin, dir); \r
- if (g_qeglobals.d_num_move_points)\r
- {\r
- drag_ok = true;\r
- Undo_Start("drag vertex");\r
- Undo_AddBrushList(&selected_brushes);\r
- // Need an update here for highlighting selected vertices\r
- Sys_UpdateWindows(W_XY | W_CAMERA);\r
- return;\r
- }\r
- }\r
-\r
- if (g_qeglobals.d_select_mode == sel_edge)\r
- {\r
- SelectEdgeByRay (origin, dir); \r
- if (g_qeglobals.d_num_move_points)\r
- {\r
- drag_ok = true;\r
- Undo_Start("drag edge");\r
- Undo_AddBrushList(&selected_brushes);\r
- return;\r
- }\r
- }\r
-\r
- //\r
- // check for direct hit first\r
- //\r
- t = Test_Ray (origin, dir, true);\r
- if (t.selected)\r
- {\r
- drag_ok = true;\r
-\r
- Undo_Start("drag selection");\r
- Undo_AddBrushList(&selected_brushes);\r
-\r
- if (buttons == (MK_LBUTTON|MK_CONTROL) )\r
- {\r
- Sys_Printf ("Shear dragging face\n");\r
- Brush_SelectFaceForDragging (t.brush, t.face, true);\r
- }\r
- else if (buttons == (MK_LBUTTON|MK_CONTROL|MK_SHIFT) )\r
- {\r
- Sys_Printf ("Sticky dragging brush\n");\r
- for (f=t.brush->brush_faces ; f ; f=f->next)\r
- Brush_SelectFaceForDragging (t.brush, f, false);\r
- }\r
- else\r
- Sys_Printf ("Dragging entire selection\n");\r
- \r
- return;\r
- }\r
-\r
- if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_edge)\r
- return;\r
-\r
- //\r
- // check for side hit\r
- //\r
- // multiple brushes selected?\r
- if (selected_brushes.next->next != &selected_brushes)\r
- {\r
- // yes, special handling\r
- bool bOK = (g_PrefsDlg.m_bALTEdge) ? Sys_AltDown() : true;\r
- if (bOK)\r
- {\r
- for (brush_t* pBrush = selected_brushes.next ; pBrush != &selected_brushes ; pBrush = pBrush->next)\r
- {\r
- if (buttons & MK_CONTROL)\r
- Brush_SideSelect (pBrush, origin, dir, true);\r
- else\r
- Brush_SideSelect (pBrush, origin, dir, false);\r
- }\r
- }\r
- else\r
- {\r
- Sys_Printf ("press ALT to drag multiple edges\n");\r
- return;\r
- }\r
- }\r
- else\r
- {\r
- // single select.. trying to drag fixed entities handle themselves and just move\r
- if (buttons & MK_CONTROL)\r
- Brush_SideSelect (selected_brushes.next, origin, dir, true);\r
- else\r
- Brush_SideSelect (selected_brushes.next, origin, dir, false);\r
- }\r
-\r
- Sys_Printf ("Side stretch\n");\r
- drag_ok = true;\r
-\r
- Undo_Start("side stretch");\r
- Undo_AddBrushList(&selected_brushes);\r
-}\r
-\r
-entity_t *peLink;\r
-\r
-void UpdateTarget(vec3_t origin, vec3_t dir)\r
-{\r
- trace_t t;\r
- entity_t *pe;\r
- int i;\r
- char sz[128];\r
-\r
- t = Test_Ray (origin, dir, 0);\r
-\r
- if (!t.brush)\r
- return;\r
-\r
- pe = t.brush->owner;\r
-\r
- if (pe == NULL)\r
- return;\r
-\r
- // is this the first?\r
- if (peLink != NULL)\r
- {\r
-\r
- // Get the target id from out current target\r
- // if there is no id, make one\r
-\r
- i = IntForKey(pe, "target");\r
- if (i <= 0)\r
- {\r
- i = GetUniqueTargetId(1);\r
- sprintf(sz, "%d", i);\r
-\r
- SetKeyValue(pe, "target", sz);\r
- }\r
-\r
- // set the target # into our src\r
-\r
- sprintf(sz, "%d", i);\r
- SetKeyValue(peLink, "targetname", sz);\r
-\r
- Sys_UpdateWindows(W_ENTITY);\r
-\r
- }\r
-\r
- // promote the target to the src\r
-\r
- peLink = pe;\r
- \r
-}\r
-\r
-/*\r
-===========\r
-Drag_Begin\r
-//++timo test three button mouse and three button emulation here ?\r
-===========\r
-*/\r
-void Drag_Begin (int x, int y, int buttons,\r
- vec3_t xaxis, vec3_t yaxis,\r
- vec3_t origin, vec3_t dir, bool sf_camera)\r
-{\r
- trace_t t;\r
- bool altdown;\r
- int nFlag;\r
-\r
- drag_ok = false;\r
- VectorCopy (vec3_origin, pressdelta);\r
- VectorCopy (vec3_origin, vPressStart);\r
-\r
- drag_first = true;\r
- peLink = NULL;\r
-\r
- altdown = Sys_AltDown();\r
-\r
- // shift-LBUTTON = select entire brush\r
- // shift-alt-LBUTTON = drill select\r
- if (buttons == (MK_LBUTTON | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint)\r
- {\r
- nFlag = altdown ? SF_CYCLE : 0;\r
- if (sf_camera)\r
- nFlag |= SF_CAMERA;\r
- else\r
- nFlag |= SF_ENTITIES_FIRST;\r
- Select_Ray(origin, dir, nFlag);\r
- return;\r
- }\r
-\r
- // (shift-)alt-LBUTTON = area select completely tall\r
- if ( !sf_camera &&\r
- ( g_PrefsDlg.m_bALTEdge ? buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT) : (buttons == MK_LBUTTON || buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) ) &&\r
- altdown && g_qeglobals.d_select_mode != sel_curvepoint)\r
- {\r
- if (g_pParentWnd->ActiveXY()->AreaSelectOK())\r
- {\r
- g_qeglobals.d_select_mode = sel_areatall;\r
-\r
- Drag_Setup (x, y, buttons, xaxis, yaxis, origin, dir);\r
- return;\r
- }\r
- }\r
-\r
- // ctrl-alt-LBUTTON = multiple brush select without selecting whole entities\r
- if (buttons == (MK_LBUTTON | MK_CONTROL) && altdown && g_qeglobals.d_select_mode != sel_curvepoint)\r
- {\r
- nFlag = 0;\r
- if (sf_camera)\r
- nFlag |= SF_CAMERA;\r
- else\r
- nFlag |= SF_ENTITIES_FIRST;\r
- Select_Ray (origin, dir, nFlag);\r
- UpdateSurfaceDialog();\r
- \r
- return;\r
- }\r
-\r
- // ctrl-shift LBUTTON = select single face\r
- if (sf_camera && buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint)\r
- {\r
- if(Sys_AltDown())\r
- {\r
- brush_t *b;\r
- for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)\r
- {\r
- if(b->pPatch)\r
- continue;\r
-\r
- for (face_t* pFace = b->brush_faces; pFace; pFace = pFace->next)\r
- {\r
- g_ptrSelectedFaces.Add(pFace);\r
- g_ptrSelectedFaceBrushes.Add(b);\r
- }\r
- }\r
-\r
- for (b = selected_brushes.next; b != &selected_brushes; )\r
- {\r
- brush_t *pb = b;\r
- b = b->next;\r
- Brush_RemoveFromList (pb);\r
- Brush_AddToList (pb, &active_brushes);\r
- }\r
- }\r
- else\r
- Select_Deselect (true);\r
-\r
- Select_Ray (origin, dir, (SF_SINGLEFACE|SF_CAMERA));\r
- return;\r
- }\r
-\r
-\r
- // LBUTTON + all other modifiers = manipulate selection\r
- if (buttons & MK_LBUTTON)\r
- {\r
- Drag_Setup (x, y, buttons, xaxis, yaxis, origin, dir);\r
- return;\r
- }\r
-\r
- int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON;\r
- // middle button = grab texture\r
- if (buttons == nMouseButton)\r
- {\r
- t = Test_Ray (origin, dir, false);\r
- if (t.face)\r
- {\r
- UpdateWorkzone_ForBrush( t.brush );\r
- // use a local brushprimit_texdef fitted to a default 2x2 texture\r
- brushprimit_texdef_t bp_local;\r
- ConvertTexMatWithQTexture( &t.face->brushprimit_texdef, t.face->d_texture, &bp_local, NULL );\r
- Texture_SetTexture ( &t.face->texdef, &bp_local, false, NULL);\r
- UpdateSurfaceDialog();\r
- UpdatePatchInspector();\r
- }\r
- else\r
- Sys_Printf ("Did not select a texture\n");\r
- return;\r
- }\r
-\r
- // ctrl-middle button = set entire brush to texture\r
- if (buttons == (nMouseButton|MK_CONTROL) )\r
- {\r
- t = Test_Ray (origin, dir, false);\r
- if (t.brush)\r
- {\r
- if (t.brush->brush_faces->texdef.GetName()[0] == '(')\r
- Sys_Printf ("Can't change an entity texture\n");\r
- else\r
- {\r
- Brush_SetTexture (t.brush, &g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, false, static_cast<IPluginTexdef *>( g_qeglobals.d_texturewin.pTexdef ) );\r
- Sys_UpdateWindows (W_ALL);\r
- }\r
- }\r
- else\r
- Sys_Printf ("Didn't hit a btrush\n");\r
- return;\r
- }\r
-\r
- // ctrl-shift-middle button = set single face to texture\r
- if (buttons == (nMouseButton|MK_SHIFT|MK_CONTROL) )\r
- {\r
- t = Test_Ray (origin, dir, false);\r
- if (t.brush)\r
- {\r
- if (t.brush->brush_faces->texdef.GetName()[0] == '(')\r
- Sys_Printf ("Can't change an entity texture\n");\r
- else\r
- {\r
- SetFaceTexdef (t.face, &g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef);\r
- Brush_Build( t.brush );\r
-\r
- Sys_UpdateWindows (W_ALL);\r
- }\r
- }\r
- else\r
- Sys_Printf ("Didn't hit a btrush\n");\r
- return;\r
- }\r
-\r
- if (buttons == (nMouseButton | MK_SHIFT))\r
- {\r
- Sys_Printf("Set brush face texture info\n");\r
- t = Test_Ray (origin, dir, false);\r
- if (t.brush)\r
- {\r
- if (t.brush->brush_faces->texdef.GetName()[0] == '(')\r
- {\r
- if (t.brush->owner->eclass->nShowFlags & ECLASS_LIGHT)\r
- {\r
- CString strBuff;\r
- qtexture_t* pTex = g_qeglobals.d_texturewin.pShader->getTexture();\r
- if (pTex)\r
- {\r
- vec3_t vColor;\r
- VectorCopy(pTex->color, vColor);\r
-\r
- float fLargest = 0.0f;\r
- for (int i = 0; i < 3; i++)\r
- {\r
- if (vColor[i] > fLargest)\r
- fLargest = vColor[i];\r
- }\r
- \r
- if (fLargest == 0.0f)\r
- {\r
- vColor[0] = vColor[1] = vColor[2] = 1.0f;\r
- }\r
- else\r
- {\r
- float fScale = 1.0f / fLargest;\r
- for (int i = 0; i < 3; i++)\r
- {\r
- vColor[i] *= fScale;\r
- }\r
- }\r
- strBuff.Format("%f %f %f",pTex->color[0], pTex->color[1], pTex->color[2]);\r
- SetKeyValue(t.brush->owner, "_color", strBuff.GetBuffer());\r
- Sys_UpdateWindows (W_ALL);\r
- }\r
- }\r
- else\r
- {\r
- Sys_Printf ("Can't select an entity brush face\n");\r
- }\r
- }\r
- else\r
- {\r
- // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=425\r
- Face_SetShader(t.face, g_qeglobals.d_texturewin.texdef.GetName());\r
- Brush_Build(t.brush);\r
-\r
- Sys_UpdateWindows (W_ALL);\r
- }\r
- }\r
- else\r
- Sys_Printf ("Didn't hit a brush\n");\r
- return;\r
- }\r
-\r
-}\r
-\r
-\r
-//\r
-//===========\r
-//MoveSelection\r
-//===========\r
-//\r
-void MoveSelection (vec3_t move)\r
-{\r
- int i, success;\r
- brush_t *b;\r
- CString strStatus;\r
- vec3_t vTemp, vTemp2, end;\r
-\r
- if (!move[0] && !move[1] && !move[2])\r
- {\r
- return;\r
- }\r
-\r
- if (!(g_qeglobals.d_select_mode == sel_area || g_qeglobals.d_select_mode == sel_areatall))\r
- {\r
- move[0] = (g_nScaleHow & SCALE_X) ? 0 : move[0];\r
- move[1] = (g_nScaleHow & SCALE_Y) ? 0 : move[1];\r
- move[2] = (g_nScaleHow & SCALE_Z) ? 0 : move[2];\r
- }\r
-\r
- if (g_pParentWnd->ActiveXY()->RotateMode() || g_bPatchBendMode)\r
- {\r
- float fDeg = -move[2];\r
- float fAdj = move[2];\r
- int nAxis = 0;\r
- if (g_pParentWnd->ActiveXY()->GetViewType() == XY)\r
- {\r
- fDeg = -move[1];\r
- fAdj = move[1];\r
- nAxis = 2;\r
- }\r
- else \r
- if (g_pParentWnd->ActiveXY()->GetViewType() == XZ)\r
- {\r
- fDeg = move[2];\r
- fAdj = move[2];\r
- nAxis = 1;\r
- }\r
- else\r
- nAxis = 0;\r
-\r
- g_pParentWnd->ActiveXY()->Rotation()[nAxis] += fAdj;\r
- 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]);\r
- g_pParentWnd->SetStatusText(2, strStatus);\r
-\r
- if (g_bPatchBendMode)\r
- {\r
- Patch_SelectBendNormal();\r
- Select_RotateAxis(nAxis, fDeg*2, false, true);\r
- Patch_SelectBendAxis();\r
- Select_RotateAxis(nAxis, fDeg, false, true);\r
- }\r
- else\r
- {\r
- Select_RotateAxis(nAxis, fDeg, false, true);\r
- }\r
- return;\r
- }\r
-\r
- if (g_pParentWnd->ActiveXY()->ScaleMode())\r
- {\r
- vec3_t v;\r
- v[0] = v[1] = v[2] = 1.0f;\r
- if (move[1] > 0)\r
- {\r
- v[0] = 1.1f;\r
- v[1] = 1.1f;\r
- v[2] = 1.1f;\r
- }\r
- else \r
- if (move[1] < 0)\r
- {\r
- v[0] = 0.9f;\r
- v[1] = 0.9f;\r
- v[2] = 0.9f;\r
- }\r
-\r
- Select_Scale((g_nScaleHow & SCALE_X) ? 1.0f : v[0],\r
- (g_nScaleHow & SCALE_Y) ? 1.0f : v[1],\r
- (g_nScaleHow & SCALE_Z) ? 1.0f : v[2]);\r
- // is that really necessary???\r
- Sys_UpdateWindows (W_ALL);\r
- return;\r
- }\r
-\r
-\r
- vec3_t vDistance;\r
- VectorSubtract(pressdelta, vPressStart, vDistance);\r
- strStatus.Format("Distance x: %.1f y: %.1f z: %.1f", vDistance[0], vDistance[1], vDistance[2]);\r
- g_pParentWnd->SetStatusText(3, strStatus);\r
-\r
- //\r
- // dragging only a part of the selection\r
- //\r
-\r
- // this is fairly crappy way to deal with curvepoint and area selection\r
- // but it touches the smallest amount of code this way\r
- // \r
- if (g_qeglobals.d_num_move_points || g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_area || g_qeglobals.d_select_mode == sel_areatall)\r
- {\r
- //area selection\r
- if (g_qeglobals.d_select_mode == sel_area || g_qeglobals.d_select_mode == sel_areatall)\r
- {\r
- VectorAdd(g_qeglobals.d_vAreaBR, move, g_qeglobals.d_vAreaBR);\r
- return;\r
- }\r
- //curve point selection\r
- if (g_qeglobals.d_select_mode == sel_curvepoint)\r
- {\r
- Patch_UpdateSelected(move);\r
- return;\r
- }\r
- //vertex selection\r
- if (g_qeglobals.d_select_mode == sel_vertex && g_PrefsDlg.m_bVertexSplit)\r
- {\r
- if(g_qeglobals.d_num_move_points) {\r
- success = true;\r
- for (b = selected_brushes.next; b != &selected_brushes; b = b->next)\r
- {\r
- success &= Brush_MoveVertex(b, g_qeglobals.d_move_points[0], move, end, true);\r
- }\r
- if (success)\r
- VectorCopy(end, g_qeglobals.d_move_points[0]);\r
- }\r
- return;\r
- }\r
- //all other selection types\r
- for (i=0 ; i<g_qeglobals.d_num_move_points ; i++)\r
- VectorAdd (g_qeglobals.d_move_points[i], move, g_qeglobals.d_move_points[i]);\r
- for (b = selected_brushes.next; b != &selected_brushes; b = b->next)\r
- {\r
- bool bMoved = false;\r
- for(face_t *f = b->brush_faces; !bMoved && f!=NULL; f=f->next)\r
- for(int p=0; !bMoved && p<3; p++)\r
- for (i=0 ; !bMoved && i<g_qeglobals.d_num_move_points ; i++)\r
- if(f->planepts[p] == g_qeglobals.d_move_points[i])\r
- bMoved = true;\r
- if(!bMoved) continue;\r
-\r
- VectorCopy(b->maxs, vTemp);\r
- VectorSubtract(vTemp, b->mins, vTemp);\r
- Brush_Build(b,true,true,false,false); // don't filter\r
- for (i=0 ; i<3 ; i++)\r
- {\r
- if (b->mins[i] > b->maxs[i]\r
- || b->maxs[i] - b->mins[i] > g_MaxBrushSize)\r
- break; // dragged backwards or fucked up\r
- }\r
- if (i != 3)\r
- break;\r
- if (b->patchBrush)\r
- {\r
- VectorCopy(b->maxs, vTemp2);\r
- VectorSubtract(vTemp2, b->mins, vTemp2);\r
- VectorSubtract(vTemp2, vTemp, vTemp2);\r
- //if (!Patch_DragScale(b->nPatchID, vTemp2, move))\r
- if (!Patch_DragScale(b->pPatch, vTemp2, move))\r
- {\r
- b = NULL;\r
- break;\r
- }\r
- }\r
- }\r
- // if any of the brushes were crushed out of existance\r
- // calcel the entire move\r
- if (b != &selected_brushes)\r
- {\r
- Sys_Printf ("Brush dragged backwards, move canceled\n");\r
- for (i=0 ; i<g_qeglobals.d_num_move_points ; i++)\r
- VectorSubtract (g_qeglobals.d_move_points[i], move, g_qeglobals.d_move_points[i]);\r
-\r
- for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)\r
- Brush_Build(b,true,true,false,false); // don't filter\r
- }\r
-\r
- }\r
- else\r
- {\r
- // reset face originals from vertex edit mode\r
- // this is dirty, but unfortunately necessary because Brush_Build\r
- // can remove windings\r
- for (b = selected_brushes.next; b != &selected_brushes; b = b->next)\r
- {\r
- Brush_ResetFaceOriginals(b);\r
- }\r
- //\r
- // if there are lots of brushes selected, just translate instead\r
- // of rebuilding the brushes\r
- // NOTE: this is not actually done, but would be a good idea\r
- //\r
- Select_Move (move);\r
- }\r
-}\r
-\r
-/*\r
-===========\r
-Drag_MouseMoved\r
-===========\r
-*/\r
-void Drag_MouseMoved (int x, int y, int buttons)\r
-{\r
- vec3_t move, delta;\r
- int i;\r
-\r
- if (!buttons)\r
- {\r
- drag_ok = false;\r
- return;\r
- }\r
- if (!drag_ok)\r
- return;\r
-\r
- // clear along one axis\r
- if (buttons & MK_SHIFT && (g_PrefsDlg.m_bALTEdge && g_qeglobals.d_select_mode != sel_areatall))\r
- {\r
- drag_first = false;\r
- if (abs(x-pressx) > abs(y-pressy))\r
- y = pressy;\r
- else\r
- x = pressx;\r
- }\r
-\r
- if (g_qeglobals.d_select_mode == sel_area && g_nPatchClickedView == W_CAMERA)\r
- {\r
- camera_t *m_pCamera = g_pParentWnd->GetCamWnd()->Camera();\r
-\r
- // snap to window\r
- if( y > m_pCamera->height ) y = m_pCamera->height - 1; else if( y < 0 ) y = 0;\r
- if( x > m_pCamera->width ) x = m_pCamera->width - 1; else if( x < 0 ) x = 0;\r
-\r
- VectorSet (move, x - pressx, y - pressy, 0);\r
- } else\r
- {\r
- for (i=0 ; i<3 ; i++)\r
- {\r
- move[i] = drag_xvec[i]*(x - pressx) + drag_yvec[i]*(y - pressy);\r
- if (!g_PrefsDlg.m_bNoClamp)\r
- {\r
- move[i] = floor(move[i]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;\r
- }\r
- }\r
- }\r
-\r
- VectorSubtract (move, pressdelta, delta);\r
- VectorCopy (move, pressdelta);\r
-\r
- MoveSelection (delta);\r
-}\r
-\r
-/*\r
-===========\r
-Drag_MouseUp\r
-===========\r
-*/\r
-void Drag_MouseUp (int nButtons)\r
-{\r
- Sys_Status ("Drag completed.", 0);\r
-\r
- if (g_qeglobals.d_select_mode == sel_area)\r
- {\r
- Patch_SelectAreaPoints(nButtons & MK_CONTROL); // adds to selection and/or deselects selected points if ctrl is held\r
- g_qeglobals.d_select_mode = sel_curvepoint;\r
- Sys_UpdateWindows (W_ALL);\r
- }\r
-\r
- if (g_qeglobals.d_select_mode == sel_areatall)\r
- {\r
- vec3_t mins, maxs;\r
-\r
- int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0;\r
- int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2;\r
-\r
- // get our rectangle\r
- mins[nDim1] = MIN( g_qeglobals.d_vAreaTL[nDim1], g_qeglobals.d_vAreaBR[nDim1] );\r
- mins[nDim2] = MIN( g_qeglobals.d_vAreaTL[nDim2], g_qeglobals.d_vAreaBR[nDim2] );\r
- maxs[nDim1] = MAX( g_qeglobals.d_vAreaTL[nDim1], g_qeglobals.d_vAreaBR[nDim1] );\r
- maxs[nDim2] = MAX( g_qeglobals.d_vAreaTL[nDim2], g_qeglobals.d_vAreaBR[nDim2] );\r
-\r
- // deselect current selection\r
- if( !(nButtons & (MK_CONTROL|MK_SHIFT)) )\r
- Select_Deselect();\r
-\r
- // select new selection\r
- Select_RealCompleteTall( mins, maxs );\r
-\r
- Sys_UpdateWindows (W_ALL);\r
- }\r
-\r
- if (g_qeglobals.d_select_translate[0] || g_qeglobals.d_select_translate[1] || g_qeglobals.d_select_translate[2])\r
- {\r
- Select_Move (g_qeglobals.d_select_translate);\r
- VectorCopy (vec3_origin, g_qeglobals.d_select_translate);\r
- Sys_UpdateWindows (W_CAMERA);\r
- }\r
- \r
- /* note: added cleanup here, since an edge drag will leave selected vertices \r
- in g_qeglobals.d_num_move_points\r
- */\r
- if ( g_qeglobals.d_select_mode != sel_vertex && \r
- g_qeglobals.d_select_mode != sel_curvepoint &&\r
- g_qeglobals.d_select_mode != sel_edge)\r
- g_qeglobals.d_num_move_points = 0;\r
- \r
- g_pParentWnd->SetStatusText(3, "");\r
- Undo_EndBrushList(&selected_brushes);\r
- Undo_End();\r
- UpdateSurfaceDialog();\r
-}\r
+/*
+Copyright (C) 1999-2007 id Software, Inc. and contributors.
+For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+This file is part of GtkRadiant.
+
+GtkRadiant is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GtkRadiant is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GtkRadiant; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "stdafx.h"
+//#include "qe3.h"
+
+/*
+
+ drag either multiple brushes, or select plane points from
+ a single brush.
+
+*/
+
+extern int g_nPatchClickedView;
+
+qboolean drag_ok;
+vec3_t drag_xvec;
+vec3_t drag_yvec;
+
+//static int buttonstate;
+int pressx, pressy;
+static vec3_t pressdelta;
+static vec3_t vPressStart;
+//static int buttonx, buttony;
+
+
+//int num_move_points;
+//float *move_points[1024];
+
+int lastx, lasty;
+
+qboolean drag_first;
+
+
+void AxializeVector (vec3_t v)
+{
+ vec3_t a;
+ float o;
+ int i;
+
+ if (!v[0] && !v[1])
+ return;
+ if (!v[1] && !v[2])
+ return;
+ if (!v[0] && !v[2])
+ return;
+
+ for (i=0 ; i<3 ; i++)
+ a[i] = fabs(v[i]);
+ if (a[0] > a[1] && a[0] > a[2])
+ i = 0;
+ else if (a[1] > a[0] && a[1] > a[2])
+ i = 1;
+ else
+ i = 2;
+
+ o = v[i];
+ VectorCopy (vec3_origin, v);
+ if (o<0)
+ v[i] = -1;
+ else
+ v[i] = 1;
+
+}
+
+/*
+===========
+Drag_Setup
+===========
+*/
+extern void SelectCurvePointByRay (vec3_t org, vec3_t dir, int buttons);
+
+void Drag_Setup (int x, int y, int buttons,
+ vec3_t xaxis, vec3_t yaxis,
+ vec3_t origin, vec3_t dir)
+{
+ trace_t t;
+ face_t *f;
+
+ drag_first = true;
+
+ VectorCopy (vec3_origin, pressdelta);
+ pressx = x;
+ pressy = y;
+
+ // snap to nearest axis for camwindow drags
+ VectorCopy (xaxis, drag_xvec);
+ AxializeVector (drag_xvec);
+ VectorCopy (yaxis, drag_yvec);
+ AxializeVector (drag_yvec);
+
+ if (g_qeglobals.d_select_mode == sel_curvepoint)
+ {
+ SelectCurvePointByRay (origin, dir, buttons);
+
+ if(g_qeglobals.d_select_mode == sel_area)
+ {
+ drag_ok = true;
+
+ if(g_nPatchClickedView == W_CAMERA ) {
+ VectorSet( g_qeglobals.d_vAreaTL, x, y, 0 );
+ VectorSet( g_qeglobals.d_vAreaBR, x, y, 0 );
+ }
+ }
+ else if (g_qeglobals.d_num_move_points) // don't add an undo if there are no points selected
+ {
+ drag_ok = true;
+ Sys_UpdateWindows(W_ALL);
+ Undo_Start("drag curve point");
+ Undo_AddBrushList(&selected_brushes);
+ }
+ return;
+ }
+ else
+ {
+ g_qeglobals.d_num_move_points = 0;
+ }
+
+ if (g_qeglobals.d_select_mode == sel_areatall)
+ {
+ VectorCopy(origin, g_qeglobals.d_vAreaTL);
+ VectorCopy(origin, g_qeglobals.d_vAreaBR);
+
+ Sys_UpdateWindows(W_ALL);
+
+ drag_ok = true;
+ return;
+ }
+
+ if (selected_brushes.next == &selected_brushes)
+ {
+ //in this case a new brush is created when the dragging
+ //takes place in the XYWnd, An useless undo is created
+ //when the dragging takes place in the CamWnd
+ Undo_Start("create brush");
+
+ Sys_Status("No selection to drag", 0);
+ return;
+ }
+
+ if (g_qeglobals.d_select_mode == sel_vertex)
+ {
+ SelectVertexByRay (origin, dir);
+ if (g_qeglobals.d_num_move_points)
+ {
+ drag_ok = true;
+ Undo_Start("drag vertex");
+ Undo_AddBrushList(&selected_brushes);
+ // Need an update here for highlighting selected vertices
+ Sys_UpdateWindows(W_XY | W_CAMERA);
+ return;
+ }
+ }
+
+ if (g_qeglobals.d_select_mode == sel_edge)
+ {
+ SelectEdgeByRay (origin, dir);
+ if (g_qeglobals.d_num_move_points)
+ {
+ drag_ok = true;
+ Undo_Start("drag edge");
+ Undo_AddBrushList(&selected_brushes);
+ return;
+ }
+ }
+
+ //
+ // check for direct hit first
+ //
+ t = Test_Ray (origin, dir, true);
+ if (t.selected)
+ {
+ drag_ok = true;
+
+ Undo_Start("drag selection");
+ Undo_AddBrushList(&selected_brushes);
+
+ if (buttons == (MK_LBUTTON|MK_CONTROL) )
+ {
+ Sys_Printf ("Shear dragging face\n");
+ Brush_SelectFaceForDragging (t.brush, t.face, true);
+ }
+ else if (buttons == (MK_LBUTTON|MK_CONTROL|MK_SHIFT) )
+ {
+ Sys_Printf ("Sticky dragging brush\n");
+ for (f=t.brush->brush_faces ; f ; f=f->next)
+ Brush_SelectFaceForDragging (t.brush, f, false);
+ }
+ else
+ Sys_Printf ("Dragging entire selection\n");
+
+ return;
+ }
+
+ if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_edge)
+ return;
+
+ //
+ // check for side hit
+ //
+ // multiple brushes selected?
+ if (selected_brushes.next->next != &selected_brushes)
+ {
+ // yes, special handling
+ bool bOK = (g_PrefsDlg.m_bALTEdge) ? Sys_AltDown() : true;
+ if (bOK)
+ {
+ for (brush_t* pBrush = selected_brushes.next ; pBrush != &selected_brushes ; pBrush = pBrush->next)
+ {
+ if (buttons & MK_CONTROL)
+ Brush_SideSelect (pBrush, origin, dir, true);
+ else
+ Brush_SideSelect (pBrush, origin, dir, false);
+ }
+ }
+ else
+ {
+ Sys_Printf ("press ALT to drag multiple edges\n");
+ return;
+ }
+ }
+ else
+ {
+ // single select.. trying to drag fixed entities handle themselves and just move
+ if (buttons & MK_CONTROL)
+ Brush_SideSelect (selected_brushes.next, origin, dir, true);
+ else
+ Brush_SideSelect (selected_brushes.next, origin, dir, false);
+ }
+
+ Sys_Printf ("Side stretch\n");
+ drag_ok = true;
+
+ Undo_Start("side stretch");
+ Undo_AddBrushList(&selected_brushes);
+}
+
+entity_t *peLink;
+
+void UpdateTarget(vec3_t origin, vec3_t dir)
+{
+ trace_t t;
+ entity_t *pe;
+ int i;
+ char sz[128];
+
+ t = Test_Ray (origin, dir, 0);
+
+ if (!t.brush)
+ return;
+
+ pe = t.brush->owner;
+
+ if (pe == NULL)
+ return;
+
+ // is this the first?
+ if (peLink != NULL)
+ {
+
+ // Get the target id from out current target
+ // if there is no id, make one
+
+ i = IntForKey(pe, "target");
+ if (i <= 0)
+ {
+ i = GetUniqueTargetId(1);
+ sprintf(sz, "%d", i);
+
+ SetKeyValue(pe, "target", sz);
+ }
+
+ // set the target # into our src
+
+ sprintf(sz, "%d", i);
+ SetKeyValue(peLink, "targetname", sz);
+
+ Sys_UpdateWindows(W_ENTITY);
+
+ }
+
+ // promote the target to the src
+
+ peLink = pe;
+
+}
+
+/*
+===========
+Drag_Begin
+//++timo test three button mouse and three button emulation here ?
+===========
+*/
+void Drag_Begin (int x, int y, int buttons,
+ vec3_t xaxis, vec3_t yaxis,
+ vec3_t origin, vec3_t dir, bool sf_camera)
+{
+ trace_t t;
+ bool altdown;
+ int nFlag;
+
+ drag_ok = false;
+ VectorCopy (vec3_origin, pressdelta);
+ VectorCopy (vec3_origin, vPressStart);
+
+ drag_first = true;
+ peLink = NULL;
+
+ altdown = Sys_AltDown();
+
+ // shift-LBUTTON = select entire brush
+ // shift-alt-LBUTTON = drill select
+ if (buttons == (MK_LBUTTON | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint)
+ {
+ nFlag = altdown ? SF_CYCLE : 0;
+ if (sf_camera)
+ nFlag |= SF_CAMERA;
+ else
+ nFlag |= SF_ENTITIES_FIRST;
+ Select_Ray(origin, dir, nFlag);
+ return;
+ }
+
+ // (shift-)alt-LBUTTON = area select completely tall
+ if ( !sf_camera &&
+ ( g_PrefsDlg.m_bALTEdge ? buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT) : (buttons == MK_LBUTTON || buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) ) &&
+ altdown && g_qeglobals.d_select_mode != sel_curvepoint)
+ {
+ if (g_pParentWnd->ActiveXY()->AreaSelectOK())
+ {
+ g_qeglobals.d_select_mode = sel_areatall;
+
+ Drag_Setup (x, y, buttons, xaxis, yaxis, origin, dir);
+ return;
+ }
+ }
+
+ // ctrl-alt-LBUTTON = multiple brush select without selecting whole entities
+ if (buttons == (MK_LBUTTON | MK_CONTROL) && altdown && g_qeglobals.d_select_mode != sel_curvepoint)
+ {
+ nFlag = 0;
+ if (sf_camera)
+ nFlag |= SF_CAMERA;
+ else
+ nFlag |= SF_ENTITIES_FIRST;
+ Select_Ray (origin, dir, nFlag);
+ UpdateSurfaceDialog();
+
+ return;
+ }
+
+ // ctrl-shift LBUTTON = select single face
+ if (sf_camera && buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint)
+ {
+ if(Sys_AltDown())
+ {
+ brush_t *b;
+ for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
+ {
+ if(b->pPatch)
+ continue;
+
+ for (face_t* pFace = b->brush_faces; pFace; pFace = pFace->next)
+ {
+ g_ptrSelectedFaces.Add(pFace);
+ g_ptrSelectedFaceBrushes.Add(b);
+ }
+ }
+
+ for (b = selected_brushes.next; b != &selected_brushes; )
+ {
+ brush_t *pb = b;
+ b = b->next;
+ Brush_RemoveFromList (pb);
+ Brush_AddToList (pb, &active_brushes);
+ }
+ }
+ else
+ Select_Deselect (true);
+
+ Select_Ray (origin, dir, (SF_SINGLEFACE|SF_CAMERA));
+ return;
+ }
+
+
+ // LBUTTON + all other modifiers = manipulate selection
+ if (buttons & MK_LBUTTON)
+ {
+ Drag_Setup (x, y, buttons, xaxis, yaxis, origin, dir);
+ return;
+ }
+
+ int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON;
+ // middle button = grab texture
+ if (buttons == nMouseButton)
+ {
+ t = Test_Ray (origin, dir, false);
+ if (t.face)
+ {
+ UpdateWorkzone_ForBrush( t.brush );
+ // use a local brushprimit_texdef fitted to a default 2x2 texture
+ brushprimit_texdef_t bp_local;
+ ConvertTexMatWithQTexture( &t.face->brushprimit_texdef, t.face->d_texture, &bp_local, NULL );
+ Texture_SetTexture ( &t.face->texdef, &bp_local, false, NULL);
+ UpdateSurfaceDialog();
+ UpdatePatchInspector();
+ }
+ else
+ Sys_Printf ("Did not select a texture\n");
+ return;
+ }
+
+ // ctrl-middle button = set entire brush to texture
+ if (buttons == (nMouseButton|MK_CONTROL) )
+ {
+ t = Test_Ray (origin, dir, false);
+ if (t.brush)
+ {
+ if (t.brush->brush_faces->texdef.GetName()[0] == '(')
+ Sys_Printf ("Can't change an entity texture\n");
+ else
+ {
+ Brush_SetTexture (t.brush, &g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, false, static_cast<IPluginTexdef *>( g_qeglobals.d_texturewin.pTexdef ) );
+ Sys_UpdateWindows (W_ALL);
+ }
+ }
+ else
+ Sys_Printf ("Didn't hit a btrush\n");
+ return;
+ }
+
+ // ctrl-shift-middle button = set single face to texture
+ if (buttons == (nMouseButton|MK_SHIFT|MK_CONTROL) )
+ {
+ t = Test_Ray (origin, dir, false);
+ if (t.brush)
+ {
+ if (t.brush->brush_faces->texdef.GetName()[0] == '(')
+ Sys_Printf ("Can't change an entity texture\n");
+ else
+ {
+ SetFaceTexdef (t.face, &g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef);
+ Brush_Build( t.brush );
+
+ Sys_UpdateWindows (W_ALL);
+ }
+ }
+ else
+ Sys_Printf ("Didn't hit a btrush\n");
+ return;
+ }
+
+ if (buttons == (nMouseButton | MK_SHIFT))
+ {
+ Sys_Printf("Set brush face texture info\n");
+ t = Test_Ray (origin, dir, false);
+ if (t.brush)
+ {
+ if (t.brush->brush_faces->texdef.GetName()[0] == '(')
+ {
+ if (t.brush->owner->eclass->nShowFlags & ECLASS_LIGHT)
+ {
+ CString strBuff;
+ qtexture_t* pTex = g_qeglobals.d_texturewin.pShader->getTexture();
+ if (pTex)
+ {
+ vec3_t vColor;
+ VectorCopy(pTex->color, vColor);
+
+ float fLargest = 0.0f;
+ for (int i = 0; i < 3; i++)
+ {
+ if (vColor[i] > fLargest)
+ fLargest = vColor[i];
+ }
+
+ if (fLargest == 0.0f)
+ {
+ vColor[0] = vColor[1] = vColor[2] = 1.0f;
+ }
+ else
+ {
+ float fScale = 1.0f / fLargest;
+ for (int i = 0; i < 3; i++)
+ {
+ vColor[i] *= fScale;
+ }
+ }
+ strBuff.Format("%f %f %f",pTex->color[0], pTex->color[1], pTex->color[2]);
+ SetKeyValue(t.brush->owner, "_color", strBuff.GetBuffer());
+ Sys_UpdateWindows (W_ALL);
+ }
+ }
+ else
+ {
+ Sys_Printf ("Can't select an entity brush face\n");
+ }
+ }
+ else
+ {
+ // http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=425
+ Face_SetShader(t.face, g_qeglobals.d_texturewin.texdef.GetName());
+ Brush_Build(t.brush);
+
+ Sys_UpdateWindows (W_ALL);
+ }
+ }
+ else
+ Sys_Printf ("Didn't hit a brush\n");
+ return;
+ }
+
+}
+
+
+//
+//===========
+//MoveSelection
+//===========
+//
+void MoveSelection (vec3_t move)
+{
+ int i, success;
+ brush_t *b;
+ CString strStatus;
+ vec3_t vTemp, vTemp2, end;
+
+ if (!move[0] && !move[1] && !move[2])
+ {
+ return;
+ }
+
+ if (!(g_qeglobals.d_select_mode == sel_area || g_qeglobals.d_select_mode == sel_areatall))
+ {
+ move[0] = (g_nScaleHow & SCALE_X) ? 0 : move[0];
+ move[1] = (g_nScaleHow & SCALE_Y) ? 0 : move[1];
+ move[2] = (g_nScaleHow & SCALE_Z) ? 0 : move[2];
+ }
+
+ if (g_pParentWnd->ActiveXY()->RotateMode() || g_bPatchBendMode)
+ {
+ float fDeg = -move[2];
+ float fAdj = move[2];
+ int nAxis = 0;
+ if (g_pParentWnd->ActiveXY()->GetViewType() == XY)
+ {
+ fDeg = -move[1];
+ fAdj = move[1];
+ nAxis = 2;
+ }
+ else
+ if (g_pParentWnd->ActiveXY()->GetViewType() == XZ)
+ {
+ fDeg = move[2];
+ fAdj = move[2];
+ nAxis = 1;
+ }
+ else
+ nAxis = 0;
+
+ g_pParentWnd->ActiveXY()->Rotation()[nAxis] += fAdj;
+ 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]);
+ g_pParentWnd->SetStatusText(2, strStatus);
+
+ if (g_bPatchBendMode)
+ {
+ Patch_SelectBendNormal();
+ Select_RotateAxis(nAxis, fDeg*2, false, true);
+ Patch_SelectBendAxis();
+ Select_RotateAxis(nAxis, fDeg, false, true);
+ }
+ else
+ {
+ Select_RotateAxis(nAxis, fDeg, false, true);
+ }
+ return;
+ }
+
+ if (g_pParentWnd->ActiveXY()->ScaleMode())
+ {
+ vec3_t v;
+ v[0] = v[1] = v[2] = 1.0f;
+ if (move[1] > 0)
+ {
+ v[0] = 1.1f;
+ v[1] = 1.1f;
+ v[2] = 1.1f;
+ }
+ else
+ if (move[1] < 0)
+ {
+ v[0] = 0.9f;
+ v[1] = 0.9f;
+ v[2] = 0.9f;
+ }
+
+ Select_Scale((g_nScaleHow & SCALE_X) ? 1.0f : v[0],
+ (g_nScaleHow & SCALE_Y) ? 1.0f : v[1],
+ (g_nScaleHow & SCALE_Z) ? 1.0f : v[2]);
+ // is that really necessary???
+ Sys_UpdateWindows (W_ALL);
+ return;
+ }
+
+
+ vec3_t vDistance;
+ VectorSubtract(pressdelta, vPressStart, vDistance);
+ strStatus.Format("Distance x: %.1f y: %.1f z: %.1f", vDistance[0], vDistance[1], vDistance[2]);
+ g_pParentWnd->SetStatusText(3, strStatus);
+
+ //
+ // dragging only a part of the selection
+ //
+
+ // this is fairly crappy way to deal with curvepoint and area selection
+ // but it touches the smallest amount of code this way
+ //
+ if (g_qeglobals.d_num_move_points || g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_area || g_qeglobals.d_select_mode == sel_areatall)
+ {
+ //area selection
+ if (g_qeglobals.d_select_mode == sel_area || g_qeglobals.d_select_mode == sel_areatall)
+ {
+ VectorAdd(g_qeglobals.d_vAreaBR, move, g_qeglobals.d_vAreaBR);
+ return;
+ }
+ //curve point selection
+ if (g_qeglobals.d_select_mode == sel_curvepoint)
+ {
+ Patch_UpdateSelected(move);
+ return;
+ }
+ //vertex selection
+ if (g_qeglobals.d_select_mode == sel_vertex && g_PrefsDlg.m_bVertexSplit)
+ {
+ if(g_qeglobals.d_num_move_points) {
+ success = true;
+ for (b = selected_brushes.next; b != &selected_brushes; b = b->next)
+ {
+ success &= Brush_MoveVertex(b, g_qeglobals.d_move_points[0], move, end, true);
+ }
+ if (success)
+ VectorCopy(end, g_qeglobals.d_move_points[0]);
+ }
+ return;
+ }
+ //all other selection types
+ for (i=0 ; i<g_qeglobals.d_num_move_points ; i++)
+ VectorAdd (g_qeglobals.d_move_points[i], move, g_qeglobals.d_move_points[i]);
+ for (b = selected_brushes.next; b != &selected_brushes; b = b->next)
+ {
+ bool bMoved = false;
+ for(face_t *f = b->brush_faces; !bMoved && f!=NULL; f=f->next)
+ for(int p=0; !bMoved && p<3; p++)
+ for (i=0 ; !bMoved && i<g_qeglobals.d_num_move_points ; i++)
+ if(f->planepts[p] == g_qeglobals.d_move_points[i])
+ bMoved = true;
+ if(!bMoved) continue;
+
+ VectorCopy(b->maxs, vTemp);
+ VectorSubtract(vTemp, b->mins, vTemp);
+ Brush_Build(b,true,true,false,false); // don't filter
+ for (i=0 ; i<3 ; i++)
+ {
+ if (b->mins[i] > b->maxs[i]
+ || b->maxs[i] - b->mins[i] > g_MaxBrushSize)
+ break; // dragged backwards or fucked up
+ }
+ if (i != 3)
+ break;
+ if (b->patchBrush)
+ {
+ VectorCopy(b->maxs, vTemp2);
+ VectorSubtract(vTemp2, b->mins, vTemp2);
+ VectorSubtract(vTemp2, vTemp, vTemp2);
+ //if (!Patch_DragScale(b->nPatchID, vTemp2, move))
+ if (!Patch_DragScale(b->pPatch, vTemp2, move))
+ {
+ b = NULL;
+ break;
+ }
+ }
+ }
+ // if any of the brushes were crushed out of existance
+ // calcel the entire move
+ if (b != &selected_brushes)
+ {
+ Sys_Printf ("Brush dragged backwards, move canceled\n");
+ for (i=0 ; i<g_qeglobals.d_num_move_points ; i++)
+ VectorSubtract (g_qeglobals.d_move_points[i], move, g_qeglobals.d_move_points[i]);
+
+ for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next)
+ Brush_Build(b,true,true,false,false); // don't filter
+ }
+
+ }
+ else
+ {
+ // reset face originals from vertex edit mode
+ // this is dirty, but unfortunately necessary because Brush_Build
+ // can remove windings
+ for (b = selected_brushes.next; b != &selected_brushes; b = b->next)
+ {
+ Brush_ResetFaceOriginals(b);
+ }
+ //
+ // if there are lots of brushes selected, just translate instead
+ // of rebuilding the brushes
+ // NOTE: this is not actually done, but would be a good idea
+ //
+ Select_Move (move);
+ }
+}
+
+/*
+===========
+Drag_MouseMoved
+===========
+*/
+void Drag_MouseMoved (int x, int y, int buttons)
+{
+ vec3_t move, delta;
+ int i;
+
+ if (!buttons)
+ {
+ drag_ok = false;
+ return;
+ }
+ if (!drag_ok)
+ return;
+
+ // clear along one axis
+ if (buttons & MK_SHIFT && (g_PrefsDlg.m_bALTEdge && g_qeglobals.d_select_mode != sel_areatall))
+ {
+ drag_first = false;
+ if (abs(x-pressx) > abs(y-pressy))
+ y = pressy;
+ else
+ x = pressx;
+ }
+
+ if (g_qeglobals.d_select_mode == sel_area && g_nPatchClickedView == W_CAMERA)
+ {
+ camera_t *m_pCamera = g_pParentWnd->GetCamWnd()->Camera();
+
+ // snap to window
+ if( y > m_pCamera->height ) y = m_pCamera->height - 1; else if( y < 0 ) y = 0;
+ if( x > m_pCamera->width ) x = m_pCamera->width - 1; else if( x < 0 ) x = 0;
+
+ VectorSet (move, x - pressx, y - pressy, 0);
+ } else
+ {
+ for (i=0 ; i<3 ; i++)
+ {
+ move[i] = drag_xvec[i]*(x - pressx) + drag_yvec[i]*(y - pressy);
+ if (!g_PrefsDlg.m_bNoClamp)
+ {
+ move[i] = floor(move[i]/g_qeglobals.d_gridsize+0.5)*g_qeglobals.d_gridsize;
+ }
+ }
+ }
+
+ VectorSubtract (move, pressdelta, delta);
+ VectorCopy (move, pressdelta);
+
+ MoveSelection (delta);
+}
+
+/*
+===========
+Drag_MouseUp
+===========
+*/
+void Drag_MouseUp (int nButtons)
+{
+ Sys_Status ("Drag completed.", 0);
+
+ if (g_qeglobals.d_select_mode == sel_area)
+ {
+ Patch_SelectAreaPoints(nButtons & MK_CONTROL); // adds to selection and/or deselects selected points if ctrl is held
+ g_qeglobals.d_select_mode = sel_curvepoint;
+ Sys_UpdateWindows (W_ALL);
+ }
+
+ if (g_qeglobals.d_select_mode == sel_areatall)
+ {
+ vec3_t mins, maxs;
+
+ int nDim1 = (g_pParentWnd->ActiveXY()->GetViewType() == YZ) ? 1 : 0;
+ int nDim2 = (g_pParentWnd->ActiveXY()->GetViewType() == XY) ? 1 : 2;
+
+ // get our rectangle
+ mins[nDim1] = MIN( g_qeglobals.d_vAreaTL[nDim1], g_qeglobals.d_vAreaBR[nDim1] );
+ mins[nDim2] = MIN( g_qeglobals.d_vAreaTL[nDim2], g_qeglobals.d_vAreaBR[nDim2] );
+ maxs[nDim1] = MAX( g_qeglobals.d_vAreaTL[nDim1], g_qeglobals.d_vAreaBR[nDim1] );
+ maxs[nDim2] = MAX( g_qeglobals.d_vAreaTL[nDim2], g_qeglobals.d_vAreaBR[nDim2] );
+
+ // deselect current selection
+ if( !(nButtons & (MK_CONTROL|MK_SHIFT)) )
+ Select_Deselect();
+
+ // select new selection
+ Select_RealCompleteTall( mins, maxs );
+
+ Sys_UpdateWindows (W_ALL);
+ }
+
+ if (g_qeglobals.d_select_translate[0] || g_qeglobals.d_select_translate[1] || g_qeglobals.d_select_translate[2])
+ {
+ Select_Move (g_qeglobals.d_select_translate);
+ VectorCopy (vec3_origin, g_qeglobals.d_select_translate);
+ Sys_UpdateWindows (W_CAMERA);
+ }
+
+ /* note: added cleanup here, since an edge drag will leave selected vertices
+ in g_qeglobals.d_num_move_points
+ */
+ if ( g_qeglobals.d_select_mode != sel_vertex &&
+ g_qeglobals.d_select_mode != sel_curvepoint &&
+ g_qeglobals.d_select_mode != sel_edge)
+ g_qeglobals.d_num_move_points = 0;
+
+ g_pParentWnd->SetStatusText(3, "");
+ Undo_EndBrushList(&selected_brushes);
+ Undo_End();
+ UpdateSurfaceDialog();
+}