protected void ExtrudeSelection(int x, int y, int z) { if (x == 0 && y == 0 && z == 0) { return; } if (m_PrevDS != dataSource) { return; } _extruding = true; Dictionary <IntVector3, byte> new_selection = new Dictionary <IntVector3, byte>(); //BSVoxelModify modify = new BSVoxelModify( List <IntVector3> indexes = new List <IntVector3>(); List <BSVoxel> old_voxels = new List <BSVoxel>(); List <BSVoxel> new_voxels = new List <BSVoxel>(); Dictionary <IntVector3, int> refVoxelMap = new Dictionary <IntVector3, int>(); foreach (KeyValuePair <IntVector3, byte> kvp in m_Selections) { IntVector3 ipos = new IntVector3(kvp.Key); ipos.x += x; ipos.y += y; ipos.z += z; BSVoxel new_voxel = dataSource.SafeRead(kvp.Key.x, kvp.Key.y, kvp.Key.z); BSVoxel old_voxel = dataSource.SafeRead(ipos.x, ipos.y, ipos.z); indexes.Add(ipos); old_voxels.Add(old_voxel); new_voxels.Add(new_voxel); new_selection.Add(ipos, kvp.Value); refVoxelMap.Add(ipos, 0); } // Extra Extendable FindExtraExtendableVoxels(dataSource, new_voxels, old_voxels, indexes, refVoxelMap); BSVoxelModify modify = new BSVoxelModify(indexes.ToArray(), old_voxels.ToArray(), new_voxels.ToArray(), dataSource, EBSBrushMode.Add); m_Action.AddModify(modify); modify.Redo(); Dictionary <IntVector3, byte> old_selection = new Dictionary <IntVector3, byte>(m_Selections); BSSelectedBoxModify sm = new BSSelectedBoxModify(old_selection, new_selection, this); m_Action.AddModify(sm); sm.Redo(); }
public void ClearSelection(BSAction action) { if (action == null) { m_Selections.Clear(); m_RecalcBoxes = true; } else { Dictionary <IntVector3, byte> old_selection = new Dictionary <IntVector3, byte>(m_Selections); m_Selections.Clear(); Dictionary <IntVector3, byte> new_selection = new Dictionary <IntVector3, byte>(m_Selections); BSSelectedBoxModify sm = new BSSelectedBoxModify(old_selection, new_selection, this); action.AddModify(sm); m_RecalcBoxes = true; } }
/// <summary> /// Calculates the selection /// </summary> /// <param name="mode">Mode : 0 = add, 1 = substract, 2 = cross</param> protected bool CalcSelection(int mode) { Vector3 iMin = Vector3.zero; Vector3 iMax = Vector3.zero; iMin.x = Mathf.Min(m_Begin.x, m_End.x); iMin.y = Mathf.Min(m_Begin.y, m_End.y); iMin.z = Mathf.Min(m_Begin.z, m_End.z); iMax.x = Mathf.Max(m_Begin.x, m_End.x); iMax.y = Mathf.Max(m_Begin.y, m_End.y); iMax.z = Mathf.Max(m_Begin.z, m_End.z); Dictionary <IntVector3, byte> selection = new Dictionary <IntVector3, byte>(); Dictionary <IntVector3, byte> removes = new Dictionary <IntVector3, byte>(); if (mode == 0) { for (float x = iMin.x; x < iMax.x; x += dataSource.Scale) { for (float y = iMin.y; y < iMax.y; y += dataSource.Scale) { for (float z = iMin.z; z < iMax.z; z += dataSource.Scale) { IntVector3 ipos = new IntVector3(Mathf.FloorToInt(x * dataSource.ScaleInverted), Mathf.FloorToInt(y * dataSource.ScaleInverted), Mathf.FloorToInt(z * dataSource.ScaleInverted)); List <IntVector4> ext_posList = null; List <BSVoxel> ext_voxels = null; if (dataSource.ReadExtendableBlock(new IntVector4(ipos, 0), out ext_posList, out ext_voxels)) { for (int i = 0; i < ext_voxels.Count; i++) { IntVector3 _ipos = new IntVector3(ext_posList[i].x, ext_posList[i].y, ext_posList[i].z); if (m_Selections.ContainsKey(_ipos)) { continue; } selection[_ipos] = (byte)0xfe; } } else { if (m_Selections.ContainsKey(ipos)) { continue; } BSVoxel voxel = dataSource.Read(ipos.x, ipos.y, ipos.z); if (!dataSource.VoxelIsZero(voxel, 1)) { selection[ipos] = (byte)0xfe; } } } } } } else if (mode == 1) { for (float x = iMin.x; x < iMax.x; x += dataSource.Scale) { for (float y = iMin.y; y < iMax.y; y += dataSource.Scale) { for (float z = iMin.z; z < iMax.z; z += dataSource.Scale) { IntVector3 ipos = new IntVector3(Mathf.FloorToInt(x * dataSource.ScaleInverted), Mathf.FloorToInt(y * dataSource.ScaleInverted), Mathf.FloorToInt(z * dataSource.ScaleInverted)); // if (!m_Selections.ContainsKey(ipos)) // continue; List <IntVector4> ext_posList = null; List <BSVoxel> ext_voxels = null; if (dataSource.ReadExtendableBlock(new IntVector4(ipos, 0), out ext_posList, out ext_voxels)) { for (int i = 0; i < ext_voxels.Count; i++) { IntVector3 _ipos = new IntVector3(ext_posList[i].x, ext_posList[i].y, ext_posList[i].z); if (!m_Selections.ContainsKey(_ipos)) { continue; } removes[_ipos] = new byte(); } } else { if (!m_Selections.ContainsKey(ipos)) { continue; } removes[ipos] = new byte(); } } } } } else if (mode == 2) { for (float x = iMin.x; x < iMax.x; x += dataSource.Scale) { for (float y = iMin.y; y < iMax.y; y += dataSource.Scale) { for (float z = iMin.z; z < iMax.z; z += dataSource.Scale) { IntVector3 ipos = new IntVector3(Mathf.FloorToInt(x * dataSource.ScaleInverted), Mathf.FloorToInt(y * dataSource.ScaleInverted), Mathf.FloorToInt(z * dataSource.ScaleInverted)); List <IntVector4> ext_posList = null; List <BSVoxel> ext_voxels = null; if (dataSource.ReadExtendableBlock(new IntVector4(ipos, 0), out ext_posList, out ext_voxels)) { bool remove = false; for (int i = 0; i < ext_voxels.Count; i++) { if (m_Selections.ContainsKey(new IntVector3(ext_posList[i].x, ext_posList[i].y, ext_posList[i].z))) { for (int _i = 0; _i < ext_voxels.Count; _i++) { IntVector3 _ipos = new IntVector3(ext_posList[_i].x, ext_posList[_i].y, ext_posList[_i].z); removes[_ipos] = new byte(); } remove = true; break; } } if (!remove) { for (int i = 0; i < ext_voxels.Count; i++) { selection[new IntVector3(ext_posList[i].x, ext_posList[i].y, ext_posList[i].z)] = (byte)0xfe; } } } else { if (m_Selections.ContainsKey(ipos)) { removes[ipos] = (byte)0xfe; } else { BSVoxel voxel = dataSource.Read(ipos.x, ipos.y, ipos.z); if (!dataSource.VoxelIsZero(voxel, 1)) { selection[ipos] = (byte)0xfe; } } } } } } } if (selection.Count - removes.Count + m_Selections.Count > MaxVoxelCount) { selection.Clear(); removes.Clear(); return(false); } // For History Dictionary <IntVector3, byte> old_seletion = new Dictionary <IntVector3, byte>(m_Selections); bool changed = false; foreach (IntVector3 key in removes.Keys) { changed = true; RemoveSelection(key); } foreach (KeyValuePair <IntVector3, byte> kvp in selection) { changed = true; AddSelection(kvp.Key, kvp.Value); } selection.Clear(); removes.Clear(); // For History if (changed) { Dictionary <IntVector3, byte> new_seletion = new Dictionary <IntVector3, byte>(m_Selections); BSSelectedBoxModify modify = new BSSelectedBoxModify(old_seletion, new_seletion, this); m_Action.AddModify(modify); } return(true); }
protected void Update() { if (dataSource == null) { return; } if (BSInput.s_MouseOnUI) { return; } if (_datasource == dataSource) { // Clear and rebuild; ClearSelection(null); _datasource = dataSource; } if (seletionBoxeRenderer != null) { seletionBoxeRenderer.m_Boxes = m_SelectionBoxes; seletionBoxeRenderer.scale = dataSource.Scale; seletionBoxeRenderer.offset = dataSource.Offset; } if (m_RecalcBoxes) { CalcBoxes(); m_RecalcBoxes = false; } if (GameConfig.IsInVCE) { return; } // Depth if (!BSInput.s_Shift && Input.GetKeyDown(KeyCode.UpArrow)) { Depth = ++Depth >= maxDragSize ? maxDragSize : Depth; m_GUIAlpha = 5; } else if (!BSInput.s_Shift && Input.GetKeyDown(KeyCode.DownArrow)) { Depth = --Depth >= 1 ? Depth : 1; m_GUIAlpha = 5; } m_GUIAlpha = Mathf.Lerp(m_GUIAlpha, 0, 0.05f); // Drag Box // Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (!m_Selecting) { // Cancel if (BSInput.s_Cancel) { if (!canDo) { return; } Dictionary <IntVector3, byte> old_seletion = new Dictionary <IntVector3, byte>(m_Selections); Cancel(); Dictionary <IntVector3, byte> new_selection = new Dictionary <IntVector3, byte>(m_Selections); // For History if (old_seletion.Count != 0) { BSSelectedBoxModify modify = new BSSelectedBoxModify(old_seletion, new_selection, this); m_Action.AddModify(modify); DoHistory(); } return; } if (BSMath.RayCastDrawTarget(ray, dataSource, out m_Target, minvol, true, BuildingMan.Datas)) { m_Drawing = true; m_Begin = m_Target.snapto; _beginPos = m_Begin; m_End = m_Begin; float vx = Mathf.Abs(m_Target.rch.normal.x); float vy = Mathf.Abs(m_Target.rch.normal.y); float vz = Mathf.Abs(m_Target.rch.normal.z); if (vx > 0.9f * m_Target.ds.Scale) { m_Coord = ECoordPlane.ZY; m_PlanePos = m_Target.rch.point.x; } else if (vy > 0.9f * m_Target.ds.Scale) { m_Coord = ECoordPlane.XZ; m_PlanePos = m_Target.rch.point.y; } else if (vz > 0.9f * m_Target.ds.Scale) { m_Coord = ECoordPlane.XY; m_PlanePos = m_Target.rch.point.z; } if (Input.GetMouseButtonDown(0)) { if (canDo) { m_Selecting = true; } } } else { m_Drawing = false; } } // Selecting else { m_Drawing = true; // Cancel if (BSInput.s_Cancel) { if (!canDo) { return; } m_Selecting = false; m_Begin = new Vector3(-10000, -10000, -10000); m_End = new Vector3(-10000, -10000, -10000); return; } RaycastHit rch; if (BSMath.RayCastCoordPlane(ray, m_Coord, m_PlanePos, out rch)) { Vector3 point = rch.point - dataSource.Offset; if (m_Coord == ECoordPlane.XY) { // x componet float x = 0; m_Begin.x = CalcValue(point.x, _beginPos.x, out x); // y componet float y = 0; m_Begin.y = CalcValue(point.y, _beginPos.y, out y); m_End.x = x; m_End.y = y; m_End.z = Mathf.FloorToInt(point.z * dataSource.ScaleInverted) * dataSource.Scale; if (m_Target.rch.normal.z > 0) { m_Begin.z = m_PlanePos - Depth * dataSource.Scale; } else { m_Begin.z = m_PlanePos + Depth * dataSource.Scale; } m_End = Clamp(m_Begin, m_End); } else if (m_Coord == ECoordPlane.XZ) { // x componet float x = 0; m_Begin.x = CalcValue(point.x, _beginPos.x, out x); // z componet float z = 0; m_Begin.z = CalcValue(point.z, _beginPos.z, out z); m_End.x = x; m_End.y = Mathf.FloorToInt(point.y * dataSource.ScaleInverted) * dataSource.Scale; m_End.z = z; if (m_Target.rch.normal.y > 0) { m_Begin.y = m_PlanePos - Depth * dataSource.Scale; } else { m_Begin.y = m_PlanePos + Depth * dataSource.Scale; } m_End = Clamp(m_Begin, m_End); } else if (m_Coord == ECoordPlane.ZY) { // y componet float y = 0; m_Begin.y = CalcValue(point.y, _beginPos.y, out y); // z componet float z = 0; m_Begin.z = CalcValue(point.z, _beginPos.z, out z); m_End.x = Mathf.FloorToInt(point.x * dataSource.ScaleInverted) * dataSource.Scale; m_End.y = y; m_End.z = z; if (m_Target.rch.normal.x > 0) { m_Begin.x = m_PlanePos - Depth * dataSource.Scale; } else { m_Begin.x = m_PlanePos + Depth * dataSource.Scale; } m_End = Clamp(m_Begin, m_End); } } // In Valid area ? if (m_PrevDS != null && m_PrevDS == dataSource) { if (m_Selections.Count != 0) { BSTools.SelBox box = new BSTools.SelBox(); box.m_Box.xMin = (short)Mathf.FloorToInt(Mathf.Min(m_Begin.x, m_End.x) * dataSource.ScaleInverted); box.m_Box.yMin = (short)Mathf.FloorToInt(Mathf.Min(m_Begin.y, m_End.y) * dataSource.ScaleInverted); box.m_Box.zMin = (short)Mathf.FloorToInt(Mathf.Min(m_Begin.z, m_End.z) * dataSource.ScaleInverted); box.m_Box.xMax = (short)Mathf.FloorToInt(Mathf.Max(m_Begin.x, m_End.x) * dataSource.ScaleInverted); box.m_Box.yMax = (short)Mathf.FloorToInt(Mathf.Max(m_Begin.y, m_End.y) * dataSource.ScaleInverted); box.m_Box.zMax = (short)Mathf.FloorToInt(Mathf.Max(m_Begin.z, m_End.z) * dataSource.ScaleInverted); // Add current box to list temporarily m_SelectionBoxes.Add(box); BSTools.IntBox bound = BSTools.SelBox.CalculateBound(m_SelectionBoxes); Vector3 size = new Vector3(bound.xMax - bound.xMin, bound.yMax - bound.yMin, bound.zMax - bound.zMin); if (size.x > maxSelectBoxSize.x || size.y > maxSelectBoxSize.y || size.z > maxSelectBoxSize.z) { m_IsValidBox = false; } else { m_IsValidBox = true; } // revert the list m_SelectionBoxes.RemoveAt(m_SelectionBoxes.Count - 1); } else { m_IsValidBox = true; } } else { m_IsValidBox = true; } if (Input.GetMouseButtonUp(0)) { if (!canDo) { return; } // bool result = false; if (m_IsValidBox) { // Add if (m_PrevDS == dataSource) { if (BSInput.s_Shift) { if (m_PrevDS == dataSource) { /*result = */ CalcSelection(0); } } // Substract else if (BSInput.s_Alt) { /*result = */ CalcSelection(1); } // Cross else if (BSInput.s_Control) { /*result = */ CalcSelection(2); } else { ClearSelection(m_Action); /*result = */ CalcSelection(0); } m_PrevDS = dataSource; } else { ClearSelection(m_Action); /*result = */ CalcSelection(0); m_PrevDS = dataSource; } } m_Selecting = false; ResetValue(); } } // Other Ajust if (AfterSelectionUpdate()) { DoHistory(); } }