/* The mouse click did not hit the brush, so grab one or more side planes for dragging */ void Brush_SideSelect(brush_t *b,vec3_t origin,vec3_t dir,bool shear) { face_t *f, *f2; vec3_t p1, p2; for(f = b->brush_faces; f; f = f->next) { Math_VectorCopy(origin,p1); Math_VectorMA(origin,16384,dir,p2); for (f2=b->brush_faces ; f2 ; f2=f2->next) { if (f2 == f) continue; Brush_ClipLineToFace(p1,p2,f2); } if(f2) continue; if(Math_VectorCompare(p1,origin)) continue; if(Brush_ClipLineToFace(p1,p2,f)) continue; Brush_SelectFaceForDragging (b, f, shear); } }
/* ================ Draw_Setup ================ */ static void Drag_Setup( int x, int y, int buttons, const idVec3 &xaxis, const idVec3 &yaxis, const idVec3 &origin, const idVec3 &dir ) { qertrace_t t; face_t *f; drag_first = true; VectorCopy(vec3_origin, pressdelta); pressx = x; pressy = y; VectorCopy(xaxis, drag_xvec); AxializeVector(drag_xvec); VectorCopy(yaxis, drag_yvec); AxializeVector(drag_yvec); if (g_qeglobals.d_select_mode == sel_addpoint) { if (g_qeglobals.selectObject) { g_qeglobals.selectObject->addPoint(origin); } else { g_qeglobals.d_select_mode = sel_brush; } return; } if (g_qeglobals.d_select_mode == sel_editpoint) { g_Inspectors->entityDlg.SelectCurvePointByRay( origin, dir, buttons ); if ( g_qeglobals.d_num_move_points ) { drag_ok = true; } Sys_UpdateWindows(W_ALL); return; } if (g_qeglobals.d_select_mode == sel_curvepoint) { SelectCurvePointByRay(origin, dir, buttons); if (g_qeglobals.d_num_move_points || g_qeglobals.d_select_mode == sel_area) { 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 (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\n", 0); return; } if (g_qeglobals.d_select_mode == sel_vertex) { if ( radiant_entityMode.GetBool() ) { return; } SelectVertexByRay(origin, dir); if (g_qeglobals.d_num_move_points) { drag_ok = true; Undo_Start("drag vertex"); Undo_AddBrushList(&selected_brushes); return; } } if (g_qeglobals.d_select_mode == sel_edge) { if ( radiant_entityMode.GetBool() ) { return; } 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); SetActiveDrag(t.point); if (t.point) { drag_ok = true; // point was hit return; } if (t.selected) { drag_ok = true; Undo_Start("drag selection"); Undo_AddBrushList(&selected_brushes); if (buttons == (MK_LBUTTON | MK_CONTROL)) { Sys_Status("Shear dragging face\n"); Brush_SelectFaceForDragging(t.brush, t.face, true); } else if (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT)) { Sys_Status("Sticky dragging brush\n"); for (f = t.brush->brush_faces; f; f = f->next) { Brush_SelectFaceForDragging(t.brush, f, false); } } else { Sys_Status("Dragging entire selection\n"); } return; } if (g_qeglobals.d_select_mode == sel_vertex || g_qeglobals.d_select_mode == sel_edge) { return; } if ( radiant_entityMode.GetBool() ) { return; } // check for side hit multiple brushes selected? if (selected_brushes.next->next != &selected_brushes) { // yes, special handling bool bOK = ( g_PrefsDlg.m_bALTEdge ) ? ( ::GetAsyncKeyState( VK_MENU ) != 0 ) : 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_Status("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_Status("Side stretch\n"); drag_ok = true; Undo_Start("side stretch"); Undo_AddBrushList(&selected_brushes); }
/* Adds the faces planepts to move_points, and rotates and adds the planepts of adjacent face if shear is set */ void Brush_SelectFaceForDragging (brush_t *b, face_t *f, bool shear) { int i; face_t *f2; winding_t *w; float d; brush_t *b2; int c; if(b->owner->eclass->fixedsize) return; c = 0; for (i=0 ; i<3 ; i++) c += AddPlanept (f->planepts[i]); if (c == 0) return; // allready completely added // select all points on this plane in all brushes the selection for(b2 = selected_brushes.next; b2 != &selected_brushes; b2 = b2->next) { if (b2 == b) continue; for (f2=b2->brush_faces ; f2 ; f2=f2->next) { for (i=0 ; i<3 ; i++) if(fabs(Math_DotProduct(f2->planepts[i],f->plane.normal) -f->plane.dist) > ON_EPSILON) break; if(i == 3) { // move this face as well Brush_SelectFaceForDragging(b2, f2, shear); break; } } } // if shearing, take all the planes adjacent to // selected faces and rotate their points so the // edge clipped by a selcted face has two of the points if(!shear) return; for (f2=b->brush_faces ; f2 ; f2=f2->next) { if (f2 == f) continue; w = MakeFaceWinding (b, f2); if (!w) continue; // any points on f will become new control points for (i=0 ; i<w->numpoints ; i++) { d = Math_DotProduct(w->points[i],f->plane.normal)-f->plane.dist; if (d > -ON_EPSILON && d < ON_EPSILON) break; } // // if none of the points were on the plane, // leave it alone // if (i != w->numpoints) { if (i == 0) { // see if the first clockwise point was the // last point on the winding d = Math_DotProduct(w->points[w->numpoints-1],f->plane.normal)-f->plane.dist; if (d > -ON_EPSILON && d < ON_EPSILON) i = w->numpoints - 1; } AddPlanept (f2->planepts[0]); Math_VectorCopy(w->points[i],f2->planepts[0]); if (++i == w->numpoints) i = 0; // see if the next point is also on the plane d = Math_DotProduct(w->points[i] , f->plane.normal) - f->plane.dist; if (d > -ON_EPSILON && d < ON_EPSILON) AddPlanept (f2->planepts[1]); Math_VectorCopy(w->points[i],f2->planepts[1]); if (++i == w->numpoints) i = 0; // the third point is never on the plane Math_VectorCopy(w->points[i],f2->planepts[2]); } free(w); } }
// if (GetKeyState(VK_MENU) & 0x8000) // ALT 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; VectorCopy (xaxis, drag_xvec); AxializeVector (drag_xvec); VectorCopy (yaxis, drag_yvec); AxializeVector (drag_yvec); //Sys_Printf ("Enter Drag_Setup()\n"); extern void SelectCurvePointByRay (vec3_t org, vec3_t dir, int buttons); if (g_qeglobals.d_select_mode == sel_curvepoint) { //if ((buttons == MK_LBUTTON)) // g_qeglobals.d_num_move_points = 0; SelectCurvePointByRay (origin, dir, buttons); if (g_qeglobals.d_num_move_points || g_qeglobals.d_select_mode == sel_area) { 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 (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\n", 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); 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; } } //Sys_Printf ("Beyond Component modifying\n"); // // 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) ? (static_cast<bool>(::GetAsyncKeyState(VK_MENU))) : true; if (bOK) { //Sys_Printf ("ALT Down\n"); for (brush_t* pBrush = selected_brushes.next ; pBrush != &selected_brushes ; pBrush = pBrush->next) { //Sys_Printf ("ALT Down 2\n"); 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 { //Sys_Printf ("Unknown\n"); // 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); }