// Paint a specified mesh position void PaintPosition(Vector3 wpos, Vector3 normal) { float voxel_size = VCEditor.s_Scene.m_Setting.m_VoxelSize; VCEditor.s_Mirror.CalcPrepare(voxel_size); // calculate the right & up axis transform.rotation = Quaternion.LookRotation(-normal); Vector3 right = transform.right; Vector3 up = transform.up; transform.rotation = Quaternion.identity; float r = Mathf.Clamp(m_Radius, 0.25f, 16.0f); Vector3 pivot = wpos + normal * voxel_size; for (float a = -r; a <= r + 0.001f; a += 0.25f) { for (float b = -r; b <= r + 0.001f; b += 0.25f) { if (a * a + b * b > r * r) { continue; } float strength = 1; if (r > 0.75f && m_Hardness < 1) { strength = (1 - Mathf.Sqrt(a * a + b * b) / r) / (1 - m_Hardness); strength = Mathf.Pow(strength, 2); strength = Mathf.Clamp01(strength); } Vector3 origin = pivot + (a * right + b * up) * voxel_size; Ray ray = new Ray(origin, -normal); RaycastHit rch; if (VCEMath.RayCastMesh(ray, out rch, voxel_size * 2)) { Vector3 iso_pos = rch.point / VCEditor.s_Scene.m_Setting.m_VoxelSize; MeshFilter mf = rch.collider.GetComponent <MeshFilter>(); ColorPosition(iso_pos, mf, strength * m_Strength); } } } }
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); } } } } }