public void ColorSelection(Color32 color, bool consider_strength = true, bool action_segment = false) { if (!VCEditor.Instance.m_UI.m_PaintTab.isChecked) { return; } if (!action_segment) { m_Action = new VCEAction(); } bool modified = false; VCEUpdateColorSign sign_b = new VCEUpdateColorSign(false, true); m_Action.Modifies.Add(sign_b); VCEditor.s_Mirror.CalcPrepare(VCEditor.s_Scene.m_Setting.m_VoxelSize); foreach (SelBox sb in m_SelectionMgr.m_GL.m_Boxes) { float t = (float)(sb.m_Val) / 255.0f; byte code; // This is a filter code, when color key was not on edge or vertex, their is no point to color this key. float x, y, z; for (x = sb.m_Box.xMin, code = 0; x <= sb.m_Box.xMax + 1.01f; x += 0.5f, code ^= 1) { for (y = sb.m_Box.yMin, code &= 1; y <= sb.m_Box.yMax + 1.01f; y += 0.5f, code ^= 2) { if (code == 0 || code == 4) { continue; // code 0, 4, no point to color } for (z = sb.m_Box.zMin, code &= 3; z <= sb.m_Box.zMax + 1.01f; z += 0.5f, code ^= 4) { if (code == 1 || code == 2) { continue; // code 1, 2, no point to color } // Mirror if (VCEditor.s_Mirror.Enabled_Masked) { IntVector3 color_pos = VCIsoData.IPosToColorPos(new Vector3(x, y, z)); VCEditor.s_Mirror.MirrorColor(color_pos); for (int i = 0; i < VCEditor.s_Mirror.OutputCnt; ++i) { if (VCEditor.s_Scene.m_IsoData.IsColorPosIn(VCEditor.s_Mirror.Output[i])) { int key = VCIsoData.ColorPosToColorKey(VCEditor.s_Mirror.Output[i]); Color32 old_color = VCEditor.s_Scene.m_IsoData.GetColor(key); Color32 new_color = consider_strength ? Color32.Lerp(old_color, color, t) : color; if (old_color.r == new_color.r && old_color.g == new_color.g && old_color.b == new_color.b && old_color.a == new_color.a) { continue; } VCEAlterColor modify = new VCEAlterColor(key, old_color, new_color); modify.Redo(); m_Action.Modifies.Add(modify); modified = true; } } } // No mirror else { int key = VCIsoData.IPosToColorKey(new Vector3(x, y, z)); Color32 old_color = VCEditor.s_Scene.m_IsoData.GetColor(key); Color32 new_color = consider_strength ? Color32.Lerp(old_color, color, t) : color; if (old_color.r == new_color.r && old_color.g == new_color.g && old_color.b == new_color.b && old_color.a == new_color.a) { continue; } VCEAlterColor modify = new VCEAlterColor(key, old_color, new_color); m_Action.Modifies.Add(modify); modified = true; } } } } } VCEUpdateColorSign sign_f = new VCEUpdateColorSign(true, false); m_Action.Modifies.Add(sign_f); if (action_segment && !modified) { m_Action.Modifies.RemoveRange(m_Action.Modifies.Count - 2, 2); } if (!action_segment && m_Action.Modifies.Count > 2) { m_Action.Do(); if (color.r == VCIsoData.BLANK_COLOR.r && color.g == VCIsoData.BLANK_COLOR.g && color.b == VCIsoData.BLANK_COLOR.b && color.a == VCIsoData.BLANK_COLOR.a) { VCEStatusBar.ShowText("Selection color have been erased".ToLocalizationString(), 2); } else { VCEStatusBar.ShowText("Selected voxels have been painted".ToLocalizationString(), 2); } } }
void Update() { // Save recent vars s_RecentRadius = m_Radius; s_RecentHardness = m_Hardness; s_RecentStrength = m_Strength; // Prepare collider if (!VCEditor.s_Scene.m_MeshComputer.Computing) { if (m_MeshMgr.m_ColliderDirty) { m_MeshMgr.PrepareMeshColliders(); } } if (m_MeshMgr.m_ColliderDirty) { return; } // Color ( target & display ) m_TargetColor = m_Eraser ? VCIsoData.BLANK_COLOR : VCEditor.SelectedColor; m_UIColor = m_TargetColor; m_UIColor.a = 1; // Update mesh color foreach (MeshFilter mf in m_NeedUpdateMfs) { m_MeshMgr.UpdateMeshColor(mf); } m_NeedUpdateMfs.Clear(); // Drawing if (m_Drawing) { if (VCEInput.s_Cancel) { m_Drawing = false; if (m_Action != null) { m_Action.Undo(); m_Action = null; } else { Debug.LogError("There must be some problem"); } } else { if (Input.GetMouseButtonUp(0)) { m_Drawing = false; if (m_Action != null) { VCEUpdateColorSign sign_f = new VCEUpdateColorSign(true, false); m_Action.Modifies.Add(sign_f); if (m_Action.Modifies.Count > 2) { m_Action.Do(); } m_Action = null; } else { Debug.LogError("There must be some problem"); } } else { // Mouse is pressing // During drawing: From 2nd frame since mouse down // 1. Test hitpoint now RaycastHit rch; Vector3 hit; if (VCEMath.RayCastMesh(VCEInput.s_PickRay, out rch)) { hit = rch.point; m_simDist = rch.distance; } else { hit = VCEInput.s_PickRay.GetPoint(m_simDist); } // 2. Step by step ray cast Vector3 move_vec = hit - m_lastHit; if (move_vec.magnitude > m_simStep) { float ustep = m_simStep / move_vec.magnitude; // traverse all the interpolation points for (float t = ustep; t < 0.999f + ustep; t += ustep) { t = Mathf.Clamp01(t); Vector3 inter_point = m_lastHit + t * move_vec; Ray test_ray = new Ray(VCEInput.s_PickRay.origin, (inter_point - VCEInput.s_PickRay.origin).normalized); if (VCEMath.RayCastMesh(test_ray, out rch)) { m_simDist = rch.distance; if ((rch.point - m_lastDraw).magnitude > m_drawStep) { PaintPosition(rch.point, rch.normal); m_lastDraw = rch.point; Debug.DrawRay(test_ray.origin, inter_point - VCEInput.s_PickRay.origin, m_UIColor, 10.0f); } else { Debug.DrawRay(test_ray.origin, inter_point - VCEInput.s_PickRay.origin, new Color(m_UIColor.r, m_UIColor.g, m_UIColor.b, 0.2f), 10.0f); } } else { Debug.DrawRay(test_ray.origin, inter_point - VCEInput.s_PickRay.origin, new Color(m_UIColor.r, m_UIColor.g, m_UIColor.b, 0.1f), 10.0f); } } // 3. Update last hitpoint m_lastHit = hit; } } } } else { if (VCEInput.s_Cancel) { Cancel(); } else { if (Input.GetMouseButtonDown(0) && !VCEInput.s_MouseOnUI) { m_Drawing = true; if (m_Action != null) { Debug.LogError("There must be some problem"); m_Action = null; } m_Action = new VCEAction(); VCEUpdateColorSign sign_b = new VCEUpdateColorSign(false, true); m_Action.Modifies.Add(sign_b); // draw once // Init continous drawing vars m_lastHit = Vector3.zero; m_lastDraw = Vector3.one * (-100); m_simStep = Mathf.Clamp(m_Radius * 0.07f, 0.2f, 100.0f) * VCEditor.s_Scene.m_Setting.m_VoxelSize; m_drawStep = Mathf.Clamp(m_Radius * 0.5f, 0.2f, 100.0f) * VCEditor.s_Scene.m_Setting.m_VoxelSize; m_simDist = VCEditor.s_Scene.m_Setting.EditorWorldSize.magnitude * 0.2f; RaycastHit rch; // cast if (VCEMath.RayCastMesh(VCEInput.s_PickRay, out rch)) { PaintPosition(rch.point, rch.normal); m_lastHit = rch.point; m_lastDraw = rch.point; m_simDist = rch.distance; } // no cast else { m_lastHit = VCEInput.s_PickRay.GetPoint(m_simDist); } } } } }