mirror of
https://github.com/Steffo99/better-tee.git
synced 2024-11-24 16:24:18 +00:00
Smooth lines
This commit is contained in:
parent
3238ab9ae6
commit
7c5beef670
6 changed files with 116 additions and 18 deletions
|
@ -4,7 +4,7 @@ MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
defaultReferences: []
|
defaultReferences: []
|
||||||
executionOrder: 100
|
executionOrder: -50
|
||||||
icon: {instanceID: 0}
|
icon: {instanceID: 0}
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
|
|
|
@ -4,9 +4,14 @@ using UnityEngine;
|
||||||
|
|
||||||
public class PencilTool : DrawTool
|
public class PencilTool : DrawTool
|
||||||
{
|
{
|
||||||
public Color color = Color.black;
|
public Color selectedColor = Color.black;
|
||||||
public float size = 1f;
|
public float size = 1f;
|
||||||
|
|
||||||
|
protected Color[] colors;
|
||||||
|
|
||||||
|
private Vector2Int? previousPixel;
|
||||||
|
private Vector2Int? pixel;
|
||||||
|
|
||||||
protected Vector2Int? HoveredPixel() {
|
protected Vector2Int? HoveredPixel() {
|
||||||
Vector2 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
|
Vector2 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
|
||||||
if(frame.Bounds.Contains(worldPoint)) {
|
if(frame.Bounds.Contains(worldPoint)) {
|
||||||
|
@ -19,31 +24,107 @@ public class PencilTool : DrawTool
|
||||||
|
|
||||||
protected override void Start() {
|
protected override void Start() {
|
||||||
base.Start();
|
base.Start();
|
||||||
InvokeRepeating("Apply", 0.05f, 0.05f);
|
colors = frame.texture.GetPixels();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Update() {
|
protected void Update() {
|
||||||
Color[] colors = frame.texture.GetPixels();
|
previousPixel = pixel;
|
||||||
if(Input.GetMouseButton(0)) {
|
if(Input.GetMouseButton(0)) {
|
||||||
Vector2Int? pixel = HoveredPixel();
|
pixel = HoveredPixel();
|
||||||
if(pixel.HasValue) {
|
if(pixel.HasValue) {
|
||||||
int x_start = Mathf.Clamp(Mathf.CeilToInt((float)pixel.Value.x - size), 0, frame.resolution.x);
|
if(previousPixel.HasValue) {
|
||||||
int x_end = Mathf.Clamp(Mathf.CeilToInt((float)pixel.Value.x + size), 0, frame.resolution.x);
|
DrawBresenhamsThickLine(previousPixel.Value, pixel.Value, size, selectedColor);
|
||||||
int y_start = Mathf.Clamp(Mathf.CeilToInt((float)pixel.Value.y - size), 0, frame.resolution.y);
|
}
|
||||||
int y_end = Mathf.Clamp(Mathf.CeilToInt((float)pixel.Value.y + size), 0, frame.resolution.y);
|
else {
|
||||||
for(int x = x_start; x < x_end; x++) {
|
DrawFilledCircle(pixel.Value, size, selectedColor);
|
||||||
for(int y = y_start; y < y_end; y++) {
|
}
|
||||||
if(Vector2Int.Distance(new Vector2Int(x, y), pixel.Value) < size) {
|
}
|
||||||
|
Apply();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pixel = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void DrawPixel(int x, int y, Color color) {
|
||||||
|
if(x < 0 || x >= frame.resolution.x || y < 0 || y >= frame.resolution.y) return;
|
||||||
colors[x + y*frame.resolution.x] = color;
|
colors[x + y*frame.resolution.x] = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void DrawCircleEightPoints(Vector2Int center, int x_radius, int y_radius, Color color) {
|
||||||
|
DrawPixel(center.x+x_radius, center.y+y_radius, color);
|
||||||
|
DrawPixel(center.x-x_radius, center.y+y_radius, color);
|
||||||
|
DrawPixel(center.x+x_radius, center.y-y_radius, color);
|
||||||
|
DrawPixel(center.x-x_radius, center.y-y_radius, color);
|
||||||
|
DrawPixel(center.x+y_radius, center.y+x_radius, color);
|
||||||
|
DrawPixel(center.x-y_radius, center.y+x_radius, color);
|
||||||
|
DrawPixel(center.x+y_radius, center.y-x_radius, color);
|
||||||
|
DrawPixel(center.x-y_radius, center.y-x_radius, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No idea on how does it work
|
||||||
|
// https://www.geeksforgeeks.org/bresenhams-circle-drawing-algorithm/
|
||||||
|
protected void DrawBresenhamEmptyCircle(Vector2Int center, int radius, Color color) {
|
||||||
|
int x = 0;
|
||||||
|
int y = radius;
|
||||||
|
int d = 3 - 2 * radius;
|
||||||
|
DrawCircleEightPoints(center, x, y, color);
|
||||||
|
while(y >= x) {
|
||||||
|
x++;
|
||||||
|
if(d > 0) {
|
||||||
|
y--;
|
||||||
|
d = d + 4 * (x - y) + 10;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
d = d + 4 * x + 6;
|
||||||
|
}
|
||||||
|
DrawCircleEightPoints(center, x, y, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void DrawFilledCircle(Vector2Int center, float radius, Color color) {
|
||||||
|
int x_start = Mathf.CeilToInt((float)center.x - radius);
|
||||||
|
int x_end = Mathf.CeilToInt((float)center.x + radius);
|
||||||
|
int y_start = Mathf.CeilToInt((float)center.y - radius);
|
||||||
|
int y_end = Mathf.CeilToInt((float)center.y + radius);
|
||||||
|
for(int x = x_start; x < x_end; x++) {
|
||||||
|
for(int y = y_start; y < y_end; y++) {
|
||||||
|
if(Vector2Int.Distance(new Vector2Int(x, y), center) < radius) {
|
||||||
|
DrawPixel(x, y, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
frame.texture.SetPixels(colors);
|
|
||||||
|
// http://www.roguebasin.com/index.php?title=Bresenham%27s_Line_Algorithm
|
||||||
|
protected void DrawBresenhamsThickLine(Vector2Int start, Vector2Int end, float radius, Color color) {
|
||||||
|
int start_x = start.x, start_y = start.y, end_x = end.x, end_y = end.y;
|
||||||
|
bool steep = Mathf.Abs(end_y - start_y) > Mathf.Abs(end_x - start_x);
|
||||||
|
if (steep) {
|
||||||
|
Utils.Swap<int>(ref start_x, ref start_y);
|
||||||
|
Utils.Swap<int>(ref end_x, ref end_y);
|
||||||
|
}
|
||||||
|
if (start_x > end_x) {
|
||||||
|
Utils.Swap<int>(ref start_x, ref end_x);
|
||||||
|
Utils.Swap<int>(ref start_y, ref end_y);
|
||||||
|
}
|
||||||
|
int dX = (end_x - start_x), dY = Mathf.Abs(end_y - start_y), err = (dX / 2), ystep = (start_y < end_y ? 1 : -1), y = start_y;
|
||||||
|
|
||||||
|
for (int x = start_x; x <= end_x; ++x)
|
||||||
|
{
|
||||||
|
if(steep) {
|
||||||
|
DrawFilledCircle(new Vector2Int(y, x), radius, color);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DrawFilledCircle(new Vector2Int(x, y), radius, color);
|
||||||
|
}
|
||||||
|
err = err - dY;
|
||||||
|
if (err < 0) { y += ystep; err += dX; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Apply() {
|
protected void Apply() {
|
||||||
|
frame.texture.SetPixels(colors);
|
||||||
frame.texture.Apply();
|
frame.texture.Apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
defaultReferences: []
|
defaultReferences: []
|
||||||
executionOrder: 200
|
executionOrder: 0
|
||||||
icon: {instanceID: 0}
|
icon: {instanceID: 0}
|
||||||
userData:
|
userData:
|
||||||
assetBundleName:
|
assetBundleName:
|
||||||
|
|
|
@ -16,6 +16,6 @@ public class PencilColorFromButtonColor : MonoBehaviour
|
||||||
|
|
||||||
public void OnClick()
|
public void OnClick()
|
||||||
{
|
{
|
||||||
pencil.color = image.color;
|
pencil.selectedColor = image.color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
6
Assets/Swap.cs
Normal file
6
Assets/Swap.cs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
public class Utils {
|
||||||
|
public static void Swap<T>(ref T lhs, ref T rhs) {
|
||||||
|
T temp; temp = lhs; lhs = rhs; rhs = temp;
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Swap.cs.meta
Normal file
11
Assets/Swap.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 12f494a09d5848e4c8843d84f864396e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in a new issue