private void Paint(Camera camera, Vector2 mousePosition, bool force) { var brush = P3dWindowData.Instance.Brush; if (painting == true && brush.DragStep > 0.01f) { var delta = mousePosition - lastMousePosition; var steps = Mathf.FloorToInt(delta.magnitude / brush.DragStep); if (steps > 0) { var step = P3dHelper.Reciprocal(steps); for (var i = 0; i < steps; i++) { Paint(camera, Vector2.Lerp(lastMousePosition, mousePosition, i * step)); } lastMousePosition = mousePosition; } } else { Paint(camera, mousePosition); lastMousePosition = mousePosition; } }
public void SetMaterial(P3dBlendMode blendMode, Texture texture, Texture shape, P3dChannel shapeChannel, float hardness, float wrapping, float normalBack, float normalFront, float normalFade, Color color, float opacity, Texture tileTexture, Matrix4x4 tileMatrix, float tileBlend) { switch (Extrusions) { case 0: Material = cachedSpotMaterials[blendMode]; break; case 1: Material = cachedLineMaterials[blendMode]; break; case 2: Material = cachedQuadMaterials[blendMode]; break; } Blend = blendMode; Color = color; Opacity = opacity; Hardness = hardness; Wrapping = wrapping; Texture = texture; Shape = shape; ShapeChannel = P3dHelper.IndexToVector((int)shapeChannel); TileTexture = tileTexture; TileMatrix = tileMatrix; TileBlend = tileBlend; var pointA = normalFront - 1.0f - normalFade; var pointB = normalFront - 1.0f; var pointC = 1.0f - normalBack + normalFade; var pointD = 1.0f - normalBack; NormalFront = new Vector2(pointA, P3dHelper.Reciprocal(pointB - pointA)); NormalBack = new Vector2(pointC, P3dHelper.Reciprocal(pointD - pointC)); }
private void Draw(Vector2 a, Vector2 b, Vector2 c, Vector2 d, float pressure) { var steps = CalculateSteps(b - c); var step = P3dHelper.Reciprocal(steps); for (var i = 1; i <= steps; i++) { var screenPosition = Hermite(a, b, c, d, i * step); PaintAt(screenPosition, false, pressure); } }
public void SetMaterial(P3dBlendMode blendMode, Texture decal, float hardness, float normalBack, float normalFront, float normalFade, Color color, float opacity, Texture shape) { Material = cachedMaterials[(int)blendMode]; Swap = cachedSwaps[(int)blendMode]; Color = color; Opacity = opacity; Hardness = hardness; Texture = decal; Shape = shape; var pointA = normalFront - 1.0f - normalFade; var pointB = normalFront - 1.0f; var pointC = 1.0f - normalBack; var pointD = 1.0f - normalBack + normalFade; NormalFront = new Vector2(pointA, P3dHelper.Reciprocal(pointB - pointA)); NormalBack = new Vector2(pointC, P3dHelper.Reciprocal(pointD - pointC)); }
private void PaintSmooth(Link link, bool down, float pixelSpacing) { var head = link.Finger.GetSmoothScreenPosition(0.0f); if (down == true) { if (storeStates == true) { P3dStateManager.StoreAllStates(); } RecordAndPaintAt(link, link.Finger.ScreenPosition, link.ScreenOld, false, link.Finger.Pressure, link); } if (pixelSpacing > 0.0f) { var steps = Mathf.Max(1, Mathf.FloorToInt(link.Finger.SmoothScreenPositionDelta)); var step = P3dHelper.Reciprocal(steps); for (var i = 0; i <= steps; i++) { var next = link.Finger.GetSmoothScreenPosition(Mathf.Clamp01(i * step)); var dist = Vector2.Distance(head, next); var gaps = Mathf.FloorToInt((link.Distance + dist) / pixelSpacing); for (var j = 0; j < gaps; j++) { var remainder = pixelSpacing - link.Distance; head = Vector2.MoveTowards(head, next, remainder); RecordAndPaintAt(link, head, link.History[link.History.Count - 1], false, link.Finger.Pressure, link); dist -= remainder; link.Distance = 0.0f; } link.Distance += dist; head = next; } } }
private void UpdateFinger(int index, Vector2 screenPosition, float pressure, bool up) { for (var i = fingers.Count - 1; i >= 0; i--) { var finger = fingers[i]; if (finger.Index == index) { finger.Pressure = pressure; finger.Down = false; finger.Up = up; finger.PositionD = finger.PositionC; finger.PositionC = finger.PositionB; finger.PositionB = finger.PositionA; finger.PositionA = screenPosition; finger.SmoothPositions.Clear(); finger.SmoothPositions.Add(finger.PositionC); if (up == true) { finger.SmoothPositions.Add(finger.PositionB); finger.SmoothPositions.Add(finger.PositionA); } else { var steps = Mathf.FloorToInt(Vector2.Distance(finger.PositionB, finger.PositionC)); var step = P3dHelper.Reciprocal(steps); for (var j = 1; j <= steps; j++) { var head = Hermite(finger.PositionD, finger.PositionC, finger.PositionB, finger.PositionA, j * step); finger.SmoothPositions.Add(head); } } break; } } }
protected override void OnInspector() { EditorGUILayout.BeginHorizontal(); var newMesh = (Mesh)EditorGUILayout.ObjectField("Mesh", mesh, typeof(Mesh), false); if (GUILayout.Button("Refresh", EditorStyles.miniButton, GUILayout.Width(50)) == true) { ready = false; } EditorGUILayout.EndHorizontal(); if (newMesh != mesh) { ready = false; mesh = newMesh; } if (mesh != null) { if (mesh.subMeshCount != submeshNames.Length) { var submeshNamesList = new List <string>(); for (var i = 0; i < mesh.subMeshCount; i++) { submeshNamesList.Add(i.ToString()); } submeshNames = submeshNamesList.ToArray(); } EditorGUILayout.Separator(); var newSubmesh = EditorGUILayout.Popup("Submesh", submesh, submeshNames); var newCoord = EditorGUILayout.Popup("Coord", coord, new string[] { "UV0", "UV1", "UV2", "UV3" }); var newMode = EditorGUILayout.Popup("Mode", mode, new string[] { "Texcoord", "Triangles" }); if (mode == 1) // Triangles { EditorGUILayout.BeginHorizontal(); var newPitch = EditorGUILayout.FloatField("Pitch", pitch); var newYaw = EditorGUILayout.FloatField("Yaw", yaw); EditorGUILayout.EndHorizontal(); if (newPitch != pitch || newYaw != yaw) { ready = false; pitch = newPitch; yaw = newYaw; } } EditorGUILayout.Separator(); EditorGUILayout.LabelField("Triangles", EditorStyles.boldLabel); EditorGUI.BeginDisabledGroup(true); EditorGUILayout.BeginHorizontal(); EditorGUILayout.IntField("Total", triangleCount); P3dHelper.BeginColor(invalidCount > 0); EditorGUILayout.IntField("With No UV", invalidCount); P3dHelper.EndColor(); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); P3dHelper.BeginColor(outsideCount > 0); EditorGUILayout.IntField("Out Of Bounds", outsideCount); P3dHelper.EndColor(); P3dHelper.BeginColor(partiallyCount > 0); EditorGUILayout.IntField("Partially Out Of Bounds", partiallyCount); P3dHelper.EndColor(); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); P3dHelper.BeginColor(utilizationPercent < 40.0f); EditorGUILayout.FloatField("Utilization %", utilizationPercent); P3dHelper.EndColor(); P3dHelper.BeginColor(overlapPercent > 0); EditorGUILayout.FloatField("Overlap %", overlapPercent); P3dHelper.EndColor(); EditorGUILayout.EndHorizontal(); EditorGUI.EndDisabledGroup(); if (coord != newCoord || newSubmesh != submesh || newMode != mode || ready == false) { ready = true; coord = newCoord; submesh = newSubmesh; mode = newMode; listA.Clear(); listB.Clear(); ratioList.Clear(); mesh.GetTriangles(indices, submesh); mesh.GetVertices(positions); mesh.GetUVs(coord, coords); triangleCount = indices.Count / 3; invalidCount = 0; outsideCount = 0; partiallyCount = 0; overlapTex = P3dHelper.Destroy(overlapTex); utilizationPercent = 0.0f; overlapPercent = 0.0f; if (coords.Count > 0) { if (mode == 0) // Texcoord { BakeOverlap(); } var rot = Quaternion.Euler(pitch, yaw, 0.0f); var off = -mesh.bounds.center; var mul = P3dHelper.Reciprocal(mesh.bounds.size.magnitude); var half = Vector3.one * 0.5f; for (var i = 0; i < indices.Count; i += 3) { var positionA = positions[indices[i + 0]]; var positionB = positions[indices[i + 1]]; var positionC = positions[indices[i + 2]]; var coordA = coords[indices[i + 0]]; var coordB = coords[indices[i + 1]]; var coordC = coords[indices[i + 2]]; var outside = 0; outside += IsOutside(coordA) ? 1 : 0; outside += IsOutside(coordB) ? 1 : 0; outside += IsOutside(coordC) ? 1 : 0; var area = Vector3.Cross(coordA - coordB, coordA - coordC).sqrMagnitude; var invalid = area <= float.Epsilon; if (invalid == true) { invalidCount++; } if (outside == 3) { outsideCount++; } if (outside == 1 || outside == 2) { partiallyCount++; } if (mode == 0) // Texcoord { listA.Add(coordA); listA.Add(coordB); listA.Add(coordB); listA.Add(coordC); listA.Add(coordC); listA.Add(coordA); } if (mode == 1) // Triangles { positionA = half + rot * (off + positionA) * mul; positionB = half + rot * (off + positionB) * mul; positionC = half + rot * (off + positionC) * mul; positionA.z = positionB.z = positionC.z = 0.0f; listA.Add(positionA); listA.Add(positionB); listA.Add(positionB); listA.Add(positionC); listA.Add(positionC); listA.Add(positionA); if (invalid == true) { listB.Add(positionA); listB.Add(positionB); listB.Add(positionB); listB.Add(positionC); listB.Add(positionC); listB.Add(positionA); } } } } else { invalidCount = triangleCount; } arrayA = listA.ToArray(); arrayB = listB.ToArray(); } var rect = EditorGUILayout.BeginVertical(); GUILayout.FlexibleSpace(); EditorGUILayout.EndVertical(); var pos = rect.min; var siz = rect.size; GUI.Box(rect, ""); if (mode == 0 && overlapTex != null) // Texcoord { GUI.DrawTexture(rect, overlapTex); } Handles.BeginGUI(); if (listA.Count > 0) { for (var i = listA.Count - 1; i >= 0; i--) { var coord = listA[i]; coord.x = pos.x + siz.x * coord.x; coord.y = pos.y + siz.y * (1.0f - coord.y); arrayA[i] = coord; } Handles.DrawLines(arrayA); for (var i = listB.Count - 1; i >= 0; i--) { var coord = listB[i]; coord.x = pos.x + siz.x * coord.x; coord.y = pos.y + siz.y * (1.0f - coord.y); arrayB[i] = coord; } Handles.color = Color.red; Handles.DrawLines(arrayB); } Handles.EndGUI(); } else { EditorGUILayout.HelpBox("No Mesh Selected.\nTo select a mesh, click Analyze Mesh from the P3dPaintable component, or from the Mesh inspector context menu (gear icon at top right).", MessageType.Info); } }
private void Paint(P3dInputManager.Finger finger, bool down, bool up) { var link = GetLink(finger); if (spacing > 0.0f) { var head = finger.GetSmoothScreenPosition(0.0f); if (down == true) { if (storeStates == true) { P3dStateManager.StoreAllStates(); } PaintAt(link, head, false, finger.Pressure, link); } var steps = Mathf.Max(1, Mathf.FloorToInt(finger.SmoothScreenPositionDelta)); var step = P3dHelper.Reciprocal(steps); for (var i = 0; i <= steps; i++) { var next = finger.GetSmoothScreenPosition(Mathf.Clamp01(i * step)); var dist = Vector2.Distance(head, next); var gaps = Mathf.FloorToInt((link.Distance + dist) / spacing); for (var j = 0; j < gaps; j++) { var remainder = spacing - link.Distance; head = Vector2.MoveTowards(head, next, remainder); PaintAt(link, head, false, finger.Pressure, link); dist -= remainder; link.Distance = 0.0f; } link.Distance += dist; head = next; } } else { var preview = true; if (showPreview == true) { if (spacing == 0.0f) // Once { if (up == true) { if (storeStates == true) { P3dStateManager.StoreAllStates(); } preview = false; } } else // Every frame { if (storeStates == true && down == true) { P3dStateManager.StoreAllStates(); } preview = false; } } else { if (spacing == 0.0f) // Once { if (down == true) { if (storeStates == true) { P3dStateManager.StoreAllStates(); } } else { return; } } else // Every frame { if (storeStates == true && down == true) { P3dStateManager.StoreAllStates(); } } preview = false; } PaintAt(link, finger.PositionA, preview, finger.Pressure, link); } if (up == true) { BreakHits(link); if (draw == DrawType.PointsIn3DFilled) { PaintGridOfPoints(link); } link.Clear(); } }
protected override void OnInspector() { if (mesh != null) { EditorGUI.BeginDisabledGroup(true); EditorGUILayout.ObjectField("Mesh", mesh, typeof(Mesh), false); EditorGUI.EndDisabledGroup(); if (mesh.subMeshCount != submeshNames.Length) { var submeshNamesList = new List <string>(); for (var i = 0; i < mesh.subMeshCount; i++) { submeshNamesList.Add(i.ToString()); } submeshNames = submeshNamesList.ToArray(); } EditorGUILayout.Separator(); var newSubmesh = EditorGUILayout.Popup("Submesh", submesh, submeshNames); var newCoord = EditorGUILayout.Popup("Coord", coord, new string[] { "UV0", "UV1", "UV2", "UV3" }); var newMode = EditorGUILayout.Popup("Mode", mode, new string[] { "Texcoord", "Triangles" }); var newRotation = EditorGUILayout.Vector3Field("Rotation", rotation); EditorGUILayout.Separator(); EditorGUILayout.LabelField("Triangles", EditorStyles.boldLabel); EditorGUI.BeginDisabledGroup(true); EditorGUILayout.IntField("Total", triangleCount); EditorGUILayout.IntField("With No UV", invalidCount); EditorGUI.EndDisabledGroup(); if (coord != newCoord || newSubmesh != submesh || newMode != mode || newRotation != rotation || ready == false) { ready = true; coord = newCoord; submesh = newSubmesh; mode = newMode; rotation = newRotation; listA.Clear(); listB.Clear(); ratioList.Clear(); mesh.GetTriangles(indices, submesh); mesh.GetVertices(positions); mesh.GetUVs(coord, coords); triangleCount = indices.Count / 3; invalidCount = 0; if (coords.Count > 0) { var rot = Quaternion.Euler(rotation); var off = -mesh.bounds.center; var mul = P3dHelper.Reciprocal(mesh.bounds.size.magnitude); var half = Vector3.one * 0.5f; for (var i = 0; i < indices.Count; i += 3) { var positionA = positions[indices[i + 0]]; var positionB = positions[indices[i + 1]]; var positionC = positions[indices[i + 2]]; var coordA = coords[indices[i + 0]]; var coordB = coords[indices[i + 1]]; var coordC = coords[indices[i + 2]]; var area = Vector3.Cross(coordA - coordB, coordA - coordC).sqrMagnitude; var invalid = area <= float.Epsilon; if (invalid == true) { invalidCount++; } if (mode == 0) // Texcoord { listA.Add(coordA); listA.Add(coordB); listA.Add(coordB); listA.Add(coordC); listA.Add(coordC); listA.Add(coordA); } if (mode == 1) // Triangles { positionA = half + rot * (off + positionA) * mul; positionB = half + rot * (off + positionB) * mul; positionC = half + rot * (off + positionC) * mul; positionA.z = positionB.z = positionC.z = 0.0f; listA.Add(positionA); listA.Add(positionB); listA.Add(positionB); listA.Add(positionC); listA.Add(positionC); listA.Add(positionA); if (invalid == true) { listB.Add(positionA); listB.Add(positionB); listB.Add(positionB); listB.Add(positionC); listB.Add(positionC); listB.Add(positionA); } } } } arrayA = listA.ToArray(); arrayB = listB.ToArray(); } var rect = P3dHelper.Reserve(position.height - 186.0f); GUI.Box(rect, ""); rect.min += Vector2.one * 3.0f; rect.max -= Vector2.one * 3.0f; var pos = rect.min; var siz = rect.size; Handles.BeginGUI(); if (listA.Count > 0) { for (var i = listA.Count - 1; i >= 0; i--) { var coord = listA[i]; coord.x = pos.x + siz.x * coord.x; coord.y = pos.y + siz.y * (1.0f - coord.y); arrayA[i] = coord; } Handles.DrawLines(arrayA); for (var i = listB.Count - 1; i >= 0; i--) { var coord = listB[i]; coord.x = pos.x + siz.x * coord.x; coord.y = pos.y + siz.y * (1.0f - coord.y); arrayB[i] = coord; } Handles.color = Color.red; Handles.DrawLines(arrayB); } Handles.EndGUI(); } else { EditorGUILayout.HelpBox("No Mesh Selected.\nTo select a mesh, click Analyze Mesh from the P3dPaintable component, or from the Mesh inspector context menu (gear icon at top right).", MessageType.Info); } }
protected virtual void Paint(P3dInputManager.Finger finger) { var link = GetLink(finger); if (dragStep > 0.0f) { if (finger.Down == true) { link.LastPoint = finger.ScreenPosition; if (storeStates == true) { P3dStateManager.StoreAllStates(); } PaintAt(finger.ScreenPosition, false, finger.Pressure); } var steps = CalculateSteps(finger.ScreenPosition - link.LastPoint); if (steps > 0) { var step = P3dHelper.Reciprocal(steps); var screenPosition = default(Vector2); for (var i = 1; i <= steps; i++) { screenPosition = Vector2.Lerp(link.LastPoint, finger.ScreenPosition, i * step); PaintAt(screenPosition, false, finger.Pressure); } link.LastPoint = screenPosition; } } else { if (showPreview == true) { if (finger.Up == true) { if (storeStates == true) { P3dStateManager.StoreAllStates(); } PaintAt(finger.ScreenPosition, false, finger.Pressure); } else { PaintAt(finger.ScreenPosition, true, finger.Pressure); } } else if (finger.Down == true) { if (storeStates == true) { P3dStateManager.StoreAllStates(); } PaintAt(finger.ScreenPosition, false, finger.Pressure); } } }