MegaShapeEditor.cs 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105
  1. using UnityEditor;
  2. using UnityEngine;
  3. using System.IO;
  4. using System.Collections.Generic;
  5. public class MegaSplineUndo
  6. {
  7. public int curve;
  8. public MegaSpline spline;
  9. }
  10. [CustomEditor(typeof(MegaShape))]
  11. public class MegaShapeEditor : Editor
  12. {
  13. public bool showcommon = true;
  14. public float outline = 0.0f;
  15. int selected = -1;
  16. Vector3 pm = new Vector3();
  17. Vector3 delta = new Vector3();
  18. bool showsplines = false;
  19. bool showknots = false;
  20. bool showlabels = true;
  21. float ImportScale = 1.0f;
  22. #if UNITY_5_5 || UNITY_5_6 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  23. #else
  24. bool hidewire = false;
  25. #endif
  26. Bounds bounds;
  27. string lastpath = "";
  28. MegaKnotAnim ma;
  29. public bool showfuncs = false;
  30. public bool export = false;
  31. public MegaAxis xaxis = MegaAxis.X;
  32. public MegaAxis yaxis = MegaAxis.Z;
  33. public float strokewidth = 1.0f;
  34. public Color strokecol = Color.black;
  35. static public Vector3 CursorPos = Vector3.zero;
  36. static public Vector3 CursorSpline = Vector3.zero;
  37. static public Vector3 CursorTangent = Vector3.zero;
  38. static public int CursorKnot = 0;
  39. public delegate bool ParseBinCallbackType(BinaryReader br, string id);
  40. public delegate void ParseClassCallbackType(string classname, BinaryReader br);
  41. static public MegaShapeEditor editor;
  42. public int maxUndo = 20;
  43. public List<MegaSplineUndo> undoHistory = new List<MegaSplineUndo>();
  44. #if UNITY_2017_2 || UNITY_2017_3 || UNITY_2017_4 || UNITY_2018 || UNITY_2019 || UNITY_2020
  45. Dictionary<int, string> myControls = new Dictionary<int, string>();
  46. public static int cid = 0;
  47. #endif
  48. void NewControlFrame()
  49. {
  50. #if UNITY_2017_2 || UNITY_2017_3 || UNITY_2017_4 || UNITY_2018 || UNITY_2019 || UNITY_2020
  51. myControls.Clear();
  52. cid = 10661066;
  53. #else
  54. #endif
  55. }
  56. void SetControlName(string name)
  57. {
  58. #if UNITY_2017_2 || UNITY_2017_3 || UNITY_2017_4 || UNITY_2018 || UNITY_2019 || UNITY_2020
  59. cid++;
  60. if ( myControls == null )
  61. myControls = new Dictionary<int, string>();
  62. //Debug.Log("add " + cid + " " + name);
  63. myControls.Add(cid, name);
  64. #else
  65. GUI.SetNextControlName(name);
  66. #endif
  67. }
  68. string GetControlName()
  69. {
  70. #if UNITY_2017_2 || UNITY_2017_3 || UNITY_2017_4 || UNITY_2018 || UNITY_2019 || UNITY_2020
  71. if ( myControls != null )
  72. {
  73. int hc = GUIUtility.hotControl;
  74. //Debug.Log("hc " + hc);
  75. if ( myControls.ContainsKey(hc) )
  76. {
  77. //Debug.Log("name " + myControls[hc]);
  78. return myControls[hc];
  79. }
  80. }
  81. return "";
  82. #else
  83. return GUI.GetNameOfFocusedControl();
  84. #endif
  85. }
  86. public void PushSpline(MegaSpline s, int c)
  87. {
  88. MegaSplineUndo su = new MegaSplineUndo();
  89. su.curve = c;
  90. su.spline = new MegaSpline();
  91. su.spline.closed = s.closed;
  92. for ( int k = 0; k < s.knots.Count; k++ )
  93. {
  94. MegaKnot knot = new MegaKnot();
  95. knot.p = s.knots[k].p;
  96. knot.invec = s.knots[k].invec;
  97. knot.outvec = s.knots[k].outvec;
  98. knot.twist = s.knots[k].twist;
  99. knot.id = s.knots[k].id;
  100. knot.notlocked = s.knots[k].notlocked;
  101. su.spline.knots.Add(knot);
  102. }
  103. undoHistory.Add(su);
  104. if ( undoHistory.Count > maxUndo )
  105. {
  106. undoHistory.RemoveAt(0);
  107. }
  108. }
  109. public void PopSpline(MegaShape s)
  110. {
  111. if ( undoHistory.Count > 0 )
  112. {
  113. MegaSplineUndo su = undoHistory[undoHistory.Count - 1];
  114. s.splines[su.curve] = su.spline;
  115. undoHistory.RemoveAt(undoHistory.Count - 1);
  116. }
  117. }
  118. public virtual bool Params()
  119. {
  120. MegaShape shape = (MegaShape)target;
  121. bool rebuild = false;
  122. float radius = EditorGUILayout.FloatField("Radius", shape.defRadius);
  123. if ( radius != shape.defRadius )
  124. {
  125. if ( radius < 0.001f )
  126. radius = 0.001f;
  127. shape.defRadius = radius;
  128. rebuild = true;
  129. }
  130. return rebuild;
  131. }
  132. public override void OnInspectorGUI()
  133. {
  134. bool buildmesh = false;
  135. bool recalc = false;
  136. MegaShape shape = (MegaShape)target;
  137. editor = this;
  138. EditorGUILayout.BeginHorizontal();
  139. int curve = shape.selcurve;
  140. if ( GUILayout.Button("Add Knot") )
  141. {
  142. if ( shape.splines == null || shape.splines.Count == 0 )
  143. {
  144. MegaSpline spline = new MegaSpline(); // Have methods for these
  145. shape.splines.Add(spline);
  146. }
  147. PushSpline(shape.splines[shape.selcurve], shape.selcurve);
  148. MegaKnot knot = new MegaKnot();
  149. float per = shape.CursorPercent * 0.01f;
  150. CursorTangent = shape.splines[curve].Interpolate(per + 0.01f, true, ref CursorKnot); //this.GetPositionOnSpline(i) - p;
  151. CursorPos = shape.splines[curve].Interpolate(per, true, ref CursorKnot); //this.GetPositionOnSpline(i) - p;
  152. knot.p = CursorPos;
  153. knot.outvec = (CursorTangent - knot.p);
  154. knot.outvec.Normalize();
  155. knot.outvec *= shape.splines[curve].knots[CursorKnot].seglength * 0.25f;
  156. knot.invec = -knot.outvec;
  157. knot.invec += knot.p;
  158. knot.outvec += knot.p;
  159. knot.twist = shape.splines[curve].knots[CursorKnot].twist;
  160. knot.id = shape.splines[curve].knots[CursorKnot].id;
  161. shape.splines[curve].knots.Insert(CursorKnot + 1, knot);
  162. if ( shape.smoothonaddknot )
  163. shape.AutoCurve(shape.splines[shape.selcurve]); //, knum, knum + 2);
  164. shape.CalcLength(); //10);
  165. EditorUtility.SetDirty(target);
  166. buildmesh = true;
  167. }
  168. if ( GUILayout.Button("Delete Knot") )
  169. {
  170. if ( selected != -1 )
  171. {
  172. PushSpline(shape.splines[shape.selcurve], shape.selcurve);
  173. shape.splines[curve].knots.RemoveAt(selected);
  174. selected--;
  175. shape.CalcLength(); //10);
  176. recalc = true;
  177. }
  178. EditorUtility.SetDirty(target);
  179. buildmesh = true;
  180. }
  181. EditorGUILayout.EndHorizontal();
  182. EditorGUILayout.BeginHorizontal();
  183. if ( GUILayout.Button("Match Handles") )
  184. {
  185. if ( selected != -1 )
  186. {
  187. PushSpline(shape.splines[shape.selcurve], shape.selcurve);
  188. Vector3 p = shape.splines[curve].knots[selected].p;
  189. Vector3 d = shape.splines[curve].knots[selected].outvec - p;
  190. shape.splines[curve].knots[selected].invec = p - d;
  191. shape.CalcLength(); //10);
  192. recalc = true;
  193. }
  194. EditorUtility.SetDirty(target);
  195. buildmesh = true;
  196. }
  197. if ( GUILayout.Button("Load") )
  198. {
  199. LoadShape(ImportScale);
  200. buildmesh = true;
  201. }
  202. if ( GUILayout.Button("Load SXL") )
  203. {
  204. LoadSXL(ImportScale);
  205. buildmesh = true;
  206. }
  207. if ( GUILayout.Button("Load KML") )
  208. {
  209. LoadKML(ImportScale);
  210. buildmesh = true;
  211. }
  212. EditorGUILayout.EndHorizontal();
  213. EditorGUILayout.BeginHorizontal();
  214. if ( GUILayout.Button("AutoCurve") )
  215. {
  216. PushSpline(shape.splines[shape.selcurve], shape.selcurve);
  217. shape.AutoCurve();
  218. EditorUtility.SetDirty(target);
  219. buildmesh = true;
  220. }
  221. if ( GUILayout.Button("Reverse") )
  222. {
  223. PushSpline(shape.splines[shape.selcurve], shape.selcurve);
  224. shape.Reverse(curve);
  225. EditorUtility.SetDirty(target);
  226. buildmesh = true;
  227. recalc = true;
  228. }
  229. EditorGUILayout.EndHorizontal();
  230. if ( GUILayout.Button("Centre Shape") )
  231. {
  232. PushSpline(shape.splines[shape.selcurve], shape.selcurve);
  233. shape.Centre(1.0f, Vector3.one);
  234. EditorUtility.SetDirty(target);
  235. buildmesh = true;
  236. }
  237. if ( GUILayout.Button("Apply Scaling") )
  238. {
  239. PushSpline(shape.splines[shape.selcurve], shape.selcurve);
  240. shape.Scale(shape.transform.localScale);
  241. EditorUtility.SetDirty(target);
  242. shape.transform.localScale = Vector3.one;
  243. buildmesh = true;
  244. }
  245. if ( GUILayout.Button("Import SVG") )
  246. {
  247. LoadSVG(ImportScale);
  248. buildmesh = true;
  249. }
  250. EditorGUILayout.BeginVertical("box");
  251. maxUndo = EditorGUILayout.IntField("Max Undo", maxUndo);
  252. maxUndo = Mathf.Clamp(maxUndo, 2, 40);
  253. if ( GUILayout.Button("Undo Edit Spline (" + undoHistory.Count + ")") )
  254. {
  255. PopSpline(shape);
  256. recalc = true;
  257. }
  258. if ( GUILayout.Button("Clear Undo History") )
  259. {
  260. undoHistory.Clear();
  261. }
  262. EditorGUILayout.EndVertical();
  263. showcommon = EditorGUILayout.Foldout(showcommon, "Common Params");
  264. bool rebuild = false; //Params();
  265. if ( showcommon )
  266. {
  267. shape.CursorPercent = EditorGUILayout.FloatField("Cursor", shape.CursorPercent);
  268. shape.CursorPercent = Mathf.Repeat(shape.CursorPercent, 100.0f);
  269. ImportScale = EditorGUILayout.FloatField("Import Scale", ImportScale);
  270. MegaAxis av = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.axis);
  271. if ( av != shape.axis )
  272. {
  273. shape.axis = av;
  274. rebuild = true;
  275. }
  276. if ( shape.splines.Count > 1 )
  277. shape.selcurve = EditorGUILayout.IntSlider("Curve", shape.selcurve, 0, shape.splines.Count - 1);
  278. if ( shape.selcurve < 0 )
  279. shape.selcurve = 0;
  280. if ( shape.selcurve > shape.splines.Count - 1 )
  281. shape.selcurve = shape.splines.Count - 1;
  282. EditorGUILayout.BeginHorizontal();
  283. EditorGUILayout.LabelField("Colors");
  284. shape.col1 = EditorGUILayout.ColorField(shape.col1);
  285. shape.col2 = EditorGUILayout.ColorField(shape.col2);
  286. EditorGUILayout.EndHorizontal();
  287. shape.VecCol = EditorGUILayout.ColorField("Vec Col", shape.VecCol);
  288. shape.KnotSize = EditorGUILayout.FloatField("Knot Size", shape.KnotSize);
  289. shape.stepdist = EditorGUILayout.FloatField("Step Dist", shape.stepdist);
  290. MegaSpline spline = shape.splines[shape.selcurve];
  291. if ( shape.stepdist < 0.01f )
  292. shape.stepdist = 0.01f;
  293. shape.dolateupdate = EditorGUILayout.Toggle("Do Late Update", shape.dolateupdate);
  294. shape.normalizedInterp = EditorGUILayout.Toggle("Normalized Interp", shape.normalizedInterp);
  295. spline.constantSpeed = EditorGUILayout.Toggle("Constant Speed", spline.constantSpeed);
  296. int subdivs = EditorGUILayout.IntField("Calc Subdivs", spline.subdivs);
  297. if ( subdivs < 2 )
  298. subdivs = 2;
  299. if ( subdivs != spline.subdivs )
  300. spline.CalcLength(subdivs);
  301. shape.drawHandles = EditorGUILayout.Toggle("Draw Handles", shape.drawHandles);
  302. shape.drawKnots = EditorGUILayout.Toggle("Draw Knots", shape.drawKnots);
  303. shape.drawTwist = EditorGUILayout.Toggle("Draw Twist", shape.drawTwist);
  304. shape.drawspline = EditorGUILayout.Toggle("Draw Spline", shape.drawspline);
  305. shape.showorigin = EditorGUILayout.Toggle("Origin Handle", shape.showorigin);
  306. shape.lockhandles = EditorGUILayout.Toggle("Lock Handles", shape.lockhandles);
  307. shape.updateondrag = EditorGUILayout.Toggle("Update On Drag", shape.updateondrag);
  308. shape.usesnap = EditorGUILayout.BeginToggleGroup("Use Snap", shape.usesnap);
  309. shape.usesnaphandles = EditorGUILayout.Toggle("Snap Handles", shape.usesnaphandles);
  310. shape.snap = EditorGUILayout.Vector3Field("Snap", shape.snap);
  311. if ( shape.snap.x < 0.0f ) shape.snap.x = 0.0f;
  312. if ( shape.snap.y < 0.0f ) shape.snap.y = 0.0f;
  313. if ( shape.snap.z < 0.0f ) shape.snap.z = 0.0f;
  314. EditorGUILayout.EndToggleGroup();
  315. MegaShapeBezComputeMode smode = (MegaShapeBezComputeMode)EditorGUILayout.EnumPopup("Smooth Mode", shape.smoothMode);
  316. if ( smode != shape.smoothMode )
  317. {
  318. shape.smoothMode = smode;
  319. shape.AutoCurve();
  320. recalc = true;
  321. }
  322. if ( shape.smoothMode == MegaShapeBezComputeMode.Old )
  323. {
  324. float smoothness = EditorGUILayout.Slider("Smoothness", shape.smoothness, 0.0f, 1.5f);
  325. if ( smoothness != shape.smoothness )
  326. {
  327. shape.smoothness = smoothness;
  328. shape.AutoCurve();
  329. recalc = true;
  330. }
  331. }
  332. shape.smoothOnDrag = EditorGUILayout.Toggle("Smooth on Drag", shape.smoothOnDrag);
  333. shape.smoothonaddknot = EditorGUILayout.Toggle("Smooth on Add Knot", shape.smoothonaddknot);
  334. shape.handleType = (MegaHandleType)EditorGUILayout.EnumPopup("Handle Type", shape.handleType);
  335. EditorGUILayout.BeginHorizontal();
  336. EditorGUILayout.LabelField("Freeze Movement", GUILayout.Width(144));
  337. EditorGUILayout.LabelField("x", GUILayout.Width(12));
  338. shape.freezeX = EditorGUILayout.Toggle("", shape.freezeX, GUILayout.Width(20));
  339. EditorGUILayout.LabelField("y", GUILayout.Width(12));
  340. shape.freezeY = EditorGUILayout.Toggle("", shape.freezeY, GUILayout.Width(20));
  341. EditorGUILayout.LabelField("z", GUILayout.Width(12));
  342. shape.freezeZ = EditorGUILayout.Toggle("", shape.freezeZ, GUILayout.Width(20));
  343. EditorGUILayout.EndHorizontal();
  344. showlabels = EditorGUILayout.Toggle("Labels", showlabels);
  345. #if UNITY_5_5 || UNITY_5_6 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  346. #else
  347. bool hidewire1 = EditorGUILayout.Toggle("Hide Wire", hidewire);
  348. if ( hidewire1 != hidewire )
  349. {
  350. hidewire = hidewire1;
  351. EditorUtility.SetSelectedWireframeHidden(shape.GetComponent<Renderer>(), hidewire);
  352. }
  353. #endif
  354. shape.animate = EditorGUILayout.Toggle("Animate", shape.animate);
  355. if ( shape.animate )
  356. {
  357. shape.time = EditorGUILayout.FloatField("Time", shape.time);
  358. shape.MaxTime = EditorGUILayout.FloatField("Loop Time", shape.MaxTime);
  359. shape.speed = EditorGUILayout.FloatField("Speed", shape.speed);
  360. shape.LoopMode = (MegaRepeatMode)EditorGUILayout.EnumPopup("Loop Mode", shape.LoopMode);
  361. }
  362. AnimationKeyFrames(shape);
  363. if ( shape.splines.Count > 0 )
  364. {
  365. if ( spline.outlineSpline != -1 )
  366. {
  367. int outlineSpline = EditorGUILayout.IntSlider("Outline Spl", spline.outlineSpline, 0, shape.splines.Count - 1);
  368. float outline = EditorGUILayout.FloatField("Outline", spline.outline);
  369. if ( outline != spline.outline || outlineSpline != spline.outlineSpline )
  370. {
  371. spline.outlineSpline = outlineSpline;
  372. spline.outline = outline;
  373. if ( outlineSpline != shape.selcurve )
  374. {
  375. shape.OutlineSpline(shape.splines[spline.outlineSpline], spline, spline.outline, true);
  376. spline.CalcLength(); //10);
  377. EditorUtility.SetDirty(target);
  378. buildmesh = true;
  379. }
  380. }
  381. }
  382. else
  383. {
  384. outline = EditorGUILayout.FloatField("Outline", outline);
  385. if ( GUILayout.Button("Outline") )
  386. {
  387. shape.OutlineSpline(shape, shape.selcurve, outline, true);
  388. shape.splines[shape.splines.Count - 1].outline = outline;
  389. shape.splines[shape.splines.Count - 1].outlineSpline = shape.selcurve;
  390. shape.selcurve = shape.splines.Count - 1;
  391. EditorUtility.SetDirty(target);
  392. buildmesh = true;
  393. }
  394. }
  395. }
  396. // Mesher
  397. shape.makeMesh = EditorGUILayout.Toggle("Make Mesh", shape.makeMesh);
  398. if ( shape.makeMesh )
  399. {
  400. shape.meshType = (MeshShapeType)EditorGUILayout.EnumPopup("Mesh Type", shape.meshType);
  401. shape.Pivot = EditorGUILayout.Vector3Field("Pivot", shape.Pivot);
  402. shape.CalcTangents = EditorGUILayout.Toggle("Calc Tangents", shape.CalcTangents);
  403. shape.GenUV = EditorGUILayout.Toggle("Gen UV", shape.GenUV);
  404. if ( GUILayout.Button("Build LightMap") )
  405. {
  406. MegaShapeLightMapWindow.Init();
  407. }
  408. EditorGUILayout.BeginVertical("Box");
  409. switch ( shape.meshType )
  410. {
  411. case MeshShapeType.Fill:
  412. shape.DoubleSided = EditorGUILayout.Toggle("Double Sided", shape.DoubleSided);
  413. shape.Height = EditorGUILayout.FloatField("Height", shape.Height);
  414. shape.UseHeightCurve = EditorGUILayout.Toggle("Use Height Crv", shape.UseHeightCurve);
  415. if ( shape.UseHeightCurve )
  416. {
  417. shape.heightCrv = EditorGUILayout.CurveField("Height Curve", shape.heightCrv);
  418. shape.heightOff = EditorGUILayout.Slider("Height Off", shape.heightOff, -1.0f, 1.0f);
  419. }
  420. shape.mat1 = (Material)EditorGUILayout.ObjectField("Top Mat", shape.mat1, typeof(Material), true);
  421. shape.mat2 = (Material)EditorGUILayout.ObjectField("Bot Mat", shape.mat2, typeof(Material), true);
  422. shape.mat3 = (Material)EditorGUILayout.ObjectField("Side Mat", shape.mat3, typeof(Material), true);
  423. shape.PhysUV = EditorGUILayout.Toggle("Physical UV", shape.PhysUV);
  424. shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset);
  425. shape.UVRotate = EditorGUILayout.Vector2Field("UV Rotate", shape.UVRotate);
  426. shape.UVScale = EditorGUILayout.Vector2Field("UV Scale", shape.UVScale);
  427. shape.UVOffset1 = EditorGUILayout.Vector2Field("UV Offset1", shape.UVOffset1);
  428. shape.UVRotate1 = EditorGUILayout.Vector2Field("UV Rotate1", shape.UVRotate1);
  429. shape.UVScale1 = EditorGUILayout.Vector2Field("UV Scale1", shape.UVScale1);
  430. break;
  431. case MeshShapeType.Tube:
  432. shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f);
  433. shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f);
  434. shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate);
  435. shape.tsides = EditorGUILayout.IntField("Sides", shape.tsides);
  436. shape.tradius = EditorGUILayout.FloatField("Radius", shape.tradius);
  437. shape.offset = EditorGUILayout.FloatField("Offset", shape.offset);
  438. shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX);
  439. shape.unlinkScale = EditorGUILayout.BeginToggleGroup("unlink Scale", shape.unlinkScale);
  440. shape.scaleY = EditorGUILayout.CurveField("Scale Y", shape.scaleY);
  441. EditorGUILayout.EndToggleGroup();
  442. shape.strands = EditorGUILayout.IntField("Strands", shape.strands);
  443. if ( shape.strands > 1 )
  444. {
  445. shape.strandRadius = EditorGUILayout.FloatField("Strand Radius", shape.strandRadius);
  446. shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit);
  447. shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng);
  448. }
  449. shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset);
  450. shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex);
  451. shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley);
  452. shape.cap = EditorGUILayout.Toggle("Cap", shape.cap);
  453. shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp);
  454. shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true);
  455. shape.flipNormals = EditorGUILayout.Toggle("Flip Normals", shape.flipNormals);
  456. break;
  457. case MeshShapeType.Ribbon:
  458. shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f);
  459. shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f);
  460. shape.boxwidth = EditorGUILayout.FloatField("Width", shape.boxwidth);
  461. shape.raxis = (MegaAxis)EditorGUILayout.EnumPopup("Axis", shape.raxis);
  462. shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate);
  463. shape.ribsegs = EditorGUILayout.IntField("Segs", shape.ribsegs);
  464. if ( shape.ribsegs < 1 )
  465. shape.ribsegs = 1;
  466. shape.offset = EditorGUILayout.FloatField("Offset", shape.offset);
  467. shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX);
  468. shape.strands = EditorGUILayout.IntField("Strands", shape.strands);
  469. if ( shape.strands > 1 )
  470. {
  471. shape.strandRadius = EditorGUILayout.FloatField("Strand Radius", shape.strandRadius);
  472. shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit);
  473. shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng);
  474. }
  475. shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset);
  476. shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex);
  477. shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley);
  478. shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp);
  479. shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true);
  480. shape.flipNormals = EditorGUILayout.Toggle("Flip Normals", shape.flipNormals);
  481. break;
  482. case MeshShapeType.Box:
  483. shape.TubeStart = EditorGUILayout.Slider("Start", shape.TubeStart, -1.0f, 2.0f);
  484. shape.TubeLength = EditorGUILayout.Slider("Length", shape.TubeLength, 0.0f, 1.0f);
  485. shape.rotate = EditorGUILayout.FloatField("Rotate", shape.rotate);
  486. shape.boxwidth = EditorGUILayout.FloatField("Box Width", shape.boxwidth);
  487. shape.boxheight = EditorGUILayout.FloatField("Box Height", shape.boxheight);
  488. shape.offset = EditorGUILayout.FloatField("Offset", shape.offset);
  489. shape.scaleX = EditorGUILayout.CurveField("Scale X", shape.scaleX);
  490. shape.unlinkScale = EditorGUILayout.BeginToggleGroup("unlink Scale", shape.unlinkScale);
  491. shape.scaleY = EditorGUILayout.CurveField("Scale Y", shape.scaleY);
  492. EditorGUILayout.EndToggleGroup();
  493. shape.strands = EditorGUILayout.IntField("Strands", shape.strands);
  494. if ( shape.strands > 1 )
  495. {
  496. shape.tradius = EditorGUILayout.FloatField("Radius", shape.tradius);
  497. shape.TwistPerUnit = EditorGUILayout.FloatField("Twist", shape.TwistPerUnit);
  498. shape.startAng = EditorGUILayout.FloatField("Start Twist", shape.startAng);
  499. }
  500. shape.UVOffset = EditorGUILayout.Vector2Field("UV Offset", shape.UVOffset);
  501. shape.uvtilex = EditorGUILayout.FloatField("UV Tile X", shape.uvtilex);
  502. shape.uvtiley = EditorGUILayout.FloatField("UV Tile Y", shape.uvtiley);
  503. shape.cap = EditorGUILayout.Toggle("Cap", shape.cap);
  504. shape.RopeUp = (MegaAxis)EditorGUILayout.EnumPopup("Up", shape.RopeUp);
  505. shape.mat1 = (Material)EditorGUILayout.ObjectField("Mat", shape.mat1, typeof(Material), true);
  506. shape.flipNormals = EditorGUILayout.Toggle("Flip Normals", shape.flipNormals);
  507. break;
  508. }
  509. if ( shape.strands < 1 )
  510. shape.strands = 1;
  511. EditorGUILayout.EndVertical();
  512. // Conform
  513. shape.conform = EditorGUILayout.BeginToggleGroup("Conform", shape.conform);
  514. GameObject contarget = (GameObject)EditorGUILayout.ObjectField("Target", shape.target, typeof(GameObject), true);
  515. if ( contarget != shape.target )
  516. shape.SetTarget(contarget);
  517. shape.conformAmount = EditorGUILayout.Slider("Amount", shape.conformAmount, 0.0f, 1.0f);
  518. shape.raystartoff = EditorGUILayout.FloatField("Ray Start Off", shape.raystartoff);
  519. shape.conformOffset = EditorGUILayout.FloatField("Conform Offset", shape.conformOffset);
  520. shape.raydist = EditorGUILayout.FloatField("Ray Dist", shape.raydist);
  521. EditorGUILayout.EndToggleGroup();
  522. }
  523. else
  524. {
  525. shape.ClearMesh();
  526. }
  527. showsplines = EditorGUILayout.Foldout(showsplines, "Spline Data");
  528. if ( showsplines )
  529. {
  530. EditorGUILayout.BeginVertical("Box");
  531. if ( shape.splines != null && shape.splines.Count > 0 )
  532. DisplaySpline(shape, shape.splines[shape.selcurve]);
  533. EditorGUILayout.EndVertical();
  534. }
  535. EditorGUILayout.BeginHorizontal();
  536. Color col = GUI.backgroundColor;
  537. GUI.backgroundColor = Color.green;
  538. if ( GUILayout.Button("Add") )
  539. {
  540. // Create a new spline in the shape
  541. MegaSpline spl = MegaSpline.Copy(shape.splines[shape.selcurve]);
  542. shape.splines.Add(spl);
  543. shape.selcurve = shape.splines.Count - 1;
  544. EditorUtility.SetDirty(shape);
  545. buildmesh = true;
  546. }
  547. if ( shape.splines.Count > 1 )
  548. {
  549. GUI.backgroundColor = Color.red;
  550. if ( GUILayout.Button("Delete") )
  551. {
  552. // Delete current spline
  553. shape.splines.RemoveAt(shape.selcurve);
  554. for ( int i = 0; i < shape.splines.Count; i++ )
  555. {
  556. if ( shape.splines[i].outlineSpline == shape.selcurve )
  557. shape.splines[i].outlineSpline = -1;
  558. if ( shape.splines[i].outlineSpline > shape.selcurve )
  559. shape.splines[i].outlineSpline--;
  560. }
  561. shape.selcurve--;
  562. if ( shape.selcurve < 0 )
  563. shape.selcurve = 0;
  564. EditorUtility.SetDirty(shape);
  565. buildmesh = true;
  566. }
  567. }
  568. GUI.backgroundColor = col;
  569. EditorGUILayout.EndHorizontal();
  570. }
  571. if ( !shape.imported )
  572. {
  573. if ( Params() )
  574. {
  575. rebuild = true;
  576. }
  577. }
  578. showfuncs = EditorGUILayout.Foldout(showfuncs, "Extra Functions");
  579. if ( showfuncs )
  580. {
  581. if ( GUILayout.Button("Flatten") )
  582. {
  583. PushSpline(shape.splines[shape.selcurve], shape.selcurve);
  584. shape.SetHeight(shape.selcurve, 0.0f);
  585. shape.CalcLength();
  586. EditorUtility.SetDirty(target);
  587. }
  588. if ( GUILayout.Button("Remove Twist") )
  589. {
  590. PushSpline(shape.splines[shape.selcurve], shape.selcurve);
  591. shape.SetTwist(shape.selcurve, 0.0f);
  592. EditorUtility.SetDirty(target);
  593. }
  594. if ( GUILayout.Button("Copy IDS") )
  595. {
  596. PushSpline(shape.splines[shape.selcurve], shape.selcurve);
  597. shape.CopyIDS(shape.selcurve);
  598. EditorUtility.SetDirty(target);
  599. }
  600. }
  601. export = EditorGUILayout.Foldout(export, "Export Options");
  602. if ( export )
  603. {
  604. xaxis = (MegaAxis)EditorGUILayout.EnumPopup("X Axis", xaxis);
  605. yaxis = (MegaAxis)EditorGUILayout.EnumPopup("Y Axis", yaxis);
  606. strokewidth = EditorGUILayout.FloatField("Stroke Width", strokewidth);
  607. strokecol = EditorGUILayout.ColorField("Stroke Color", strokecol);
  608. if ( GUILayout.Button("Export") )
  609. {
  610. Export(shape);
  611. }
  612. }
  613. if ( recalc )
  614. {
  615. shape.CalcLength(); //10);
  616. shape.BuildMesh();
  617. //MegaLoftLayerSimple[] layers = (MegaLoftLayerSimple[])FindObjectsOfType(typeof(MegaLoftLayerSimple));
  618. //for ( int i = 0; i < layers.Length; i++ )
  619. //{
  620. //layers[i].Notify(shape.splines[shape.selcurve], 0);
  621. //}
  622. EditorUtility.SetDirty(shape);
  623. }
  624. if ( GUI.changed )
  625. {
  626. EditorUtility.SetDirty(target);
  627. buildmesh = true;
  628. }
  629. if ( rebuild )
  630. {
  631. shape.MakeShape();
  632. EditorUtility.SetDirty(target);
  633. buildmesh = true;
  634. }
  635. if ( buildmesh )
  636. {
  637. if ( shape.makeMesh )
  638. {
  639. shape.SetMats();
  640. shape.BuildMesh();
  641. }
  642. }
  643. }
  644. void DisplayKnot(MegaShape shape, MegaSpline spline, MegaKnot knot, int i)
  645. {
  646. bool recalc = false;
  647. Vector3 p = EditorGUILayout.Vector3Field("Knot [" + i + "] Pos", knot.p);
  648. if ( p != knot.p )
  649. {
  650. PushSpline(spline, shape.selcurve);
  651. }
  652. delta = p - knot.p;
  653. knot.invec += delta;
  654. knot.outvec += delta;
  655. if ( knot.p != p )
  656. {
  657. recalc = true;
  658. knot.p = p;
  659. }
  660. if ( recalc )
  661. {
  662. shape.CalcLength(); //10);
  663. }
  664. knot.twist = EditorGUILayout.FloatField("Twist", knot.twist);
  665. knot.id = EditorGUILayout.IntField("ID", knot.id);
  666. }
  667. void DisplaySpline(MegaShape shape, MegaSpline spline)
  668. {
  669. bool closed = EditorGUILayout.Toggle("Closed", spline.closed);
  670. if ( closed != spline.closed )
  671. {
  672. PushSpline(spline, shape.selcurve);
  673. spline.closed = closed;
  674. shape.CalcLength(); //10);
  675. EditorUtility.SetDirty(target);
  676. }
  677. bool reverse = EditorGUILayout.Toggle("Reverse", spline.reverse);
  678. if ( reverse != spline.reverse )
  679. {
  680. PushSpline(spline, shape.selcurve);
  681. spline.reverse = reverse;
  682. }
  683. EditorGUILayout.LabelField("Length ", spline.length.ToString("0.000"));
  684. spline.twistmode = (MegaShapeEase)EditorGUILayout.EnumPopup("Twist Mode", spline.twistmode);
  685. showknots = EditorGUILayout.Foldout(showknots, "Knots");
  686. if ( showknots )
  687. {
  688. for ( int i = 0; i < spline.knots.Count; i++ )
  689. {
  690. DisplayKnot(shape, spline, spline.knots[i], i);
  691. }
  692. }
  693. }
  694. static bool editmode = true;
  695. //static string hackControlName = "hackery129578835432342";
  696. // call this function in OnGUI before calling TextField (only needs to be called once)
  697. //static void FocusHack() {
  698. // fake control used for unfocussing things, since we can't call
  699. // FocusControl with no arguments and an empty string doesn't work
  700. //GUI.SetNextControlName(hackControlName);
  701. //GUI.Button(new Rect(-10000,-10000, 0,0), GUIContent.none);
  702. //}
  703. string lastfocus = "";
  704. bool dragging = false;
  705. Vector3 CircleCap(int id, Vector3 pos, Quaternion rot, float size)
  706. {
  707. #if UNITY_2017_2 || UNITY_2017_3 || UNITY_2017_4 || UNITY_2018 || UNITY_2019 || UNITY_2020
  708. return Handles.FreeMoveHandle(cid, pos, rot, size, Vector3.zero, Handles.CircleHandleCap);
  709. #else
  710. #if UNITY_5_6 || UNITY_2017_1
  711. return Handles.FreeMoveHandle(pos, rot, size, Vector3.zero, Handles.CircleHandleCap);
  712. #else
  713. return Handles.FreeMoveHandle(pos, rot, size, Vector3.zero, Handles.CircleCap);
  714. #endif
  715. #endif
  716. }
  717. Vector3 SphereCap(int id, Vector3 pos, Quaternion rot, float size)
  718. {
  719. #if UNITY_2017_2 || UNITY_2017_3 || UNITY_2017_4 || UNITY_2018 || UNITY_2019 || UNITY_2020
  720. return Handles.FreeMoveHandle(cid, pos, rot, size, Vector3.zero, Handles.SphereHandleCap);
  721. #else
  722. #if UNITY_5_6 || UNITY_2017_1
  723. return Handles.FreeMoveHandle(pos, rot, size, Vector3.zero, Handles.SphereHandleCap);
  724. #else
  725. return Handles.FreeMoveHandle(pos, rot, size, Vector3.zero, Handles.SphereCap);
  726. #endif
  727. #endif
  728. }
  729. public void OnSceneGUI()
  730. {
  731. MegaShape shape = (MegaShape)target;
  732. bool mouseup = false;
  733. bool recalc = false;
  734. #if UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  735. if ( Event.current.type == EventType.MouseUp )
  736. #else
  737. if ( Event.current.type == EventType.mouseUp )
  738. #endif
  739. {
  740. mouseup = true;
  741. recalc = true;
  742. if ( dragging )
  743. PushSpline(shape.splines[shape.selcurve], shape.selcurve);
  744. dragging = false;
  745. }
  746. #if UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  747. if ( Event.current.type == EventType.MouseDown )
  748. #else
  749. if ( Event.current.type == EventType.mouseDown )
  750. #endif
  751. {
  752. }
  753. #if UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  754. if ( Event.current.type == EventType.MouseDrag && Event.current.button == 0 )
  755. #else
  756. if ( Event.current.type == EventType.mouseDrag && Event.current.button == 0 )
  757. #endif
  758. {
  759. dragging = true;
  760. }
  761. Handles.matrix = shape.transform.localToWorldMatrix;
  762. if ( shape.selcurve > shape.splines.Count - 1 )
  763. shape.selcurve = 0;
  764. Vector3 dragplane = Vector3.one;
  765. Color nocol = new Color(0, 0, 0, 0);
  766. bounds.size = Vector3.zero;
  767. Color twistcol = new Color(0.5f, 0.5f, 1.0f, 0.25f);
  768. //string hn = GUI.GetNameOfFocusedControl();
  769. string hn = GetControlName();
  770. //Debug.Log("hn " + hn);
  771. NewControlFrame();
  772. if ( hn != lastfocus )
  773. {
  774. if ( hn.Length > 0 )
  775. {
  776. if ( hn[0] == 'k' )
  777. {
  778. GUI.FocusControl("");
  779. string hn1 = hn.Replace('k', ' ');
  780. selected = int.Parse(hn1);
  781. }
  782. if ( hn[0] == 'a' )
  783. {
  784. PushSpline(shape.splines[shape.selcurve], shape.selcurve);
  785. GUI.FocusControl("");
  786. // Add knot
  787. string hn1 = hn.Replace('a', ' ');
  788. int ak = int.Parse(hn1);
  789. Vector3 mp = Vector3.zero;
  790. if ( shape.splines[shape.selcurve].closed )
  791. {
  792. mp = shape.splines[shape.selcurve].knots[ak].InterpolateCS(0.5f, shape.splines[shape.selcurve].knots[0]);
  793. }
  794. else
  795. {
  796. if ( ak == shape.splines[shape.selcurve].knots.Count - 1 )
  797. {
  798. mp = shape.InterpCurve3D(shape.selcurve, 1.02f, true); //.splines[s].knots[p].InterpolateCS(0.5f, shape.splines[s].knots[p + 1]);
  799. }
  800. else
  801. mp = shape.splines[shape.selcurve].knots[ak].InterpolateCS(0.5f, shape.splines[shape.selcurve].knots[ak + 1]);
  802. }
  803. MegaKnot knot = new MegaKnot();
  804. knot.p = mp;
  805. knot.id = shape.splines[shape.selcurve].knots[ak].id;
  806. knot.twist = shape.splines[shape.selcurve].knots[ak].twist;
  807. shape.splines[shape.selcurve].knots.Insert(ak + 1, knot);
  808. if ( shape.smoothonaddknot )
  809. shape.AutoCurve(shape.splines[shape.selcurve]); //, knum, knum + 2);
  810. shape.CalcLength(); //10);
  811. EditorUtility.SetDirty(target);
  812. if ( shape.makeMesh )
  813. {
  814. shape.SetMats();
  815. shape.BuildMesh();
  816. }
  817. }
  818. }
  819. lastfocus = hn;
  820. }
  821. // Draw nearest point (use for adding knot)
  822. Vector3 wcp = CursorPos;
  823. Vector3 newCursorPos = PosHandles(shape, wcp, Quaternion.identity);
  824. if ( newCursorPos != wcp )
  825. {
  826. Vector3 cd = newCursorPos - wcp;
  827. CursorPos += cd;
  828. float calpha = 0.0f;
  829. CursorPos = shape.FindNearestPoint(CursorPos, 5, ref CursorKnot, ref CursorTangent, ref calpha);
  830. shape.CursorPercent = calpha * 100.0f;
  831. }
  832. //GUI.SetNextControlName("Cursor");
  833. SetControlName("Cursor");
  834. Handles.Label(CursorPos, "Cursor " + shape.CursorPercent.ToString("0.00") + "% - " + CursorPos);
  835. // Move whole spline handle
  836. if ( shape.showorigin )
  837. {
  838. //GUI.SetNextControlName("Origin");
  839. SetControlName("Origin");
  840. Handles.Label(bounds.min, "Origin");
  841. Vector3 spos = Handles.PositionHandle(bounds.min, Quaternion.identity);
  842. if ( spos != bounds.min )
  843. {
  844. if ( shape.usesnap )
  845. {
  846. if ( shape.snap.x != 0.0f )
  847. spos.x = (int)(spos.x / shape.snap.x) * shape.snap.x;
  848. if ( shape.snap.y != 0.0f )
  849. spos.y = (int)(spos.y / shape.snap.y) * shape.snap.y;
  850. if ( shape.snap.z != 0.0f )
  851. spos.z = (int)(spos.z / shape.snap.z) * shape.snap.z;
  852. }
  853. // Move the spline
  854. shape.MoveSpline(spos - bounds.min, shape.selcurve, false);
  855. recalc = true;
  856. }
  857. }
  858. Vector3 np = Vector3.zero;
  859. Quaternion fwd = Quaternion.identity;
  860. Vector3 rg = Vector3.zero;
  861. for ( int s = 0; s < shape.splines.Count; s++ )
  862. {
  863. for ( int p = 0; p < shape.splines[s].knots.Count; p++ )
  864. {
  865. if ( p == selected )
  866. {
  867. if ( p == 0 || p < shape.splines[s].knots.Count - 2 )
  868. {
  869. np = shape.splines[s].knots[p].Interpolate(0.002f, shape.splines[s].knots[p + 1]);
  870. np = np - shape.splines[s].knots[p].p;
  871. }
  872. else
  873. {
  874. if ( shape.splines[s].closed )
  875. {
  876. np = shape.splines[s].knots[p].Interpolate(0.002f, shape.splines[s].knots[0]);
  877. np = np - shape.splines[s].knots[p].p;
  878. }
  879. else
  880. {
  881. np = shape.splines[s].knots[p - 1].Interpolate(0.998f, shape.splines[s].knots[p]);
  882. np = shape.splines[s].knots[p].p - np;
  883. }
  884. }
  885. if ( np == Vector3.zero )
  886. np = Vector3.forward;
  887. np = np.normalized;
  888. // np holds the tangent so we can align the arc
  889. fwd = Quaternion.LookRotation(np);
  890. rg = Vector3.Cross(np, Vector3.up);
  891. }
  892. if ( s == shape.selcurve )
  893. {
  894. bounds.Encapsulate(shape.splines[s].knots[p].p);
  895. }
  896. if ( shape.drawKnots && s == shape.selcurve )
  897. {
  898. pm = shape.splines[s].knots[p].p;
  899. if ( showlabels )
  900. {
  901. if ( p == selected && s == shape.selcurve )
  902. {
  903. Color col = Color.white;
  904. col.a = 1.0f;
  905. Handles.color = col;
  906. Handles.Label(pm, " Selected\n" + pm.ToString("0.000"));
  907. }
  908. else
  909. {
  910. Handles.color = shape.KnotCol;
  911. Handles.Label(pm, " " + p);
  912. }
  913. }
  914. Handles.color = nocol;
  915. Vector3 newp = Vector3.zero;
  916. //GUI.SetNextControlName("k" + p.ToString());
  917. SetControlName("k" + p.ToString());
  918. if ( p == selected )
  919. {
  920. if ( shape.usesnap )
  921. newp = PosHandlesSnap(shape, pm, fwd); //Quaternion.identity);
  922. else
  923. newp = PosHandles(shape, pm, fwd); //Quaternion.identity);
  924. if ( newp != pm )
  925. {
  926. if ( shape.freezeX ) newp.x = pm.x;
  927. if ( shape.freezeY ) newp.y = pm.y;
  928. if ( shape.freezeZ ) newp.z = pm.z;
  929. MegaUndo.SetSnapshotTarget(shape, "Knot Move");
  930. }
  931. Vector3 dl = Vector3.Scale(newp - pm, dragplane);
  932. shape.splines[s].knots[p].p += dl; //Vector3.Scale(newp - pm, dragplane);
  933. shape.splines[s].knots[p].invec += dl; //delta;
  934. shape.splines[s].knots[p].outvec += dl; //delta;
  935. if ( newp != pm )
  936. {
  937. if ( shape.smoothOnDrag )
  938. shape.AutoCurve();
  939. recalc = true;
  940. }
  941. }
  942. else
  943. {
  944. //Handles.FreeMoveHandle(pm, Quaternion.identity, shape.KnotSize * 0.01f, Vector3.zero, Handles.CircleCap);
  945. CircleCap(0, pm, Quaternion.identity, shape.KnotSize * 0.01f);
  946. }
  947. //GUI.SetNextControlName("");
  948. //SetControlName("");
  949. }
  950. if ( shape.drawHandles && s == shape.selcurve )
  951. {
  952. if ( p == selected )
  953. {
  954. Handles.color = shape.VecCol;
  955. pm = shape.splines[s].knots[p].p;
  956. Vector3 ip = shape.splines[s].knots[p].invec;
  957. Vector3 op = shape.splines[s].knots[p].outvec;
  958. //GUI.SetNextControlName("hli" + p.ToString());
  959. SetControlName("hli" + p.ToString());
  960. Handles.DrawLine(pm, ip);
  961. //GUI.SetNextControlName("hlo" + p.ToString());
  962. SetControlName("hlo" + p.ToString());
  963. Handles.DrawLine(pm, op);
  964. Handles.color = shape.HandleCol;
  965. Vector3 invec = shape.splines[s].knots[p].invec;
  966. Handles.color = nocol;
  967. Vector3 newinvec = Vector3.zero;
  968. //GUI.SetNextControlName("hi" + p.ToString());
  969. SetControlName("hi" + p.ToString());
  970. if ( shape.usesnaphandles )
  971. newinvec = PosHandlesSnap(shape, invec, Quaternion.identity);
  972. else
  973. newinvec = PosHandles(shape, invec, Quaternion.identity);
  974. if ( newinvec != invec ) //shape.splines[s].knots[p].invec )
  975. {
  976. MegaUndo.SetSnapshotTarget(shape, "Handle Move");
  977. }
  978. Vector3 dl = Vector3.Scale(newinvec - invec, dragplane);
  979. shape.splines[s].knots[p].invec += dl; //Vector3.Scale(newinvec - invec, dragplane);
  980. if ( invec != newinvec ) //shape.splines[s].knots[p].invec )
  981. {
  982. if ( shape.lockhandles )
  983. shape.splines[s].knots[p].outvec -= dl;
  984. selected = p;
  985. recalc = true;
  986. }
  987. Vector3 outvec = shape.splines[s].knots[p].outvec;
  988. //GUI.SetNextControlName("ho" + p.ToString());
  989. SetControlName("ho" + p.ToString());
  990. Vector3 newoutvec = Vector3.zero;
  991. if ( shape.usesnaphandles )
  992. newoutvec = PosHandlesSnap(shape, outvec, Quaternion.identity);
  993. else
  994. newoutvec = PosHandles(shape, outvec, Quaternion.identity);
  995. if ( newoutvec != outvec ) //shape.splines[s].knots[p].outvec )
  996. {
  997. MegaUndo.SetSnapshotTarget(shape, "Handle Move");
  998. }
  999. dl = Vector3.Scale(newoutvec - outvec, dragplane);
  1000. shape.splines[s].knots[p].outvec += dl;
  1001. if ( outvec != newoutvec ) //shape.splines[s].knots[p].outvec )
  1002. {
  1003. if ( shape.lockhandles )
  1004. shape.splines[s].knots[p].invec -= dl;
  1005. selected = p;
  1006. recalc = true;
  1007. }
  1008. Vector3 hp = shape.splines[s].knots[p].invec;
  1009. if ( selected == p )
  1010. Handles.Label(hp, " " + p);
  1011. hp = shape.splines[s].knots[p].outvec;
  1012. if ( selected == p )
  1013. Handles.Label(hp, " " + p);
  1014. }
  1015. }
  1016. // Twist handles
  1017. if ( shape.drawTwist && s == shape.selcurve && p == selected )
  1018. {
  1019. Handles.color = twistcol;
  1020. float twist = shape.splines[s].knots[p].twist;
  1021. Handles.DrawSolidArc(shape.splines[s].knots[p].p, np, rg, twist, shape.KnotSize * 0.1f);
  1022. Vector3 tang = new Vector3(0.0f, 0.0f, shape.splines[s].knots[p].twist);
  1023. Quaternion inrot = fwd * Quaternion.Euler(tang);
  1024. //Quaternion rot = Handles.RotationHandle(inrot, shape.splines[s].knots[p].p);
  1025. Handles.color = Color.white;
  1026. Quaternion rot = Handles.Disc(inrot, shape.splines[s].knots[p].p, np, shape.KnotSize * 0.1f, false, 0.0f);
  1027. if ( rot != inrot )
  1028. {
  1029. tang = rot.eulerAngles;
  1030. float diff = (tang.z - shape.splines[s].knots[p].twist);
  1031. if ( Mathf.Abs(diff) > 0.0001f )
  1032. {
  1033. while ( diff > 180.0f )
  1034. diff -= 360.0f;
  1035. while ( diff < -180.0f )
  1036. diff += 360.0f;
  1037. shape.splines[s].knots[p].twist += diff;
  1038. recalc = true;
  1039. }
  1040. }
  1041. }
  1042. // Midpoint add knot code
  1043. if ( s == shape.selcurve )
  1044. {
  1045. if ( p < shape.splines[s].knots.Count - 1 )
  1046. {
  1047. Handles.color = Color.white;
  1048. Vector3 mp = shape.splines[s].knots[p].InterpolateCS(0.5f, shape.splines[s].knots[p + 1]);
  1049. //GUI.SetNextControlName("a" + p.ToString());
  1050. SetControlName("a" + p.ToString());
  1051. //Handles.FreeMoveHandle(mp, Quaternion.identity, shape.KnotSize * 0.01f, Vector3.zero, Handles.CircleCap);
  1052. CircleCap(0, mp, Quaternion.identity, shape.KnotSize * 0.01f);
  1053. //FocusHack();
  1054. }
  1055. else
  1056. {
  1057. if ( shape.splines[s].closed )
  1058. {
  1059. Handles.color = Color.white;
  1060. Vector3 mp = shape.splines[s].knots[p].InterpolateCS(0.5f, shape.splines[s].knots[0]);
  1061. //GUI.SetNextControlName("a" + p.ToString());
  1062. SetControlName("a" + p.ToString());
  1063. //Handles.FreeMoveHandle(mp, Quaternion.identity, shape.KnotSize * 0.01f, Vector3.zero, Handles.CircleCap);
  1064. CircleCap(0, mp, Quaternion.identity, shape.KnotSize * 0.01f);
  1065. }
  1066. else
  1067. {
  1068. Handles.color = Color.white;
  1069. Vector3 mp = shape.InterpCurve3D(s, 1.02f, true); //.splines[s].knots[p].InterpolateCS(0.5f, shape.splines[s].knots[p + 1]);
  1070. //GUI.SetNextControlName("a" + p.ToString());
  1071. SetControlName("a" + p.ToString());
  1072. //Handles.FreeMoveHandle(mp, Quaternion.identity, shape.KnotSize * 0.01f, Vector3.zero, Handles.CircleCap);
  1073. CircleCap(0, mp, Quaternion.identity, shape.KnotSize * 0.01f);
  1074. }
  1075. }
  1076. }
  1077. }
  1078. }
  1079. //GUI.SetNextControlName("");
  1080. //SetControlName("");
  1081. if ( recalc )
  1082. {
  1083. shape.CalcLength(); //10);
  1084. if ( shape.updateondrag || (!shape.updateondrag && mouseup) )
  1085. {
  1086. shape.BuildMesh();
  1087. //MegaLoftLayerSimple[] layers = (MegaLoftLayerSimple[])FindObjectsOfType(typeof(MegaLoftLayerSimple));
  1088. //for ( int i = 0; i < layers.Length; i++ )
  1089. //layers[i].Notify(shape.splines[shape.selcurve], 0);
  1090. EditorUtility.SetDirty(shape);
  1091. }
  1092. }
  1093. Handles.matrix = Matrix4x4.identity;
  1094. // This is wrong gui not changing here
  1095. if ( GUI.changed )
  1096. {
  1097. MegaUndo.CreateSnapshot();
  1098. MegaUndo.RegisterSnapshot();
  1099. }
  1100. MegaUndo.ClearSnapshotTarget();
  1101. }
  1102. Vector3 PosHandlesSnap(MegaShape shape, Vector3 pos, Quaternion q)
  1103. {
  1104. switch ( shape.handleType )
  1105. {
  1106. case MegaHandleType.Position:
  1107. pos = PositionHandle(pos, q, 1.0f, 0.75f);
  1108. break;
  1109. case MegaHandleType.Free:
  1110. //pos = Handles.FreeMoveHandle(pos, q, shape.KnotSize * 0.01f, Vector3.zero, Handles.SphereCap); //CircleCap);
  1111. pos = SphereCap(0, pos, q, shape.KnotSize * 0.01f);
  1112. break;
  1113. }
  1114. if ( shape.usesnap )
  1115. {
  1116. if ( shape.snap.x != 0.0f )
  1117. pos.x = (int)(pos.x / shape.snap.x) * shape.snap.x;
  1118. if ( shape.snap.y != 0.0f )
  1119. pos.y = (int)(pos.y / shape.snap.y) * shape.snap.y;
  1120. if ( shape.snap.z != 0.0f )
  1121. pos.z = (int)(pos.z / shape.snap.z) * shape.snap.z;
  1122. }
  1123. return pos;
  1124. }
  1125. Vector3 PosHandles(MegaShape shape, Vector3 pos, Quaternion q)
  1126. {
  1127. switch ( shape.handleType )
  1128. {
  1129. case MegaHandleType.Position:
  1130. pos = PositionHandle(pos, q, 1.0f, 0.75f);
  1131. break;
  1132. case MegaHandleType.Free:
  1133. //pos = Handles.FreeMoveHandle(pos, q, shape.KnotSize * 0.01f, Vector3.zero, Handles.CircleCap);
  1134. pos = CircleCap(0, pos, q, shape.KnotSize * 0.01f);
  1135. break;
  1136. }
  1137. return pos;
  1138. }
  1139. #if UNITY_2017_2 || UNITY_2017_3 || UNITY_2017_4 || UNITY_2018 || UNITY_2019 || UNITY_2020
  1140. public static Vector3 PositionHandle(Vector3 position, Quaternion rotation, float size, float alpha)
  1141. {
  1142. return Handles.PositionHandle(position, rotation);
  1143. #if false
  1144. float handlesize = HandleUtility.GetHandleSize(position) * size;
  1145. Color color = Handles.color;
  1146. Color col = Color.red;
  1147. col.a = alpha;
  1148. Handles.color = col; //Color.red; //Handles..xAxisColor;
  1149. //position = Handles.Slider(position, rotation * Vector3.right, handlesize, new Handles.DrawCapFunction(Handles.ArrowHandleCap), 0.0f); //SnapSettings.move.x);
  1150. position = Handles.Slider(cid, position, rotation * Vector3.right, handlesize, Handles.ArrowHandleCap, 0.0f); // new Handles.DrawCapFunction(Handles.ArrowHandleCap), 0.0f); //SnapSettings.move.x);
  1151. col = Color.green;
  1152. col.a = alpha;
  1153. Handles.color = col; //Color.green; //Handles.yAxisColor;
  1154. position = Handles.Slider(cid, position, rotation * Vector3.up, handlesize, Handles.ArrowHandleCap, 0.0f); //SnapSettings.move.y);
  1155. col = Color.blue;
  1156. col.a = alpha;
  1157. Handles.color = col; //Color.blue; //Handles.zAxisColor;
  1158. position = Handles.Slider(cid, position, rotation * Vector3.forward, handlesize, Handles.ArrowHandleCap, 0.0f); //SnapSettings.move.z);
  1159. col = Color.yellow;
  1160. col.a = alpha;
  1161. Handles.color = col; //Color.yellow; //Handles.centerColor;
  1162. position = Handles.FreeMoveHandle(cid, position, rotation, handlesize * 0.15f, Vector3.zero, Handles.RectangleHandleCap);
  1163. Handles.color = color;
  1164. return position;
  1165. #endif
  1166. }
  1167. #else
  1168. #if UNITY_5_6 || UNITY_2017_1
  1169. public static Vector3 PositionHandle(Vector3 position, Quaternion rotation, float size, float alpha)
  1170. {
  1171. float handlesize = HandleUtility.GetHandleSize(position) * size;
  1172. Color color = Handles.color;
  1173. Color col = Color.red;
  1174. col.a = alpha;
  1175. Handles.color = col; //Color.red; //Handles..xAxisColor;
  1176. //position = Handles.Slider(position, rotation * Vector3.right, handlesize, new Handles.DrawCapFunction(Handles.ArrowHandleCap), 0.0f); //SnapSettings.move.x);
  1177. position = Handles.Slider(position, rotation * Vector3.right, handlesize, Handles.ArrowHandleCap, 0.0f); // new Handles.DrawCapFunction(Handles.ArrowHandleCap), 0.0f); //SnapSettings.move.x);
  1178. col = Color.green;
  1179. col.a = alpha;
  1180. Handles.color = col; //Color.green; //Handles.yAxisColor;
  1181. position = Handles.Slider(position, rotation * Vector3.up, handlesize, Handles.ArrowHandleCap, 0.0f); //SnapSettings.move.y);
  1182. col = Color.blue;
  1183. col.a = alpha;
  1184. Handles.color = col; //Color.blue; //Handles.zAxisColor;
  1185. position = Handles.Slider(position, rotation * Vector3.forward, handlesize, Handles.ArrowHandleCap, 0.0f); //SnapSettings.move.z);
  1186. col = Color.yellow;
  1187. col.a = alpha;
  1188. Handles.color = col; //Color.yellow; //Handles.centerColor;
  1189. position = Handles.FreeMoveHandle(position, rotation, handlesize * 0.15f, Vector3.zero, Handles.RectangleHandleCap);
  1190. Handles.color = color;
  1191. return position;
  1192. }
  1193. #else
  1194. public static Vector3 PositionHandle(Vector3 position, Quaternion rotation, float size, float alpha)
  1195. {
  1196. float handlesize = HandleUtility.GetHandleSize(position) * size;
  1197. Color color = Handles.color;
  1198. Color col = Color.red;
  1199. col.a = alpha;
  1200. Handles.color = col; //Color.red; //Handles..xAxisColor;
  1201. position = Handles.Slider(position, rotation * Vector3.right, handlesize, new Handles.DrawCapFunction(Handles.ArrowCap), 0.0f); //SnapSettings.move.x);
  1202. col = Color.green;
  1203. col.a = alpha;
  1204. Handles.color = col; //Color.green; //Handles.yAxisColor;
  1205. position = Handles.Slider(position, rotation * Vector3.up, handlesize, new Handles.DrawCapFunction(Handles.ArrowCap), 0.0f); //SnapSettings.move.y);
  1206. col = Color.blue;
  1207. col.a = alpha;
  1208. Handles.color = col; //Color.blue; //Handles.zAxisColor;
  1209. position = Handles.Slider(position, rotation * Vector3.forward, handlesize, new Handles.DrawCapFunction(Handles.ArrowCap), 0.0f); //SnapSettings.move.z);
  1210. col = Color.yellow;
  1211. col.a = alpha;
  1212. Handles.color = col; //Color.yellow; //Handles.centerColor;
  1213. position = Handles.FreeMoveHandle(position, rotation, handlesize * 0.15f, Vector3.zero, new Handles.DrawCapFunction(Handles.RectangleCap));
  1214. Handles.color = color;
  1215. return position;
  1216. }
  1217. #endif
  1218. #endif
  1219. #if UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5 || UNITY_5_6 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  1220. [DrawGizmo(GizmoType.NotInSelectionHierarchy | GizmoType.Pickable | GizmoType.InSelectionHierarchy)]
  1221. #else
  1222. [DrawGizmo(GizmoType.NotSelected | GizmoType.Pickable | GizmoType.SelectedOrChild)]
  1223. #endif
  1224. static void RenderGizmo(MegaShape shape, GizmoType gizmoType)
  1225. {
  1226. if ( (gizmoType & GizmoType.Active) != 0 && Selection.activeObject == shape.gameObject )
  1227. {
  1228. if ( shape.splines == null || shape.splines.Count == 0 )
  1229. return;
  1230. DrawGizmos(shape, new Color(1.0f, 1.0f, 1.0f, 1.0f));
  1231. if ( shape.splines[shape.selcurve].knots.Count > 1 )
  1232. {
  1233. Color col = Color.yellow;
  1234. col.a = 0.5f;
  1235. Gizmos.color = col; //Color.yellow;
  1236. CursorPos = shape.InterpCurve3D(shape.selcurve, shape.CursorPercent * 0.01f, true);
  1237. Gizmos.DrawSphere(shape.transform.TransformPoint(CursorPos), shape.KnotSize * 0.01f);
  1238. Handles.color = Color.white;
  1239. if ( MegaShapeEditor.editor != null && editmode ) ////if ( shape.handleType == MegaHandleType.Free && editmode )
  1240. {
  1241. int s = shape.selcurve;
  1242. {
  1243. for ( int p = 0; p < shape.splines[s].knots.Count; p++ )
  1244. {
  1245. if ( p == MegaShapeEditor.editor.selected )
  1246. {
  1247. if ( shape.handleType == MegaHandleType.Free )
  1248. {
  1249. if ( shape.drawKnots ) //&& s == shape.selcurve )
  1250. {
  1251. Gizmos.color = Color.green;
  1252. Gizmos.DrawSphere(shape.transform.TransformPoint(shape.splines[s].knots[p].p), shape.KnotSize * 0.01f);
  1253. }
  1254. if ( shape.drawHandles )
  1255. {
  1256. Gizmos.color = Color.red;
  1257. Gizmos.DrawSphere(shape.transform.TransformPoint(shape.splines[s].knots[p].invec), shape.KnotSize * 0.01f);
  1258. Gizmos.DrawSphere(shape.transform.TransformPoint(shape.splines[s].knots[p].outvec), shape.KnotSize * 0.01f);
  1259. }
  1260. }
  1261. }
  1262. else
  1263. {
  1264. Gizmos.color = Color.green;
  1265. Gizmos.DrawSphere(shape.transform.TransformPoint(shape.splines[s].knots[p].p), shape.KnotSize * 0.01f);
  1266. }
  1267. }
  1268. }
  1269. }
  1270. }
  1271. }
  1272. else
  1273. DrawGizmos(shape, new Color(1.0f, 1.0f, 1.0f, 0.25f));
  1274. if ( Camera.current )
  1275. {
  1276. Vector3 vis = Camera.current.WorldToScreenPoint(shape.transform.position);
  1277. if ( vis.z > 0.0f )
  1278. {
  1279. Gizmos.DrawIcon(shape.transform.position, "MegaSpherify icon.png", false);
  1280. Handles.Label(shape.transform.position, " " + shape.name);
  1281. }
  1282. }
  1283. }
  1284. // Dont want this in here, want in editor
  1285. // If we go over a knot then should draw to the knot
  1286. static void DrawGizmos(MegaShape shape, Color modcol1)
  1287. {
  1288. if ( ((1 << shape.gameObject.layer) & Camera.current.cullingMask) == 0 )
  1289. return;
  1290. if ( !shape.drawspline )
  1291. return;
  1292. Matrix4x4 tm = shape.transform.localToWorldMatrix;
  1293. for ( int s = 0; s < shape.splines.Count; s++ )
  1294. {
  1295. if ( shape.splines[s].knots.Count > 1 )
  1296. {
  1297. float ldist = shape.stepdist * 0.1f;
  1298. if ( ldist < 0.01f )
  1299. ldist = 0.01f;
  1300. Color modcol = modcol1;
  1301. if ( s != shape.selcurve && modcol1.a == 1.0f )
  1302. modcol.a *= 0.5f;
  1303. if ( shape.splines[s].length / ldist > 500.0f )
  1304. ldist = shape.splines[s].length / 500.0f;
  1305. float ds = shape.splines[s].length / (shape.splines[s].length / ldist);
  1306. if ( ds > shape.splines[s].length )
  1307. ds = shape.splines[s].length;
  1308. int c = 0;
  1309. int k = -1;
  1310. int lk = -1;
  1311. Vector3 first = shape.splines[s].Interpolate(0.0f, shape.normalizedInterp, ref lk);
  1312. for ( float dist = ds; dist < shape.splines[s].length; dist += ds )
  1313. {
  1314. float alpha = dist / shape.splines[s].length;
  1315. Vector3 pos = shape.splines[s].Interpolate(alpha, shape.normalizedInterp, ref k);
  1316. if ( (c & 1) == 1 )
  1317. Gizmos.color = shape.col1 * modcol;
  1318. else
  1319. Gizmos.color = shape.col2 * modcol;
  1320. if ( k != lk )
  1321. {
  1322. for ( lk = lk + 1; lk <= k; lk++ )
  1323. {
  1324. Gizmos.DrawLine(tm.MultiplyPoint(first), tm.MultiplyPoint(shape.splines[s].knots[lk].p));
  1325. first = shape.splines[s].knots[lk].p;
  1326. }
  1327. }
  1328. lk = k;
  1329. Gizmos.DrawLine(tm.MultiplyPoint(first), tm.MultiplyPoint(pos));
  1330. c++;
  1331. first = pos;
  1332. }
  1333. if ( (c & 1) == 1 )
  1334. Gizmos.color = shape.col1 * modcol;
  1335. else
  1336. Gizmos.color = shape.col2 * modcol;
  1337. Vector3 lastpos;
  1338. if ( shape.splines[s].closed )
  1339. lastpos = shape.splines[s].Interpolate(0.0f, shape.normalizedInterp, ref k);
  1340. else
  1341. lastpos = shape.splines[s].Interpolate(1.0f, shape.normalizedInterp, ref k);
  1342. Gizmos.DrawLine(tm.MultiplyPoint(first), tm.MultiplyPoint(lastpos));
  1343. }
  1344. }
  1345. }
  1346. void LoadSVG(float scale)
  1347. {
  1348. MegaShape ms = (MegaShape)target;
  1349. string filename = EditorUtility.OpenFilePanel("SVG File", lastpath, "svg");
  1350. if ( filename == null || filename.Length < 1 )
  1351. return;
  1352. lastpath = filename;
  1353. bool opt = true;
  1354. if ( ms.splines != null && ms.splines.Count > 0 )
  1355. opt = EditorUtility.DisplayDialog("Spline Import Option", "Splines already present, do you want to 'Add' or 'Replace' splines with this file?", "Add", "Replace");
  1356. int startspline = 0;
  1357. if ( opt )
  1358. startspline = ms.splines.Count;
  1359. StreamReader streamReader = new StreamReader(filename);
  1360. string text = streamReader.ReadToEnd();
  1361. streamReader.Close();
  1362. MegaShapeSVG svg = new MegaShapeSVG();
  1363. svg.importData(text, ms, scale, opt, startspline); //.splines[0]);
  1364. ms.imported = true;
  1365. }
  1366. void LoadSXL(float scale)
  1367. {
  1368. MegaShape ms = (MegaShape)target;
  1369. string filename = EditorUtility.OpenFilePanel("SXL File", lastpath, "sxl");
  1370. if ( filename == null || filename.Length < 1 )
  1371. return;
  1372. lastpath = filename;
  1373. bool opt = true;
  1374. if ( ms.splines != null && ms.splines.Count > 0 )
  1375. opt = EditorUtility.DisplayDialog("Spline Import Option", "Splines already present, do you want to 'Add' or 'Replace' splines with this file?", "Add", "Replace");
  1376. int startspline = 0;
  1377. if ( opt )
  1378. startspline = ms.splines.Count;
  1379. StreamReader streamReader = new StreamReader(filename);
  1380. string text = streamReader.ReadToEnd();
  1381. streamReader.Close();
  1382. MegaShapeSXL sxl = new MegaShapeSXL();
  1383. sxl.importData(text, ms, scale, opt, startspline); //.splines[0]);
  1384. ms.imported = true;
  1385. }
  1386. void LoadKML(float scale)
  1387. {
  1388. MegaShape ms = (MegaShape)target;
  1389. string filename = EditorUtility.OpenFilePanel("KML File", lastpath, "kml");
  1390. if ( filename == null || filename.Length < 1 )
  1391. return;
  1392. lastpath = filename;
  1393. MegaKML kml = new MegaKML();
  1394. kml.KMLDecode(filename);
  1395. Vector3[] points = kml.GetPoints(ImportScale);
  1396. ms.BuildSpline(ms.selcurve, points, true);
  1397. }
  1398. void LoadShape(float scale)
  1399. {
  1400. MegaShape ms = (MegaShape)target;
  1401. string filename = EditorUtility.OpenFilePanel("Shape File", lastpath, "spl");
  1402. if ( filename == null || filename.Length < 1 )
  1403. return;
  1404. lastpath = filename;
  1405. // Clear what we have
  1406. bool opt = true;
  1407. if ( ms.splines != null && ms.splines.Count > 0 )
  1408. opt = EditorUtility.DisplayDialog("Spline Import Option", "Splines already present, do you want to 'Add' or 'Replace' splines with this file?", "Add", "Replace");
  1409. int startspline = 0;
  1410. if ( opt )
  1411. startspline = ms.splines.Count;
  1412. else
  1413. ms.splines.Clear();
  1414. ParseFile(filename, ShapeCallback);
  1415. ms.Scale(scale, startspline);
  1416. ms.MaxTime = 0.0f;
  1417. for ( int s = 0; s < ms.splines.Count; s++ )
  1418. {
  1419. if ( ms.splines[s].animations != null )
  1420. {
  1421. for ( int a = 0; a < ms.splines[s].animations.Count; a++ )
  1422. {
  1423. MegaControl con = ms.splines[s].animations[a].con;
  1424. if ( con != null )
  1425. {
  1426. float t = con.Times[con.Times.Length - 1];
  1427. if ( t > ms.MaxTime )
  1428. ms.MaxTime = t;
  1429. }
  1430. }
  1431. }
  1432. }
  1433. ms.imported = true;
  1434. }
  1435. public void ShapeCallback(string classname, BinaryReader br)
  1436. {
  1437. switch ( classname )
  1438. {
  1439. case "Shape": LoadShape(br); break;
  1440. }
  1441. }
  1442. public void LoadShape(BinaryReader br)
  1443. {
  1444. MegaParse.Parse(br, ParseShape);
  1445. }
  1446. public void ParseFile(string assetpath, ParseClassCallbackType cb)
  1447. {
  1448. FileStream fs = new FileStream(assetpath, FileMode.Open, FileAccess.Read, System.IO.FileShare.Read);
  1449. BinaryReader br = new BinaryReader(fs);
  1450. bool processing = true;
  1451. while ( processing )
  1452. {
  1453. string classname = MegaParse.ReadString(br);
  1454. if ( classname == "Done" )
  1455. break;
  1456. int chunkoff = br.ReadInt32();
  1457. long fpos = fs.Position;
  1458. cb(classname, br);
  1459. fs.Position = fpos + chunkoff;
  1460. }
  1461. br.Close();
  1462. }
  1463. static public Vector3 ReadP3(BinaryReader br)
  1464. {
  1465. Vector3 p = Vector3.zero;
  1466. p.x = br.ReadSingle();
  1467. p.y = br.ReadSingle();
  1468. p.z = br.ReadSingle();
  1469. return p;
  1470. }
  1471. bool SplineParse(BinaryReader br, string cid)
  1472. {
  1473. MegaShape ms = (MegaShape)target;
  1474. MegaSpline ps = ms.splines[ms.splines.Count - 1];
  1475. switch ( cid )
  1476. {
  1477. case "Transform":
  1478. Vector3 pos = ReadP3(br);
  1479. Vector3 rot = ReadP3(br);
  1480. Vector3 scl = ReadP3(br);
  1481. rot.y = -rot.y;
  1482. ms.transform.position = pos;
  1483. ms.transform.rotation = Quaternion.Euler(rot * Mathf.Rad2Deg);
  1484. ms.transform.localScale = scl;
  1485. break;
  1486. case "Flags":
  1487. int count = br.ReadInt32();
  1488. ps.closed = (br.ReadInt32() == 1);
  1489. count = br.ReadInt32();
  1490. ps.knots = new List<MegaKnot>(count);
  1491. ps.length = 0.0f;
  1492. break;
  1493. case "Knots":
  1494. for ( int i = 0; i < ps.knots.Capacity; i++ )
  1495. {
  1496. MegaKnot pk = new MegaKnot();
  1497. pk.p = ReadP3(br);
  1498. pk.invec = ReadP3(br);
  1499. pk.outvec = ReadP3(br);
  1500. pk.seglength = br.ReadSingle();
  1501. ps.length += pk.seglength;
  1502. pk.length = ps.length;
  1503. ps.knots.Add(pk);
  1504. }
  1505. break;
  1506. }
  1507. return true;
  1508. }
  1509. bool AnimParse(BinaryReader br, string cid)
  1510. {
  1511. MegaShape ms = (MegaShape)target;
  1512. switch ( cid )
  1513. {
  1514. case "V":
  1515. int v = br.ReadInt32();
  1516. ma = new MegaKnotAnim();
  1517. int s = ms.GetSpline(v, ref ma); //.s, ref ma.p, ref ma.t);
  1518. if ( ms.splines[s].animations == null )
  1519. ms.splines[s].animations = new List<MegaKnotAnim>();
  1520. ms.splines[s].animations.Add(ma);
  1521. break;
  1522. case "Anim":
  1523. ma.con = MegaParseBezVector3Control.LoadBezVector3KeyControl(br);
  1524. break;
  1525. }
  1526. return true;
  1527. }
  1528. bool ParseShape(BinaryReader br, string cid)
  1529. {
  1530. MegaShape ms = (MegaShape)target;
  1531. switch ( cid )
  1532. {
  1533. case "Num":
  1534. int count = br.ReadInt32();
  1535. ms.splines = new List<MegaSpline>(count);
  1536. break;
  1537. case "Spline":
  1538. MegaSpline spl = new MegaSpline();
  1539. ms.splines.Add(spl);
  1540. MegaParse.Parse(br, SplineParse);
  1541. break;
  1542. case "Anim":
  1543. MegaParse.Parse(br, AnimParse);
  1544. break;
  1545. }
  1546. return true;
  1547. }
  1548. [MenuItem("GameObject/Create MegaShape Prefab")]
  1549. static void DoCreateSimplePrefabNew()
  1550. {
  1551. if ( Selection.activeGameObject != null )
  1552. {
  1553. if ( !Directory.Exists("Assets/MegaPrefabs") )
  1554. {
  1555. AssetDatabase.CreateFolder("Assets", "MegaPrefabs");
  1556. }
  1557. GameObject obj = Selection.activeGameObject;
  1558. #if UNITY_2019 || UNITY_2018_3 || UNITY_2020
  1559. GameObject prefab = PrefabUtility.SaveAsPrefabAsset(Selection.activeGameObject, "Assets/MegaPrefabs/" + Selection.activeGameObject.name + ".prefab");
  1560. #else
  1561. GameObject prefab = PrefabUtility.CreatePrefab("Assets/MegaPrefabs/" + Selection.activeGameObject.name + ".prefab", Selection.activeGameObject);
  1562. #endif
  1563. MeshFilter mf = obj.GetComponent<MeshFilter>();
  1564. if ( mf )
  1565. {
  1566. MeshFilter newmf = prefab.GetComponent<MeshFilter>();
  1567. Mesh mesh = CloneMesh(mf.sharedMesh);
  1568. mesh.name = obj.name + " copy";
  1569. AssetDatabase.AddObjectToAsset(mesh, prefab);
  1570. newmf.sharedMesh = mesh;
  1571. MeshCollider mc = prefab.GetComponent<MeshCollider>();
  1572. if ( mc )
  1573. {
  1574. mc.sharedMesh = null;
  1575. mc.sharedMesh = mesh;
  1576. }
  1577. }
  1578. //MegaShapeLoft oldloft = obj.GetComponent<MegaShapeLoft>();
  1579. //MegaShapeLoft loft = prefab.GetComponent<MegaShapeLoft>();
  1580. //if ( loft )
  1581. //{
  1582. //for ( int i = 0; i < loft.Layers.Length; i++ )
  1583. //loft.Layers[i].CopyLayer(oldloft.Layers[i]);
  1584. //}
  1585. }
  1586. }
  1587. static Mesh CloneMesh(Mesh mesh)
  1588. {
  1589. Mesh clonemesh = new Mesh();
  1590. clonemesh.vertices = mesh.vertices;
  1591. #if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  1592. clonemesh.uv2 = mesh.uv2;
  1593. #else
  1594. clonemesh.uv1 = mesh.uv1;
  1595. clonemesh.uv2 = mesh.uv2;
  1596. #endif
  1597. clonemesh.uv = mesh.uv;
  1598. clonemesh.normals = mesh.normals;
  1599. clonemesh.tangents = mesh.tangents;
  1600. clonemesh.colors = mesh.colors;
  1601. clonemesh.subMeshCount = mesh.subMeshCount;
  1602. for ( int s = 0; s < mesh.subMeshCount; s++ )
  1603. clonemesh.SetTriangles(mesh.GetTriangles(s), s);
  1604. clonemesh.boneWeights = mesh.boneWeights;
  1605. clonemesh.bindposes = mesh.bindposes;
  1606. clonemesh.name = mesh.name + "_copy";
  1607. clonemesh.RecalculateBounds();
  1608. return clonemesh;
  1609. }
  1610. // Animation keyframe stuff
  1611. // Need system to grab state of curve
  1612. void AnimationKeyFrames(MegaShape shape)
  1613. {
  1614. MegaSpline spline = shape.splines[shape.selcurve];
  1615. shape.showanimations = EditorGUILayout.Foldout(shape.showanimations, "Animations");
  1616. if ( shape.showanimations )
  1617. {
  1618. EditorGUILayout.BeginVertical("Box");
  1619. shape.keytime = EditorGUILayout.FloatField("Key Time", shape.keytime);
  1620. if ( shape.keytime < 0.0f )
  1621. shape.keytime = 0.0f;
  1622. spline.splineanim.Enabled = EditorGUILayout.BeginToggleGroup("Enabled", spline.splineanim.Enabled);
  1623. EditorGUILayout.BeginHorizontal();
  1624. if ( GUILayout.Button("Add Key") )
  1625. AddKeyFrame(shape, shape.keytime);
  1626. if ( GUILayout.Button("Clear") )
  1627. ClearAnim(shape);
  1628. EditorGUILayout.EndHorizontal();
  1629. // Need to show each keyframe
  1630. if ( spline.splineanim != null )
  1631. {
  1632. int nk = spline.splineanim.NumKeys();
  1633. float mt = 0.0f;
  1634. for ( int i = 0; i < nk; i++ )
  1635. {
  1636. EditorGUILayout.BeginHorizontal();
  1637. mt = spline.splineanim.GetKeyTime(i);
  1638. EditorGUILayout.LabelField("" + i, GUILayout.MaxWidth(20)); //" + " Time: " + mt);
  1639. float t = EditorGUILayout.FloatField("", mt, GUILayout.MaxWidth(100));
  1640. if ( t != mt )
  1641. spline.splineanim.SetKeyTime(spline, i, t);
  1642. if ( GUILayout.Button("Delete", GUILayout.MaxWidth(50)) )
  1643. spline.splineanim.RemoveKey(i);
  1644. if ( GUILayout.Button("Update", GUILayout.MaxWidth(50)) )
  1645. spline.splineanim.UpdateKey(spline, i);
  1646. if ( GUILayout.Button("Get", GUILayout.MaxWidth(50)) )
  1647. {
  1648. spline.splineanim.GetKey(spline, i);
  1649. EditorUtility.SetDirty(target);
  1650. }
  1651. EditorGUILayout.EndHorizontal();
  1652. }
  1653. if ( spline.splineanim.NumKeys() > 1 )
  1654. {
  1655. shape.MaxTime = mt;
  1656. float at = EditorGUILayout.Slider("T", shape.testtime, 0.0f, mt);
  1657. if ( at != shape.testtime )
  1658. {
  1659. shape.testtime = at;
  1660. if ( !shape.animate )
  1661. {
  1662. for ( int s = 0; s < shape.splines.Count; s++ )
  1663. {
  1664. if ( shape.splines[s].splineanim != null && shape.splines[s].splineanim.Enabled )
  1665. {
  1666. shape.splines[s].splineanim.GetState1(shape.splines[s], at);
  1667. shape.splines[s].CalcLength(); //(10); // could use less here
  1668. }
  1669. }
  1670. }
  1671. }
  1672. }
  1673. }
  1674. EditorGUILayout.EndToggleGroup();
  1675. EditorGUILayout.EndVertical();
  1676. }
  1677. }
  1678. void ClearAnim(MegaShape shape)
  1679. {
  1680. MegaSpline spline = shape.splines[shape.selcurve];
  1681. if ( spline.splineanim != null )
  1682. spline.splineanim.Init(spline);
  1683. }
  1684. void AddKeyFrame(MegaShape shape, float t)
  1685. {
  1686. MegaSpline spline = shape.splines[shape.selcurve];
  1687. spline.splineanim.AddState(spline, t);
  1688. }
  1689. void Export(MegaShape shape)
  1690. {
  1691. string filename = EditorUtility.SaveFilePanel("Export Shape to SVG", "", shape.name, ".svg");
  1692. if ( filename.Length > 0 )
  1693. {
  1694. string data = MegaShapeSVG.Export(shape, (int)xaxis, (int)yaxis, strokewidth, strokecol);
  1695. System.IO.File.WriteAllText(filename, data);
  1696. }
  1697. }
  1698. }