private static void EditFaces(OccluderVolumeEditingContext ctx, int currentFaceId, Vector3[] verts, Matrix4x4 inverse, Matrix4x4 transform) { foreach (var face in ctx.faces) { var id = GUIUtility.GetControlID(FocusType.Passive); var centroid = transform.MultiplyPoint(face.centroid); var normal = Vector3.Normalize(transform.MultiplyVector(face.normal)); if (currentFaceId != id && Vector3.Dot(normal, Camera.current.transform.position - centroid) < 0) { continue; } float size = HandleUtility.GetHandleSize(centroid) * 0.5f; Vector3 snap = Vector3.one * 0.5f; Handles.color = Color.yellow; // draw a small X at the arrow origin to make it easier to see where it starts var u = Vector3.Cross(normal, transform.GetColumn(1)); if (Vector3.SqrMagnitude(u) < 0.1f) { u = Vector3.Cross(normal, transform.GetColumn(0)); } u = Vector3.Normalize(u); var v = Vector3.Normalize(Vector3.Cross(normal, u)); Handles.DrawLine(centroid - (u + v) * 0.1f, centroid + (u + v) * 0.1f); Handles.DrawLine(centroid - (u - v) * 0.1f, centroid + (u - v) * 0.1f); Handles.CircleHandleCap(-1, centroid, Quaternion.LookRotation(normal, u), 0.1f * Mathf.Sqrt(2), EventType.Repaint); var newCentroid = Handles.Slider(id, centroid, normal, size * 1.5f, Handles.ArrowHandleCap, 0.5f); if (GUIUtility.hotControl == id) { ctx.Dragging = id; } newCentroid = centroid + math.dot(newCentroid - centroid, normal) * normal; var dn = inverse.MultiplyVector(newCentroid - centroid); for (int i = 0; i < face.vertices.Length; i++) { verts[face.vertices[i]] += dn; } } }
private static void RenderWireframe(OccluderVolumeEditingContext ctx, Occluder occluder, Mesh mesh, Vector3[] verts, bool frontFacing) { var transform = occluder.localTransform; foreach (var face in ctx.faces) { var p = transform.MultiplyPoint(face.centroid); if (Vector3.Dot(transform.MultiplyVector(face.normal), Camera.current.transform.position - p) < 0) { if (!frontFacing) { Handles.color = Color.white; for (int i = 0; i < face.vertices.Length; i++) { var a = verts[face.vertices[i]]; var b = verts[face.vertices[(i + 1) % face.vertices.Length]]; Handles.DrawDottedLine(transform.MultiplyPoint(a), transform.MultiplyPoint(b), 2); } } } else if (frontFacing) { Handles.color = Color.white; for (int i = 0; i < face.vertices.Length; i++) { var a = transform.MultiplyPoint(verts[face.vertices[i]]); var b = transform.MultiplyPoint(verts[face.vertices[(i + 1) % face.vertices.Length]]); Handles.DrawBezier(a, b, a, b, Color.white, null, 6); } } } /* foreach (var edge in ctx.edges) * { * var t1 = ctx.tris[edge.t[0]]; * var t2 = ctx.tris[edge.t[1]]; * * if (Vector3.Dot(t1.normal, t2.normal) > 0.99f) * { * continue; * } * * var n1 = occluder.localTransform.MultiplyVector(t1.normal); * var n2 = occluder.localTransform.MultiplyVector(t2.normal); * * var a = occluder.localTransform.MultiplyPoint(verts[edge.v[0]]); * var b = occluder.localTransform.MultiplyPoint(verts[edge.v[1]]); * var d = Camera.current.transform.position - a; * * if (Vector3.Dot(n1, d) < 0 && Vector3.Dot(n2, d) < 0) * { * if (!frontFacing) * { * Handles.color = Color.white;// grey; * Handles.DrawDottedLine(a, b, 2); * } * } * else if (frontFacing) * { * Handles.DrawBezier(a, b, a, b, Color.white, null, 6); * } * }*/ }
private void EditVertices(OccluderVolumeEditingContext ctx, Mesh mesh, Vector3[] verts, Matrix4x4 inverse, Matrix4x4 transform) { var transformed = new Vector3[mesh.vertexCount]; var marqueeSize = (marqueeEnd - marqueeStart); marqueeSize.Set(Mathf.Abs(marqueeSize.x), Mathf.Abs(marqueeSize.y)); Rect marqueeRect = new Rect { x = Mathf.Min(marqueeStart.x, marqueeEnd.x), y = Mathf.Min(marqueeStart.y, marqueeEnd.y), width = marqueeSize.x, height = marqueeSize.y }; for (int i = 0; i < mesh.vertexCount; i++) { var p = transform.MultiplyPoint(verts[i]); transformed[i] = p; } if (marqueeSelectionEnded) { marqueeSelectionEnded = false; for (int i = 0; i < mesh.vertexCount; i++) { var screenPoint = HandleUtility.WorldToGUIPoint(transformed[i]); if (marqueeRect.Contains(screenPoint)) { ctx.VertexSelection.Add(i); } } } for (int i = 0; i < mesh.vertexCount; i++) { var p = transformed[i]; float size = HandleUtility.GetHandleSize(p) * 0.5f; Vector3 snap = Vector3.one * 0.5f; bool isSelected = ctx.VertexSelection.Contains(i); Handles.color = isSelected ? Handles.selectedColor : Color.grey; if (marqueeSelection) { var screenPoint = HandleUtility.WorldToGUIPoint(p); if (marqueeRect.Contains(screenPoint)) { Handles.color = Handles.preselectionColor; } } if (isSelected) { size *= 1.2f; } if (Handles.Button(p, Quaternion.identity, 0.5f * size, size, Handles.SphereHandleCap)) { if (Event.current.modifiers == EventModifiers.Shift) { if (isSelected) { // deselect in a multiselection ctx.VertexSelection.Remove(i); } else { ctx.VertexSelection.Add(i); } } else { ctx.VertexSelection.Clear(); if (!isSelected) { ctx.VertexSelection.Add(i); } } } verts[i] = inverse.MultiplyPoint(p); } var selectedVertexCount = ctx.VertexSelection.Count; if (selectedVertexCount > 0) { var center = Vector3.zero; foreach (var v in ctx.VertexSelection) { center += transformed[v]; } center /= selectedVertexCount; float size = HandleUtility.GetHandleSize(center) * 0.5f; Vector3 snap = Vector3.one * 0.5f; foreach (var v in ctx.VertexSelection) { var p = transformed[v]; Handles.color = Color.magenta; Handles.DrawDottedLine(p, center, 1); } var delta = Vector3.zero; foreach (var v in ctx.VertexSelection) { var p = transformed[v]; Handles.color = Color.red; var newX = Handles.Slider(p, transform.GetColumn(0), size * 1.5f, Handles.ArrowHandleCap, 0.5f); Handles.color = Color.green; var newY = Handles.Slider(p, transform.GetColumn(1), size * 1.5f, Handles.ArrowHandleCap, 0.5f); Handles.color = Color.blue; var newZ = Handles.Slider(p, transform.GetColumn(2), size * 1.5f, Handles.ArrowHandleCap, 0.5f); delta += newX + newY + newZ - p * 3; } delta = inverse.MultiplyVector(delta); foreach (var v in ctx.VertexSelection) { verts[v] += delta; } } }