public void MoveMarkedRaw(GLView view, Vector3 dir) { if (dir == Vector3.Zero) { return; } if (view.m_view_type == ViewType.PERSP) { dir = Vector3.Transform(dir, view.m_cam_mat.ExtractRotation().Inverted()); dir.Z *= -1f; } else { if (view.m_view_type == ViewType.TOP) { dir = Vector3.Transform(dir, Matrix4.CreateRotationX(Utility.RAD_90)); } else if (view.m_view_type == ViewType.RIGHT) { dir = Vector3.Transform(dir, Matrix4.CreateRotationY(-Utility.RAD_90)); } } // Tag all the verts to move, then move them TagAllVerts(false); switch (editor.m_edit_mode) { case EditMode.POLY: for (int i = 0; i < polygon.Count; i++) { if (polygon[i].marked) { TagPolyVerts(polygon[i]); } } break; case EditMode.VERT: for (int i = 0; i < vert_info.Count; i++) { if (vert_info[i].marked) { vert_info[i].tag = true; } } break; } for (int i = 0; i < vert_info.Count; i++) { if (vert_info[i].tag) { vertex[i] += dir; } } editor.RefreshGeometry(); }
// Find the closest edge (avg pos between two verts) on the selected polygon for the view/pos, returns the first of the verts in the edge public int GetClosestEdgeFV(GLView view, DMesh dmesh, Vector3 pos, int exclude_vert, bool update_cut_pos = false) { int closest_edge = -1; float closest_dist = 9999f; float dist; Vector3 edge_pos; for (int i = 0; i < num_verts; i++) { if (i != exclude_vert) { edge_pos = dmesh.vertex[vert[i]] + dmesh.vertex[vert[(i + 1) % num_verts]]; edge_pos *= 0.5f; edge_pos = Utility.NullifyAxisForView(edge_pos, view.m_view_type); dist = (pos - edge_pos).Length; if (dist < closest_dist) { if (update_cut_pos) { Editor.POLYCUT_POS = edge_pos; } closest_dist = dist; closest_edge = i; } } } return(closest_edge); }
public void AddVertAtMouse(GLView view) { SaveStateForUndo("Add new vertex"); Vector3 pos = ScreenToWorldPos(view.m_mouse_pos, view); m_dmesh.AddVertexEditor(pos.X, pos.Y, pos.Z); RefreshGeometry(); }
public void Initialize(Editor editor) { m_editor = editor; this.Resize += new System.EventHandler(this.gl_panel_Resize); // Init views and view labels Size sz = this.Size; sz.Height -= 5; sz.Width -= 5; // Create GL views and labels for (int i = 0; i < (int)ViewType.NUM; i++) { gl_view[i] = new GLView((ViewType)i, m_editor); gl_view[i].Parent = this; switch (i) { case 0: gl_view[i].Location = new Point(0, 0); break; case 1: gl_view[i].Location = new Point(sz.Width / 2, 0); break; case 2: gl_view[i].Location = new Point(0, sz.Height / 2); break; case 3: gl_view[i].Location = new Point(sz.Width / 2, sz.Height / 2); break; } gl_view[i].Size = new Size(sz.Width / 2, sz.Height / 2); gl_view[i].Show(); } for (int i = 0; i < (int)ViewType.NUM; i++) { label_viewport[i] = new Label(); label_viewport[i].Parent = this; label_viewport[i].Location = new Point(gl_view[i].Location.X + 2, gl_view[i].Location.Y + 2); label_viewport[i].AutoSize = true; label_viewport[i].Text = ((ViewType)i).ToString(); label_viewport[i].BackColor = GLView.C_bg; label_viewport[i].ForeColor = Color.White; label_viewport[i].Show(); this.Controls.Add(label_viewport[i]); label_viewport[i].BringToFront(); } }
public void ScaleMarkedElementsRaw(GLView view, float amtx = 1f, float amty = 1f) { if (m_scale_mode == ScaleMode.FREE_XY) { m_dmesh.ScaleMarked(view, ScaleMode.VIEW_X, amtx); m_dmesh.ScaleMarked(view, ScaleMode.VIEW_X, amty); } else { m_dmesh.ScaleMarked(view, m_scale_mode, amtx); } RefreshGeometry(); }
public void KeyboardDown(KeyEventArgs e, GLView view) { //Utility.DebugLog("Got keycode " + e.KeyCode.ToString() + " - data: " + e.KeyData.ToString() + " - value: " + e.KeyValue.ToString() + " - alt: " + e.Alt.ToString()); //Look for keycode foreach (KeyboardAssignment ka in KeyboardAssignments) { if (ka.Matches(e.KeyData)) { ka.Function(e, view); } } }
public void ScaleMarkedElements(GLView view, bool up, bool minor) { SaveStateForUndo("Scale marked elements"); float amt = 1f; if (up) { amt = (minor ? 1.1f : 2f); } else { amt = (minor ? 1f / 1.1f : 0.5f); } m_dmesh.ScaleMarked(view, m_scale_mode, amt); RefreshGeometry(); }
public void FitFrameMarkedSelected(bool all, GLView view) { if (all) { List <Vector3> pos_list = new List <Vector3>(); for (int i = 0; i < 4; i++) { pos_list = m_dmesh.AllMarkedVertexPositions(); gl_view[i].FitFrame(pos_list); } } else { view.FitFrame(m_dmesh.AllMarkedVertexPositions()); } }
public void MaybeCutPolygon(GLView view, bool dont_cut = false) { if (m_dmesh.selected_poly > -1 && m_dmesh.selected_poly < m_dmesh.polygon.Count) { DPoly dp = m_dmesh.polygon[m_dmesh.selected_poly]; SaveStateForUndo("Maybe cut polygon"); Vector3 pos = ScreenToWorldPos(view.m_mouse_pos, view, false); if (m_cut_poly_state == 0) { m_cut_polyvert_start = dp.GetClosestEdgeFV(view, m_dmesh, pos, -1, true); m_cut_poly_state = 1; } else { m_cut_polyvert_end = dp.GetClosestEdgeFV(view, m_dmesh, pos, m_cut_polyvert_start); int v1 = dp.vert[m_cut_polyvert_start]; int v2 = dp.vert[(m_cut_polyvert_start + 1) % dp.num_verts]; int v3 = dp.vert[m_cut_polyvert_end]; int v4 = dp.vert[(m_cut_polyvert_end + 1) % dp.num_verts]; // Add the verts DPoly.AddedVert = -1; dp.MaybeAddVertBetween(v1, v2, m_dmesh); int new_v0 = DPoly.AddedVert; DPoly.AddedVert = -1; dp.MaybeAddVertBetween(v3, v4, m_dmesh); int new_v1 = DPoly.AddedVert; m_cut_poly_state = 0; if (!dont_cut) { m_dmesh.SplitPolygonByVerts(dp, new_v0, new_v1); } AddOutputText("Cut a polygon"); } RefreshGeometry(true); } else { AddOutputText("Select a polygon to cut"); } }
public Vector3 WorldToScreenPos(Vector3 obj_pos, GLView view) { if (view.m_view_type == ViewType.TOP) { obj_pos = Vector3.Transform(obj_pos, Matrix4.CreateRotationX(-Utility.RAD_90)); } else if (view.m_view_type == ViewType.RIGHT) { obj_pos = Vector3.Transform(obj_pos, Matrix4.CreateRotationY(Utility.RAD_90)); } else if (view.m_view_type == ViewType.PERSP) { //obj_pos.Z *= -1f; } obj_pos.Z *= -1f; return(Utility.WorldToScreen(obj_pos, view.m_cam_mat, view.m_persp_mat, view.m_control_sz.X, view.m_control_sz.Y, (view.m_view_type == ViewType.PERSP))); }
public Vector3 ScreenToWorldPos(Vector2 mouse_pos, GLView view, bool snap = true) { Vector3 pos = new Vector3(mouse_pos.X, mouse_pos.Y, 0f); pos.X = (2.0f * pos.X / (float)view.m_control_sz.X) - 1f; pos.Y = (2.0f * pos.Y / (float)view.m_control_sz.Y) - 1f; pos.Y *= -1f; pos = Vector3.Transform(pos, view.m_persp_mat.Inverted()); pos = Vector3.Transform(pos, view.m_cam_mat.Inverted()); switch (view.m_view_type) { case ViewType.TOP: pos = Vector3.Transform(pos, Matrix4.CreateRotationX(Utility.RAD_90)); break; case ViewType.RIGHT: pos = Vector3.Transform(pos, Matrix4.CreateRotationY(-Utility.RAD_90)); break; case ViewType.FRONT: break; case ViewType.PERSP: pos.Z *= -1f; // Project it forward, then project it to the XY plane Vector3 orig_pos = pos; Vector3 cam_forward = view.m_cam_mat.Column2.Xyz; cam_forward.X *= -1f; cam_forward.Y *= -1f; pos += cam_forward * (-view.m_cam_mat.Row3.Z - 1f); pos *= -view.m_cam_mat.Row3.Z; cam_forward = (pos - orig_pos).Normalized(); pos -= cam_forward * (pos.Y / cam_forward.Y); break; } if (snap) { pos = Utility.SnapValue(pos, m_grid_snap); } return(pos); }
public void RotateMarkedElementsRaw(GLView view, float amt) { m_dmesh.RotateMarked(view, amt); RefreshGeometry(); }
public const float VERT_CYCLE_RANGE_SQ = 100f; // In PIXELS, not distance public bool MousePickSelect(GLView view, Vector2 mouse_pos, bool silent = false, bool ignore_z = false) { Vector2 v; Vector3 center_pos; Vector3 normal; float closest_sq = 1000f; int closest_obj = -1; int near_objs = 0; int sel_obj_idx = -1; int sel_side_idx = -1; float dist_sq; vert_scrn_pos = new Vector3[vertex.Count]; for (int i = 0; i < vertex.Count; i++) { vert_scrn_pos[i] = WorldToScreenPos(vertex[i], view); } // Apply the matrices to the vertices, find which vert is the closest, and a list of all near verts (within a certain range) switch (editor.m_edit_mode) { case EditMode.VERT: sel_obj_idx = selected_vert; for (int i = 0; i < vertex.Count; i++) { if (near_objs < MAX_NEAR_OBJS) { // Test verts for distance from mouse_pos v.X = vert_scrn_pos[i].X; v.Y = vert_scrn_pos[i].Y; dist_sq = (mouse_pos - v).LengthSquared; if (dist_sq < closest_sq) { closest_obj = i; closest_sq = dist_sq; } if (view.m_view_type != ViewType.PERSP || vert_scrn_pos[i].Z > 0f) { if (dist_sq < VERT_CYCLE_RANGE_SQ) { near_obj_list[near_objs] = i; near_obj_z[near_objs] = vert_scrn_pos[i].Z; near_objs += 1; } } } } break; case EditMode.POLY: sel_obj_idx = selected_poly; List <DTriangle> tri_list = new List <DTriangle>(); // Go through all the triangles of each poly, first check normal, then test for being inside for (int i = 0; i < polygon.Count; i++) { if (!IsPolyVisible(i)) { continue; } tri_list = polygon[i].DeconvertPoly(); foreach (DTriangle tri in tri_list) { normal = Utility.FindNormal(vert_scrn_pos[tri.vert[0]], vert_scrn_pos[tri.vert[1]], vert_scrn_pos[tri.vert[2]]); if (normal.Z > 0f || ignore_z) { bool inside = Utility.PointInsideTri(mouse_pos, vert_scrn_pos[tri.vert[0]], vert_scrn_pos[tri.vert[1]], vert_scrn_pos[tri.vert[2]]); if (inside) { // Find the relative distance to the opposite edges float e0 = Utility.FindDistanceToEdge(mouse_pos, vert_scrn_pos[tri.vert[1]], vert_scrn_pos[tri.vert[2]]) / Utility.FindDistanceToEdge(vert_scrn_pos[tri.vert[0]], vert_scrn_pos[tri.vert[1]], vert_scrn_pos[tri.vert[2]]); float e1 = Utility.FindDistanceToEdge(mouse_pos, vert_scrn_pos[tri.vert[2]], vert_scrn_pos[tri.vert[0]]) / Utility.FindDistanceToEdge(vert_scrn_pos[tri.vert[1]], vert_scrn_pos[tri.vert[2]], vert_scrn_pos[tri.vert[0]]); float e2 = Utility.FindDistanceToEdge(mouse_pos, vert_scrn_pos[tri.vert[0]], vert_scrn_pos[tri.vert[1]]) / Utility.FindDistanceToEdge(vert_scrn_pos[tri.vert[2]], vert_scrn_pos[tri.vert[0]], vert_scrn_pos[tri.vert[1]]); float total = e0 + e1 + e2; //center_pos = (vert_scrn_pos[tri.vert[0]] + vert_scrn_pos[tri.vert[1]] + vert_scrn_pos[tri.vert[2]]) * 0.3333f; center_pos = vert_scrn_pos[tri.vert[0]] * e0 + vert_scrn_pos[tri.vert[1]] * e1 + vert_scrn_pos[tri.vert[2]] * e2; if (view.m_view_type != ViewType.PERSP || center_pos.Z > 0f) { near_obj_list[near_objs] = i; near_obj_z[near_objs] = center_pos.Z; near_objs += 1; } } } } } break; } if (near_objs < 2 && closest_obj > -1 && editor.m_edit_mode == EditMode.VERT) { sel_obj_idx = closest_obj; } else if (near_objs >= 1) { // Sort the objects by Z order (have to copy to arrays of the correct size first) int[] sort_list = new int[near_objs]; int[] sort_side = new int[near_objs]; float[] sort_z = new float[near_objs]; for (int i = 0; i < near_objs; i++) { sort_list[i] = near_obj_list[i]; sort_side[i] = near_obj_side[i]; sort_z[i] = near_obj_z[i]; } Array.Sort(sort_z, sort_list); for (int i = 0; i < near_objs; i++) { sort_z[i] = near_obj_z[i]; } Array.Sort(sort_z, sort_side); // See if the current selected object is in the array int sel_index = -1; for (int i = 0; i < near_objs; i++) { // Extra testing for segment/sides, but not verts/entities if (sort_list[i] == sel_obj_idx) { sel_index = i; break; } } // If it's in the list, and not the last in the list if (sel_index > -1 && sel_index < near_objs - 1) { // Find the next in the list sel_obj_idx = sort_list[sel_index + 1]; sel_side_idx = sort_side[sel_index + 1]; } else { // Choose the first in the list sel_obj_idx = sort_list[0]; sel_side_idx = sort_side[0]; } } // Select the actual object if (sel_obj_idx > -1 && near_objs > 0) { switch (editor.m_edit_mode) { case EditMode.VERT: selected_vert = sel_obj_idx; break; case EditMode.POLY: SelectPolyIndex(sel_obj_idx); break; } if (!silent) { editor.RefreshGeometry(); } return(true); } else { return(false); } }
public void MouseDragMark(GLView view, Vector2 mouse_pos_down, Vector2 mouse_pos, bool add) { int count; vert_scrn_pos = new Vector3[vertex.Count]; for (int i = 0; i < vertex.Count; i++) { vert_scrn_pos[i] = WorldToScreenPos(vertex[i], view); } // Apply the matrices to the vertices, find which vert is the closest, and a list of all near verts (within a certain range) switch (editor.m_edit_mode) { case EditMode.VERT: for (int i = 0; i < vertex.Count; i++) { if (!add) { vert_info[i].marked = false; } if (Utility.PointInsideAABB(vert_scrn_pos[i].Xy, mouse_pos_down, mouse_pos)) { vert_info[i].marked = true; } } break; case EditMode.POLY: for (int i = 0; i < polygon.Count; i++) { if (!add) { polygon[i].marked = false; } if (!IsPolyVisible(i)) { continue; } if (editor.m_drag_mode == DragMode.ALL) { count = 0; for (int j = 0; j < polygon[i].num_verts; j++) { if (Utility.PointInsideAABB(vert_scrn_pos[polygon[i].vert[j]].Xy, mouse_pos_down, mouse_pos)) { count += 1; } } if (count == polygon[i].num_verts) { polygon[i].marked = true; } } else if (editor.m_drag_mode == DragMode.ANY) { for (int j = 0; j < polygon[i].num_verts; j++) { if (Utility.PointInsideAABB(vert_scrn_pos[polygon[i].vert[j]].Xy, mouse_pos_down, mouse_pos)) { polygon[i].marked = true; break; } } } } break; } editor.RefreshGeometry(); }
public void KeyboardDown(KeyEventArgs e, GLView view) { //Utility.DebugLog("Got keycode " + e.KeyCode.ToString() + " - data: " + e.KeyData.ToString() + " - value: " + e.KeyValue.ToString() + " - alt: " + e.Alt.ToString()); switch (e.KeyCode) { case Keys.NumPad1: RotateMarkedElements(view, -1f, e.Alt); break; case Keys.NumPad3: RotateMarkedElements(view, 1f, e.Alt); break; case Keys.NumPad7: ScaleMarkedElements(view, false, e.Alt); break; case Keys.NumPad9: ScaleMarkedElements(view, true, e.Alt); break; case Keys.NumPad4: MoveMarkedElements(view, -Vector3.UnitX, e.Alt); break; case Keys.NumPad6: MoveMarkedElements(view, Vector3.UnitX, e.Alt); break; case Keys.NumPad8: MoveMarkedElements(view, Vector3.UnitY, e.Alt); break; case Keys.NumPad2: MoveMarkedElements(view, -Vector3.UnitY, e.Alt); break; case Keys.Subtract: MoveMarkedElements(view, Vector3.UnitZ, e.Alt); break; case Keys.A: if (!e.Control) { if (e.Shift) { AddPolygonFromMarkedVerts(); } else { AddVertAtMouse(view); } } break; case Keys.Add: break; case Keys.R: CycleScaleMode(e.Shift); UpdateOptionLabels(); break; case Keys.Tab: case Keys.Oemtilde: CycleEditMode(e.Shift); break; case Keys.Insert: if (e.Control) { ExtrudeMarkedPolys(); } else if (e.Shift) { ExtrudeMarkedVerts(); } else { ExtrudeSelectedPoly(); } break; case Keys.I: if (e.Control) { ExtrudeMarkedPolys(); } else if (e.Shift) { ExtrudeMarkedVerts(); } else { ExtrudeSelectedPoly(); } break; case Keys.Delete: DeleteMarked(); break; case Keys.Space: if (e.Modifiers == Keys.Control) { ClearAllMarked(); } else if (e.Modifiers == Keys.Shift) { ToggleMarkAll(); } else { ToggleMarkSelected(); } break; case Keys.F: if (e.Control) { SaveStateForUndo("Flip normal"); m_dmesh.ReverseMarkedPolys(); RefreshGeometry(); } else { FitFrameAll(e.Shift, view); } break; case Keys.G: if (e.Modifiers == Keys.Shift) { CycleGridDisplay(); } else if (e.Modifiers == Keys.Control) { SnapMarkedElementsToGrid(); } break; case Keys.Q: if (e.Modifiers == Keys.Shift) { MarkCoplanarPolys(); } break; case Keys.T: if (e.Modifiers == Keys.Shift) { m_dmesh.UVAlignToPoly(); RefreshGeometry(); } else if (e.Modifiers == Keys.Control) { m_dmesh.UVDefaultMapMarkedPolys(); RefreshGeometry(); } break; case Keys.J: break; case Keys.OemCloseBrackets: if (e.Modifiers == Keys.Shift) { ChangeGridSpacing(1); } else { ChangeGridSnap(1); } break; case Keys.OemOpenBrackets: if (e.Modifiers == Keys.Shift) { ChangeGridSpacing(-1); } else { ChangeGridSnap(-1); } break; case Keys.N: break; case Keys.C: if (e.Modifiers == Keys.Control) { CopyMarkedPolys(); } else { m_dmesh.CycleSelectedPoly(e.Shift); RefreshGeometry(true); } break; case Keys.V: if (e.Modifiers == Keys.Control) { PasteBufferPolys(); } else { m_dmesh.CycleSelectedVert(e.Shift); RefreshGeometry(true); } break; case Keys.X: //CycleSelectedSide(e.Shift); if (e.Modifiers == Keys.Shift || e.Modifiers == (Keys.Shift | Keys.Control)) { MaybeCutPolygon(view, (e.Modifiers != Keys.Shift)); } break; case Keys.Up: MoveMarkedSideTextures(Vector2.UnitY, e.Alt); break; case Keys.Down: MoveMarkedSideTextures(-Vector2.UnitY, e.Alt); break; case Keys.Left: if (e.Control) { RotateMarkedSideTextures(1f, e.Alt); } else { MoveMarkedSideTextures(Vector2.UnitX, e.Alt); } break; case Keys.Right: if (e.Control) { RotateMarkedSideTextures(-1f, e.Alt); } else { MoveMarkedSideTextures(-Vector2.UnitX, e.Alt); } break; case Keys.F1: CycleVisibilityType(); break; case Keys.F2: break; case Keys.F3: break; default: //Utility.DebugLog("Got keydown " + e.KeyCode.ToString()); break; } }
private void Editor_Load(object sender, EventArgs e) { m_dmesh = new DMesh("default_dmesh"); tm_decal = new TextureManager(this); texture_list = new TextureList(this); uv_editor = new UVEditor(this); tunnel_builder = new TunnelBuilder(this); dmesh_browser = new DMeshBrowser(this); NewDMesh(); UndoInit(); KeyPreview = true; // Init views and view labels Size sz = gl_panel.Size; sz.Height -= 5; sz.Width -= 5; // Create GL views and labels for (int i = 0; i < (int)ViewType.NUM; i++) { gl_view[i] = new GLView((ViewType)i, this); gl_view[i].Parent = gl_panel; switch (i) { case 0: gl_view[i].Location = new Point(0, 0); break; case 1: gl_view[i].Location = new Point(sz.Width / 2, 0); break; case 2: gl_view[i].Location = new Point(0, sz.Height / 2); break; case 3: gl_view[i].Location = new Point(sz.Width / 2, sz.Height / 2); break; } gl_view[i].Size = new Size(sz.Width / 2, sz.Height / 2); gl_view[i].Show(); } for (int i = 0; i < (int)ViewType.NUM; i++) { label_viewport[i] = new Label(); label_viewport[i].Parent = gl_panel; label_viewport[i].Location = new Point(gl_view[i].Location.X + 2, gl_view[i].Location.Y + 2); label_viewport[i].AutoSize = true; label_viewport[i].Text = ((ViewType)i).ToString(); label_viewport[i].BackColor = GLView.C_bg; label_viewport[i].ForeColor = Color.White; label_viewport[i].Show(); gl_panel.Controls.Add(label_viewport[i]); label_viewport[i].BringToFront(); } // Could make this save/load? WindowState = FormWindowState.Maximized; ResetViews(); UpdateDirectories(); LoadPreferences(); UpdateOptionLabels(); RefreshGrid(); ResetViews(); InitChecklists(); ComputerInfo ci = new ComputerInfo(); ulong total_memory = (ulong)ci.TotalPhysicalMemory; bool low_mem = total_memory < 5000000000; // 5 GB if (m_low_res_force || low_mem) { m_low_res_textures = true; } tm_decal.LoadTexturesInDir(m_filepath_decal_textures, false, false); tm_decal.LoadTexturesInDir(m_filepath_level_textures, false, false); texture_list.InitImageLists(); texture_list.Hide(); uv_editor.Hide(); tunnel_builder.Hide(); }
public void RotateMarked(GLView view, float amt = Utility.RAD_90) { if (amt == 0f) { return; } Axis axis = Axis.X; switch (view.m_view_type) { case ViewType.FRONT: axis = Axis.Z; amt *= -1f; break; case ViewType.RIGHT: axis = Axis.X; break; case ViewType.TOP: axis = Axis.Y; amt *= -1f; break; case ViewType.PERSP: Vector3 dir = Vector3.Transform(Vector3.UnitZ, view.m_cam_mat.ExtractRotation().Inverted()); dir = Utility.CardinalVector(dir); float sign; axis = Utility.VectorToAxis(dir, out sign); amt *= sign; break; } // Tag all the verts to rotate, then rotate them TagAllVerts(false); switch (editor.m_edit_mode) { case EditMode.POLY: for (int i = 0; i < polygon.Count; i++) { if (polygon[i].marked) { TagPolyVerts(polygon[i]); } } break; case EditMode.VERT: for (int i = 0; i < vert_info.Count; i++) { if (vert_info[i].marked) { vert_info[i].tag = true; } } break; } Vector3 pivot = GetPivotPosition(); for (int i = 0; i < vert_info.Count; i++) { if (vert_info[i].tag) { vertex[i] = Utility.RotateAroundPivot(vertex[i], pivot, axis, amt); } } }
public void ScaleMarked(GLView view, ScaleMode scale_mode, float amt = 2f) { if (amt == 1f) { return; } Axis axis = Axis.ALL; // Figure which axis to scale if (scale_mode != ScaleMode.ALL) { ViewType vt = view.m_view_type; if (vt == ViewType.PERSP) { Vector3 dir = Vector3.Transform(Vector3.UnitZ, view.m_cam_mat.ExtractRotation().Inverted()); dir = Utility.CardinalVector(dir); vt = Utility.VectorToViewType(dir); } switch (vt) { case ViewType.FRONT: switch (scale_mode) { case ScaleMode.VIEW_X: axis = Axis.X; break; case ScaleMode.VIEW_Y: axis = Axis.Y; break; case ScaleMode.VIEW_XY: axis = Axis.XY; break; } break; case ViewType.RIGHT: switch (scale_mode) { case ScaleMode.VIEW_X: axis = Axis.Z; break; case ScaleMode.VIEW_Y: axis = Axis.Y; break; case ScaleMode.VIEW_XY: axis = Axis.YZ; break; } break; case ViewType.TOP: switch (scale_mode) { case ScaleMode.VIEW_X: axis = Axis.X; break; case ScaleMode.VIEW_Y: axis = Axis.Z; break; case ScaleMode.VIEW_XY: axis = Axis.XZ; break; } break; } } // Tag all the verts to scale, then scale them TagAllVerts(false); switch (editor.m_edit_mode) { case EditMode.POLY: for (int i = 0; i < polygon.Count; i++) { if (polygon[i].marked) { TagPolyVerts(polygon[i]); } } break; case EditMode.VERT: for (int i = 0; i < vert_info.Count; i++) { if (vert_info[i].marked) { vert_info[i].tag = true; } } break; } Vector3 pivot = GetPivotPosition(); for (int i = 0; i < vert_info.Count; i++) { if (vert_info[i].tag) { vertex[i] = Utility.ScaleFromPivot(vertex[i], pivot, axis, amt); } } }
public void MoveMarkedElementsRaw(GLView view, Vector3 amt_dir) { m_dmesh.MoveMarkedRaw(view, amt_dir); RefreshGeometry(); }
public void MoveMarkedElements(GLView view, Vector3 dir, bool minor) { SaveStateForUndo("Move marked elements"); m_dmesh.MoveMarked(view, dir, m_grid_snap * (minor ? 0.125f : 1f)); RefreshGeometry(); }
public void RotateMarkedElements(GLView view, float amt, bool minor) { SaveStateForUndo("Rotate marked elements"); m_dmesh.RotateMarked(view, amt * (minor ? Utility.RAD_15 : Utility.RAD_45)); RefreshGeometry(); }