Created
January 10, 2020 05:12
-
-
Save lowteq/f217b289b3a850b9ac016273a5c13168 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System; | |
using System.Collections.Generic; | |
#if UNITY_EDITOR | |
using UnityEditor; | |
public class BroochEditor : EditorWindow | |
{ | |
private class PathTool | |
{ | |
int selectindex = -1; | |
DrawTexture2D drawTexture2d = new DrawTexture2D(); | |
Texture2D texture; | |
bool closed = false; | |
List<Vector2> veclist; | |
float r; | |
int canvasSize; | |
public PathTool(int canvassize,float radius){ | |
r = radius; | |
canvasSize = canvassize; | |
veclist = new List<Vector2>(); | |
texture = new Texture2D(canvasSize,canvasSize,TextureFormat.RGBA32,false); | |
drawTexture2d = new DrawTexture2D(); | |
} | |
public Texture2D canvas(){ | |
drawTexture2d.Begin(texture); | |
drawTexture2d.Clear(Color.clear); | |
var c = new Color(0.5f, 0.5f, 0.5f); | |
if (veclist.Count == 0){ | |
drawTexture2d.End(); | |
return texture; | |
}else{ | |
drawTexture2d.DrawCircle((int)veclist[0].x, (int)veclist[0].y, (int)r, c); | |
for(var i=1;i<veclist.Count;i++){ | |
var v1 = veclist[i-1]; | |
var v2 = veclist[i]; | |
drawTexture2d.DrawLine((int)v1.x,(int)v1.y,(int)v2.x,(int)v2.y,c); | |
drawTexture2d.DrawCircle((int)v2.x,(int)v2.y,(int)r,c); | |
} | |
} | |
if(closed){ | |
drawTexture2d.DrawLine((int)veclist[0].x,(int)veclist[0].y,(int)veclist[veclist.Count-1].x,(int)veclist[veclist.Count-1].y,c); | |
} | |
drawTexture2d.End(); | |
return texture; | |
} | |
public void Clear(){ | |
veclist = new List<Vector2>(); | |
texture = new Texture2D(canvasSize, canvasSize); | |
drawTexture2d = new DrawTexture2D(); | |
veclist.Clear(); | |
closed = false; | |
} | |
public void ReleaseSelect(){ | |
selectindex = -1; | |
} | |
public void Move(Vector2 vec) | |
{ | |
if(selectindex == -1) return; | |
veclist[selectindex] = vec; | |
} | |
public bool Select(Vector2 vec){ | |
selectindex = -1; | |
for(var i=0;i<veclist.Count;i++){ | |
if(circleIn(vec,veclist[i],r)){ | |
selectindex = i; | |
return true; | |
} | |
} | |
return false; | |
} | |
public bool Add(Vector2 vec){ | |
bool ret = false; | |
for (var i = 0; i < veclist.Count; i++) | |
{ | |
if (circleIn(vec, veclist[i], r)) | |
{ | |
//もし追加しようとしてるvecがveclist内の点付近の場合は追加しない | |
//だたし閉じる処理のveclist[0]のクリックは調べない | |
if(closed) return false; | |
} | |
} | |
Debug.Log("Pass"); | |
if(closed){ | |
for (var i = 1; i < veclist.Count; i++) | |
{ | |
if(lineIn(vec,veclist[i-1],veclist[i],r)){ | |
veclist.Insert(i,vec); | |
Debug.Log("insert 1"); | |
ret = true; | |
break; | |
} | |
} | |
if (lineIn(vec, veclist[0], veclist[veclist.Count - 1], r)) | |
{ | |
veclist.Insert(0, vec); | |
Debug.Log("insert 2"); | |
ret = true; | |
} | |
}else{ | |
if (veclist.Count > 2) | |
{ | |
if (circleIn(veclist[0], vec, r)) | |
{ | |
//閉じるための処理 | |
closed = true; | |
} | |
else | |
{ | |
//追加する | |
veclist.Add(vec); | |
ret = true; | |
} | |
} | |
else | |
{ | |
veclist.Add(vec); | |
ret = true; | |
} | |
} | |
return ret; | |
} | |
public void Remove(Vector2 vec){ | |
if(veclist.Count <= 3){ | |
return; | |
} | |
for(var i=0;i<veclist.Count;i++){ | |
if (circleIn(veclist[i], vec, r)) | |
{ | |
veclist.RemoveAt(i); | |
break; | |
} | |
} | |
} | |
/// <summary> | |
/// 線分v1-v2上(太さ2*r)にpが存在するか | |
/// 点v1,v2付近ではfalseになる部分がある | |
/// </summary> | |
/// <param name="p"></param> | |
/// <param name="v1"></param> | |
/// <param name="v2"></param> | |
/// <param name="r"></param> | |
/// <returns></returns> | |
private static bool lineIn(Vector2 p,Vector2 v1,Vector2 v2,float r){ | |
float a = v2.x - v1.x; | |
float b = v2.y - v1.y; | |
float a2 = a * a; | |
float b2 = b * b; | |
float r2 = a2 + b2; | |
float tt = -(a*(v1.x-p.x)+b*(v1.y-p.y)); | |
float d2; | |
if(tt < 0){ | |
d2 = (v1.x-p.x)*(v1.x-p.x) + (v1.y-p.y)*(v1.y-p.y); | |
} | |
if(tt > r2){ | |
d2 = (v2.x-p.x)*(v2.x-p.x) + (v2.y-p.y)*(v2.y-p.y); | |
} | |
float f1 = a*(v1.y-p.y)-b*(v1.x-p.x); | |
d2 = (f1*f1)/r2; | |
Debug.Log(Math.Sqrt(d2)); | |
if (d2<=r && dist2(v1,p) < r2 && dist2(v2,p) < r2){ | |
return true; | |
}else{ | |
return false; | |
} | |
} | |
/// <summary> | |
/// 2点間の距離の2乗 | |
/// </summary> | |
/// <param name="p1"></param> | |
/// <param name="p2"></param> | |
/// <returns></returns> | |
private static float dist2(Vector2 p1,Vector2 p2){ | |
float c =(p2.x - p1.x); | |
float d =(p2.y - p1.y); | |
return c*c + d*d; | |
} | |
private static bool circleIn(Vector2 mousevec, Vector2 plotvec, float r) | |
{ | |
if (Math.Pow(mousevec.x - plotvec.x, 2) + Math.Pow(mousevec.y - plotvec.y, 2) <= r * r) | |
{ | |
return true; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
} | |
public Material mat1; | |
Texture2D texture = null; | |
Texture2D guitexture = null; | |
private int canvasOffsetX = 240; | |
private int canvasOffsetY = 20; | |
private int canvasSize = 500; | |
private int selGridInt = 0; | |
private PathTool pt; | |
enum ToolType{ | |
AddEdit = 0,Remove = 1 | |
} | |
private string[] selCaptions = new string[] { | |
"Add/Edit", | |
"Remove", | |
}; | |
[MenuItem("Window/BroochEditor")] | |
private static void Create() | |
{ | |
// 生成 | |
var window = GetWindow<BroochEditor>("Brooch Editor"); | |
window.minSize = new Vector2(320, 320); | |
window.Init(); | |
} | |
private void Init(){ | |
pt = new PathTool(canvasSize, 5); | |
mat1 = AssetDatabase.LoadAssetAtPath("Assets/BroochEditor/Editor/mat1.mat",typeof(Material)) as Material; | |
} | |
void OnInspectorUpdate() | |
{ | |
if (EditorWindow.focusedWindow == this && | |
EditorWindow.mouseOverWindow == this) | |
{ | |
this.Repaint(); | |
} | |
} | |
public static void SetTextureImporterFormat(Texture2D texture, bool isReadable) | |
{ | |
if (texture.isReadable == isReadable){ | |
return; | |
} | |
string assetPath = AssetDatabase.GetAssetPath(texture); | |
var tImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter; | |
if (tImporter != null) | |
{ | |
//tImporter.textureType = TextureImporterType.Default; | |
tImporter.isReadable = isReadable; | |
AssetDatabase.ImportAsset(assetPath); | |
AssetDatabase.Refresh(); | |
} | |
} | |
void OnGUI() | |
{ | |
Event e = Event.current; | |
var cmp = new Vector2(e.mousePosition.x - canvasOffsetX,e.mousePosition.y - canvasOffsetY); | |
EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(200));{ | |
EditorGUILayout.BeginVertical(GUI.skin.box);{ | |
EditorGUILayout.BeginVertical(GUI.skin.box); | |
{ | |
var mp = e.mousePosition; | |
EditorGUILayout.LabelField("x:" + mp.x + " y:" + mp.y + " type:" + e.type); | |
if (e.type == EventType.MouseDown){ | |
Debug.Log(mp); | |
} | |
} | |
EditorGUILayout.EndVertical(); | |
EditorGUILayout.BeginVertical(GUI.skin.box);{ | |
EditorGUI.BeginChangeCheck(); | |
texture = EditorGUILayout.ObjectField("Reference Texture:", texture, typeof(Texture), false) as Texture2D; | |
if(EditorGUI.EndChangeCheck()){ | |
Debug.Log("ChangeTexture"); | |
if (texture != null){ | |
SetTextureImporterFormat(texture,true); | |
} | |
} | |
}EditorGUILayout.EndVertical(); | |
EditorGUILayout.BeginVertical(GUI.skin.box);{ | |
EditorGUILayout.LabelField("Tools",EditorStyles.boldLabel); | |
selGridInt = GUILayout.SelectionGrid(selGridInt, selCaptions, 1, EditorStyles.radioButton); | |
}EditorGUILayout.EndVertical(); | |
EditorGUILayout.BeginVertical(GUI.skin.box);{ | |
GUILayout.Label("Base Settings", EditorStyles.boldLabel); | |
// myString = EditorGUILayout.TextField("Text Field", myString); | |
}EditorGUILayout.EndVertical(); | |
}EditorGUILayout.EndVertical(); | |
} | |
if (texture != null) | |
{ | |
// Color[] pixels = texture.GetPixels(); | |
// Color[] change_pixels = new Color[pixels.Length]; | |
// for (int i = 0; i < pixels.Length; i++) | |
// { | |
// Color pixel = pixels[i]; | |
// // 書き換え用テクスチャのピクセル色を指定 | |
// Color change_pixel = new Color(1f, pixel.g, pixel.b, pixel.a); | |
// change_pixels.SetValue(change_pixel, i); | |
// } | |
// // 書き換え用テクスチャの生成 | |
// Texture2D change_texture = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false); | |
// change_texture.filterMode = FilterMode.Point; | |
// change_texture.SetPixels(change_pixels); | |
// change_texture.Apply(); | |
EditorGUI.DrawPreviewTexture(new Rect(240,20, 500, 500),texture,null,ScaleMode.StretchToFill,1,-1,UnityEngine.Rendering.ColorWriteMask.All); | |
//EditorGUI.DrawTextureAlpha(new Rect(240, 20, 500, 500), texture, ScaleMode.StretchToFill, 1, 0); | |
} | |
if (0 < cmp.x && cmp.x < canvasSize && 0 < cmp.y && cmp.y < canvasSize) | |
{ | |
guitexture = CanvasBehaviour(e, cmp); | |
} | |
if(guitexture != null){ | |
//EditorGUI.DrawPreviewTexture(new Rect(240, 20, 500, 500), guitexture); | |
EditorGUI.DrawPreviewTexture(new Rect(240,20,500,500),guitexture,mat1,ScaleMode.StretchToFill,0,-1,UnityEngine.Rendering.ColorWriteMask.All); | |
//EditorGUI.DrawTextureAlpha(new Rect(240,20,500,500),guitexture,ScaleMode.StretchToFill,1,0); | |
} | |
} | |
private Texture2D CanvasBehaviour(Event e,Vector2 canvasMousePosition){ | |
// if((ToolType)selGridInt==ToolType.Add){ | |
// switch(e.type){ | |
// case EventType.MouseDown: | |
// pt.Add(canvasMousePosition); | |
// break; | |
// } | |
// } | |
if((ToolType)selGridInt==ToolType.Remove){ | |
switch(e.type){ | |
case EventType.MouseDown: | |
pt.Remove(canvasMousePosition); | |
break; | |
} | |
}else if((ToolType)selGridInt==ToolType.AddEdit){ | |
switch(e.type){ | |
case EventType.MouseDown: | |
if(!pt.Add(canvasMousePosition)){ | |
pt.Select(canvasMousePosition); | |
} | |
break; | |
case EventType.MouseDrag: | |
pt.Move(canvasMousePosition); | |
break; | |
case EventType.MouseUp: | |
pt.ReleaseSelect(); | |
break; | |
} | |
} | |
return pt.canvas(); | |
//EditorGUI.DrawPreviewTexture(new Rect(240,20,500,500),drawtex); | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment