MegaMorphEditor.cs 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System;
  7. public class MegaTargetMesh
  8. {
  9. public string name;
  10. public List<Vector3> verts = new List<Vector3>();
  11. public List<int> faces = new List<int>();
  12. static public List<MegaTargetMesh> LoadTargets(string path, float scale, bool flipzy, bool negx)
  13. {
  14. List<MegaTargetMesh> targets = new List<MegaTargetMesh>();
  15. MegaTargetMesh current = null;
  16. StreamReader stream = File.OpenText(path);
  17. string entireText = stream.ReadToEnd();
  18. stream.Close();
  19. entireText = entireText.Replace("\n", "\r\n");
  20. List<Vector3> verts = new List<Vector3>();
  21. using ( StringReader reader = new StringReader(entireText) )
  22. {
  23. string currentText = reader.ReadLine();
  24. char[] splitIdentifier = { ' ' };
  25. string[] brokenString;
  26. string name = "";
  27. Vector3 p = Vector3.zero;
  28. while ( currentText != null )
  29. {
  30. if ( !currentText.StartsWith("v ") && !currentText.StartsWith("g ") && !currentText.StartsWith("f ") )
  31. {
  32. currentText = reader.ReadLine();
  33. if ( currentText != null )
  34. currentText = currentText.Replace(" ", " ");
  35. }
  36. else
  37. {
  38. currentText = currentText.Trim();
  39. brokenString = currentText.Split(splitIdentifier, 50);
  40. switch ( brokenString[0] )
  41. {
  42. case "f":
  43. if ( verts.Count > 0 )
  44. {
  45. current = new MegaTargetMesh();
  46. current.name = name;
  47. current.verts = new List<Vector3>(verts);
  48. current.faces = new List<int>();
  49. targets.Add(current);
  50. verts.Clear();
  51. }
  52. break;
  53. case "g":
  54. name = brokenString[1];
  55. break;
  56. case "v":
  57. p.x = System.Convert.ToSingle(brokenString[1]) * scale;
  58. if ( negx )
  59. {
  60. p.x = -p.x;
  61. }
  62. if ( flipzy )
  63. {
  64. p.y = System.Convert.ToSingle(brokenString[3]) * scale;
  65. p.z = System.Convert.ToSingle(brokenString[2]) * scale;
  66. }
  67. else
  68. {
  69. p.y = System.Convert.ToSingle(brokenString[2]) * scale;
  70. p.z = System.Convert.ToSingle(brokenString[3]) * scale;
  71. }
  72. verts.Add(p);
  73. break;
  74. }
  75. currentText = reader.ReadLine();
  76. if ( currentText != null )
  77. currentText = currentText.Replace(" ", " ");
  78. }
  79. }
  80. }
  81. return targets;
  82. }
  83. }
  84. // Have a simple text format so can do a simple max exporter and others can do blender scripts etc
  85. [CanEditMultipleObjects, CustomEditor(typeof(MegaMorph))]
  86. public class MegaMorphEditor : Editor
  87. {
  88. static string lastpath = " ";
  89. static public Color ChanCol1 = new Color(0.44f, 0.67f, 1.0f);
  90. static public Color ChanCol2 = new Color(1.0f, 0.67f, 0.44f);
  91. Stack<Color> bcol = new Stack<Color>();
  92. Stack<Color> ccol = new Stack<Color>();
  93. Stack<Color> col = new Stack<Color>();
  94. bool extraparams = false;
  95. private MegaModifier src;
  96. private MegaUndo undoManager;
  97. private void OnEnable()
  98. {
  99. src = target as MegaModifier;
  100. // Instantiate undoManager
  101. undoManager = new MegaUndo(src, src.ModName() + " change");
  102. }
  103. int FindVert(Vector3 vert, List<Vector3> verts, float tolerance)
  104. {
  105. float closest = Vector3.SqrMagnitude(verts[0] - vert);
  106. int find = 0;
  107. for ( int i = 0; i < verts.Count; i++ )
  108. {
  109. float dif = Vector3.SqrMagnitude(verts[i] - vert);
  110. if ( dif < closest )
  111. {
  112. closest = dif;
  113. find = i;
  114. }
  115. }
  116. if ( closest > tolerance ) //0.0001f ) // not exact
  117. return -1;
  118. return find; //0;
  119. }
  120. int FindVert(Vector3 vert, List<Vector3> verts, float tolerance, float scl, bool flipyz, bool negx, int vn)
  121. {
  122. int find = 0;
  123. if ( negx )
  124. vert.x = -vert.x;
  125. if ( flipyz )
  126. {
  127. float z = vert.z;
  128. vert.z = vert.y;
  129. vert.y = z;
  130. }
  131. vert /= scl;
  132. float closest = Vector3.SqrMagnitude(verts[0] - vert);
  133. for ( int i = 0; i < verts.Count; i++ )
  134. {
  135. float dif = Vector3.SqrMagnitude(verts[i] - vert);
  136. if ( dif < closest )
  137. {
  138. closest = dif;
  139. find = i;
  140. }
  141. }
  142. if ( closest > tolerance ) //0.0001f ) // not exact
  143. return -1;
  144. return find; //0;
  145. }
  146. int FindVert(Vector3 vert, List<Vector3> verts, float tolerance, float scl, bool flipyz, bool negx, bool negy, int vn)
  147. {
  148. int find = 0;
  149. //Debug.Log("Scl " + scl);
  150. //Debug.Log("invert " + vert.ToString("0.000"));
  151. if ( negx )
  152. vert.x = -vert.x;
  153. if ( flipyz )
  154. {
  155. float z = vert.z;
  156. vert.z = vert.y;
  157. vert.y = z;
  158. }
  159. if ( negy )
  160. {
  161. vert.y = -vert.y;
  162. }
  163. vert /= scl;
  164. //Debug.Log("vert " + vert.ToString("0.000"));
  165. float closest = Vector3.SqrMagnitude(verts[0] - vert);
  166. for ( int i = 0; i < verts.Count; i++ )
  167. {
  168. float dif = Vector3.SqrMagnitude(verts[i] - vert);
  169. if ( dif < closest )
  170. {
  171. closest = dif;
  172. find = i;
  173. }
  174. }
  175. if ( closest > tolerance ) //0.0001f ) // not exact
  176. return -1;
  177. return find; //0;
  178. }
  179. bool FindMatch(Vector3 vert, Vector3[] verts, float tolerance)
  180. {
  181. float closest = Vector3.SqrMagnitude(verts[0] - vert);
  182. for ( int i = 0; i < verts.Length; i++ )
  183. {
  184. float dif = Vector3.SqrMagnitude(verts[i] - vert);
  185. if ( dif < closest )
  186. closest = dif;
  187. }
  188. if ( closest > tolerance ) //0.0001f ) // not exact
  189. return false;
  190. return true;
  191. }
  192. Vector3 Extents(Vector3[] verts, out Vector3 min, out Vector3 max)
  193. {
  194. Vector3 extent = Vector3.zero;
  195. min = Vector3.zero;
  196. max = Vector3.zero;
  197. if ( verts != null && verts.Length > 0 )
  198. {
  199. min = verts[0];
  200. max = verts[0];
  201. for ( int i = 1; i < verts.Length; i++ )
  202. {
  203. if ( verts[i].x < min.x ) min.x = verts[i].x;
  204. if ( verts[i].y < min.y ) min.y = verts[i].y;
  205. if ( verts[i].z < min.z ) min.z = verts[i].z;
  206. if ( verts[i].x > max.x ) max.x = verts[i].x;
  207. if ( verts[i].y > max.y ) max.y = verts[i].y;
  208. if ( verts[i].z > max.z ) max.z = verts[i].z;
  209. }
  210. extent = max - min;
  211. }
  212. return extent;
  213. }
  214. Vector3 Extents(List<Vector3> verts, out Vector3 min, out Vector3 max)
  215. {
  216. Vector3 extent = Vector3.zero;
  217. min = Vector3.zero;
  218. max = Vector3.zero;
  219. if ( verts != null && verts.Count > 0 )
  220. {
  221. min = verts[0];
  222. max = verts[0];
  223. for ( int i = 1; i < verts.Count; i++ )
  224. {
  225. if ( verts[i].x < min.x ) min.x = verts[i].x;
  226. if ( verts[i].y < min.y ) min.y = verts[i].y;
  227. if ( verts[i].z < min.z ) min.z = verts[i].z;
  228. if ( verts[i].x > max.x ) max.x = verts[i].x;
  229. if ( verts[i].y > max.y ) max.y = verts[i].y;
  230. if ( verts[i].z > max.z ) max.z = verts[i].z;
  231. }
  232. extent = max - min;
  233. }
  234. return extent;
  235. }
  236. // TODO: report error if target vert counts dont match base mapping
  237. bool DoMapping(MegaModifiers mod, MegaMorph morph, MegaTargetMesh tm, int[] mapping, float scale, bool flipyz, bool negx)
  238. {
  239. int step = mod.verts.Length / 10;
  240. int count = 0;
  241. for ( int i = 0; i < mod.verts.Length; i++ )
  242. {
  243. count--;
  244. if ( count < 0 )
  245. {
  246. count = step;
  247. float a = (float)i / (float)mod.verts.Length;
  248. EditorUtility.DisplayProgressBar("Mapping", "Mapping vertex " + i, a);
  249. }
  250. mapping[i] = FindVert(mod.verts[i], tm.verts, morph.tolerance, scale, flipyz, negx, i);
  251. if ( mapping[i] == -1 )
  252. {
  253. // Failed
  254. EditorUtility.ClearProgressBar();
  255. return false;
  256. }
  257. }
  258. EditorUtility.ClearProgressBar();
  259. return true;
  260. }
  261. bool DoMapping(MegaModifiers mod, MegaMorph morph, MegaTargetMesh tm, int[] mapping, float scale, bool flipyz, bool negx, bool negy)
  262. {
  263. int step = mod.verts.Length / 10;
  264. int count = 0;
  265. for ( int i = 0; i < mod.verts.Length; i++ )
  266. {
  267. count--;
  268. if ( count < 0 )
  269. {
  270. count = step;
  271. float a = (float)i / (float)mod.verts.Length;
  272. EditorUtility.DisplayProgressBar("Mapping", "Mapping vertex " + i, a);
  273. }
  274. mapping[i] = FindVert(mod.verts[i], tm.verts, morph.tolerance, scale, flipyz, negx, negy, i);
  275. if ( mapping[i] == -1 )
  276. {
  277. // Failed
  278. EditorUtility.ClearProgressBar();
  279. return false;
  280. }
  281. }
  282. EditorUtility.ClearProgressBar();
  283. return true;
  284. }
  285. bool TryMapping(List<MegaTargetMesh> targets, MegaMorph morph)
  286. {
  287. MegaModifiers mod = morph.GetComponent<MegaModifiers>();
  288. if ( mod == null )
  289. {
  290. //Debug.Log("No modifyobject found");
  291. EditorUtility.DisplayDialog("Missing ModifyObject!", "No ModifyObject script found on the object", "OK");
  292. return false;
  293. }
  294. //if ( morph.oPoints.Length > mod.verts.Length )
  295. //{
  296. // EditorUtility.DisplayDialog("Morph has more points than Mesh!", "The number of base morph points exceeds the number of vertices in the mesh, please check your source mesh for hidden, duplicated or unused points", "OK");
  297. // return false;
  298. //}
  299. int[] mapping = new int[mod.verts.Length];
  300. //for ( int i = 0; i < 18; i++ )
  301. //{
  302. // Debug.Log("v[" + i + "] " + mod.verts[i].ToString("0.00000"));
  303. //}
  304. //for ( int i = 0; i < 18; i++ )
  305. //{
  306. // Debug.Log("t[" + i + "] " + targets[0].verts[i].ToString("0.00000"));
  307. //}
  308. //Debug.Log("Targets " + targets.Count);
  309. for ( int t = 0; t < targets.Count; t++ )
  310. {
  311. MegaTargetMesh tm = targets[t];
  312. //Debug.Log("tm verts " + tm.verts.Count);
  313. // Get extents for mod verts and for imported meshes, if not the same then scale
  314. Vector3 min1,max1;
  315. Vector3 min2,max2;
  316. Vector3 ex1 = Extents(mod.verts, out min1, out max1);
  317. Vector3 ex2 = Extents(tm.verts, out min2, out max2);
  318. //Debug.Log("min1 " + min1.ToString("0.000"));
  319. //Debug.Log("max1 " + max1.ToString("0.000"));
  320. //Debug.Log("min2 " + min2.ToString("0.000"));
  321. //Debug.Log("max2 " + max2.ToString("0.000"));
  322. // need min max on all axis so we can produce an offset to add
  323. float d1 = ex1.x;
  324. float d2 = ex2.x;
  325. float scl = d1 / d2; //d2 / d1;
  326. bool flipyz = false;
  327. bool negx = false;
  328. //Vector3 offset = (min2 * scl) - min1;
  329. //Debug.Log("offset " + offset.ToString("0.0000"));
  330. //Debug.Log("scl " + scl);
  331. // So try to match first vert using autoscale and no flip
  332. bool mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx);
  333. if ( !mapped )
  334. {
  335. flipyz = true;
  336. mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx);
  337. if ( !mapped ) //DoMapping(mod, morph, tm, mapping, scl, flipyz, negx) )
  338. {
  339. flipyz = false;
  340. negx = true;
  341. mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx);
  342. if ( !mapped )
  343. {
  344. flipyz = true;
  345. mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx);
  346. }
  347. }
  348. }
  349. if ( mapped )
  350. {
  351. morph.importScale = scl;
  352. morph.flipyz = flipyz;
  353. morph.negx = negx;
  354. morph.mapping = mapping;
  355. // if mapping was ok set opoints
  356. morph.oPoints = tm.verts.ToArray();
  357. for ( int i = 0; i < morph.oPoints.Length; i++ )
  358. {
  359. Vector3 p = morph.oPoints[i];
  360. if ( negx )
  361. p.x = -p.x;
  362. if ( flipyz )
  363. {
  364. float z = p.z;
  365. p.z = p.y;
  366. p.y = z;
  367. }
  368. morph.oPoints[i] = p * morph.importScale;
  369. }
  370. return true;
  371. }
  372. else
  373. {
  374. //morph.oPoints = tm.verts.ToArray();
  375. }
  376. }
  377. return false;
  378. }
  379. void LoadBase(MegaMorph morph)
  380. {
  381. string filename = EditorUtility.OpenFilePanel("Morph Base", lastpath, "obj");
  382. if ( filename == null || filename.Length < 1 )
  383. return;
  384. lastpath = filename;
  385. List<MegaTargetMesh> targets = MegaTargetMesh.LoadTargets(filename, 1.0f, false, false); //morph.importScale, morph.flipyz, morph.negx);
  386. // only use first
  387. if ( targets != null && targets.Count > 0 )
  388. {
  389. if ( !TryMapping(targets, morph) )
  390. {
  391. // No match found
  392. EditorUtility.DisplayDialog("Mapping Failed!", "Mapping of " + System.IO.Path.GetFileNameWithoutExtension(filename) + " failed!", "OK");
  393. EditorUtility.ClearProgressBar();
  394. return;
  395. }
  396. }
  397. }
  398. // remove mPoints from channel, just use target list, if targets.Count == 1 then use delta
  399. // first target goes into mPoints
  400. // guess we should update any targets who we have already, ie use name
  401. void LoadTargets(MegaMorphChan channel)
  402. {
  403. MegaMorph mr = (MegaMorph)target;
  404. string filename = EditorUtility.OpenFilePanel("Morph Targets", lastpath, "obj");
  405. if ( filename == null || filename.Length < 1 )
  406. return;
  407. lastpath = filename;
  408. List<MegaTargetMesh> targets = MegaTargetMesh.LoadTargets(filename, mr.importScale, mr.flipyz, mr.negx);
  409. if ( targets != null )
  410. {
  411. if ( channel.mName == "Empty" )
  412. channel.mName = System.IO.Path.GetFileNameWithoutExtension(filename);
  413. // Now need to check that each target has correct num verts and face list matches
  414. for ( int i = 0; i < targets.Count; i++ )
  415. {
  416. MegaTargetMesh tm = targets[i];
  417. if ( tm.verts.Count != mr.oPoints.Length )
  418. EditorUtility.DisplayDialog("Target Vertex count mismatch!", "Target " + tm.name + " has wrong number of verts", "OK");
  419. else
  420. {
  421. // See if we have a target with this name, if so update that
  422. MegaMorphTarget mt = channel.GetTarget(tm.name);
  423. if ( mt == null ) // add a new target
  424. {
  425. mt = new MegaMorphTarget();
  426. mt.name = tm.name;
  427. channel.mTargetCache.Add(mt);
  428. }
  429. mt.points = tm.verts.ToArray();
  430. //for ( int v = 0; v < mt.points.Length; v++ )
  431. //{
  432. //if ( mt.points[v] == mr.oPoints[v] )
  433. //Debug.Log("Vert " + v + " isnt morphed");
  434. //}
  435. }
  436. }
  437. channel.ResetPercent();
  438. channel.Rebuild(mr); // rebuild delta for 1st channel
  439. }
  440. mr.BuildCompress();
  441. }
  442. void LoadTarget(MegaMorphTarget mt)
  443. {
  444. MegaMorph mr = (MegaMorph)target;
  445. string filename = EditorUtility.OpenFilePanel("Morph Target", lastpath, "obj");
  446. if ( filename == null || filename.Length < 1 )
  447. return;
  448. lastpath = filename;
  449. List<MegaTargetMesh> targets = MegaTargetMesh.LoadTargets(filename, mr.importScale, mr.flipyz, mr.negx);
  450. if ( targets != null && targets.Count > 0 )
  451. {
  452. MegaTargetMesh tm = targets[0];
  453. if ( tm.verts.Count != mr.oPoints.Length )
  454. {
  455. EditorUtility.DisplayDialog("Target Vertex count mismatch!", "Target " + tm.name + " has wrong number of verts", "OK");
  456. }
  457. else
  458. {
  459. mt.points = tm.verts.ToArray();
  460. mt.name = tm.name;
  461. }
  462. }
  463. }
  464. void SwapTargets(MegaMorphChan chan, int t1, int t2)
  465. {
  466. if ( t1 >= 0 && t1 < chan.mTargetCache.Count && t2 >= 0 && t2 < chan.mTargetCache.Count && t1 != t2 )
  467. {
  468. MegaMorphTarget mt1 = chan.mTargetCache[t1];
  469. MegaMorphTarget mt2 = chan.mTargetCache[t2];
  470. float per = mt1.percent;
  471. mt1.percent = mt2.percent;
  472. mt2.percent = per;
  473. chan.mTargetCache.RemoveAt(t1);
  474. chan.mTargetCache.Insert(t2, mt1);
  475. EditorUtility.SetDirty(target);
  476. }
  477. }
  478. // Still need to be able to add in unity meshes
  479. void DisplayTarget(MegaMorph morph, MegaMorphChan channel, MegaMorphTarget mt, int num)
  480. {
  481. PushCols();
  482. EditorGUI.indentLevel = 1;
  483. mt.name = EditorGUILayout.TextField("Name", mt.name);
  484. mt.percent = EditorGUILayout.Slider("Percent", mt.percent, 0.0f, 100.0f);
  485. EditorGUILayout.BeginHorizontal();
  486. if ( mt.points == null || mt.points.Length != morph.oPoints.Length)
  487. GUI.backgroundColor = new Color(0.5f, 0.5f, 0.5f);
  488. else
  489. GUI.backgroundColor = new Color(0.0f, 1.0f, 0.0f);
  490. if ( GUILayout.Button("Load") )
  491. {
  492. LoadTarget(mt);
  493. }
  494. GUI.backgroundColor = new Color(1.0f, 0.5f, 0.5f);
  495. if ( GUILayout.Button("Delete") )
  496. {
  497. MegaMorphTarget mt0 = channel.mTargetCache[0];
  498. channel.mTargetCache.Remove(mt);
  499. channel.ResetPercent();
  500. if ( channel.mTargetCache.Count > 0 && channel.mTargetCache[0] != mt0 )
  501. channel.Rebuild(morph);
  502. }
  503. GUI.backgroundColor = new Color(1.0f, 1.0f, 0.5f);
  504. if ( GUILayout.Button("Up") )
  505. {
  506. if ( num > 0 )
  507. {
  508. SwapTargets(channel, num, num - 1);
  509. if ( num == 1 )
  510. channel.Rebuild(morph);
  511. }
  512. }
  513. GUI.backgroundColor = new Color(0.5f, 1.0f, 1.0f);
  514. if ( GUILayout.Button("Dn") )
  515. {
  516. if ( num < channel.mTargetCache.Count - 1 )
  517. {
  518. SwapTargets(channel, num, num + 1);
  519. if ( num == 0 )
  520. channel.Rebuild(morph);
  521. }
  522. }
  523. EditorGUILayout.EndHorizontal();
  524. EditorGUI.indentLevel = 0;
  525. PopCols();
  526. }
  527. void PushCols()
  528. {
  529. bcol.Push(GUI.backgroundColor);
  530. ccol.Push(GUI.contentColor);
  531. col.Push(GUI.color);
  532. }
  533. void PopCols()
  534. {
  535. GUI.backgroundColor = bcol.Pop();
  536. GUI.contentColor = ccol.Pop();
  537. GUI.color = col.Pop();
  538. }
  539. void DisplayChannel(MegaMorph morph, MegaMorphChan channel, int num)
  540. {
  541. if ( GUILayout.Button(num + " - " + channel.mName) )
  542. channel.showparams = !channel.showparams;
  543. float min = 0.0f;
  544. float max = 100.0f;
  545. if ( morph.UseLimit )
  546. {
  547. min = morph.Min;
  548. max = morph.Max;
  549. }
  550. GUI.backgroundColor = new Color(1, 1, 1);
  551. if ( channel.showparams )
  552. {
  553. channel.mName = EditorGUILayout.TextField("Name", channel.mName);
  554. if ( channel.mTargetCache != null && channel.mTargetCache.Count > 0 )
  555. {
  556. channel.mActiveOverride = EditorGUILayout.Toggle("Active", channel.mActiveOverride);
  557. if ( morph.UseLimit )
  558. {
  559. channel.Percent = EditorGUILayout.Slider("Percent", channel.Percent, min, max); //0.0f, 100.0f);
  560. }
  561. else
  562. {
  563. if ( channel.mUseLimit )
  564. channel.Percent = EditorGUILayout.Slider("Percent", channel.Percent, channel.mSpinmin, channel.mSpinmax);
  565. else
  566. channel.Percent = EditorGUILayout.Slider("Percent", channel.Percent, 0.0f, 100.0f);
  567. }
  568. channel.mCurvature = EditorGUILayout.FloatField("Tension", channel.mCurvature);
  569. channel.weight = EditorGUILayout.Slider("Weight", channel.weight, 0.0f, 1.0f);
  570. }
  571. channel.mUseLimit = EditorGUILayout.Toggle("Use Limit", channel.mUseLimit);
  572. if ( channel.mUseLimit )
  573. {
  574. channel.mSpinmin = EditorGUILayout.FloatField("Min", channel.mSpinmin);
  575. channel.mSpinmax = EditorGUILayout.FloatField("Max", channel.mSpinmax);
  576. }
  577. EditorGUILayout.BeginHorizontal();
  578. PushCols();
  579. GUI.backgroundColor = new Color(0.5f, 0.5f, 0.5f);
  580. if ( GUILayout.Button("Load Targets") )
  581. {
  582. if ( channel.mTargetCache == null )
  583. channel.mTargetCache = new List<MegaMorphTarget>();
  584. LoadTargets(channel);
  585. }
  586. GUI.backgroundColor = new Color(0.5f, 1.0f, 0.5f);
  587. if ( GUILayout.Button("Add Target") )
  588. {
  589. if ( channel.mTargetCache == null )
  590. channel.mTargetCache = new List<MegaMorphTarget>();
  591. MegaMorphTarget mt = new MegaMorphTarget();
  592. channel.mTargetCache.Add(mt);
  593. channel.ResetPercent();
  594. }
  595. GUI.backgroundColor = new Color(1.5f, 0.5f, 0.5f);
  596. if ( GUILayout.Button("Delete Channel") )
  597. morph.chanBank.Remove(channel);
  598. EditorGUILayout.EndHorizontal();
  599. PopCols();
  600. if ( channel.mTargetCache != null && channel.mTargetCache.Count > 0 )
  601. {
  602. channel.showtargets = EditorGUILayout.Foldout(channel.showtargets, "Targets");
  603. if ( channel.showtargets )
  604. {
  605. if ( channel.mTargetCache != null )
  606. {
  607. for ( int i = 0; i < channel.mTargetCache.Count; i++ )
  608. DisplayTarget(morph, channel, channel.mTargetCache[i], i);
  609. }
  610. }
  611. }
  612. }
  613. else
  614. {
  615. if ( channel.mActiveOverride && channel.mTargetCache != null && channel.mTargetCache.Count > 0 )
  616. {
  617. //channel.Percent = EditorGUILayout.Slider("Percent", channel.Percent, 0.0f, 100.0f);
  618. if ( morph.UseLimit )
  619. {
  620. channel.Percent = EditorGUILayout.Slider("Percent", channel.Percent, min, max); //0.0f, 100.0f);
  621. }
  622. else
  623. {
  624. if ( channel.mUseLimit )
  625. channel.Percent = EditorGUILayout.Slider("Percent", channel.Percent, channel.mSpinmin, channel.mSpinmax);
  626. else
  627. channel.Percent = EditorGUILayout.Slider("Percent", channel.Percent, 0.0f, 100.0f);
  628. }
  629. }
  630. }
  631. }
  632. void DisplayChannelLim(MegaMorph morph, MegaMorphChan channel, int num)
  633. {
  634. float min = 0.0f;
  635. float max = 100.0f;
  636. if ( morph.UseLimit )
  637. {
  638. min = morph.Min;
  639. max = morph.Max;
  640. }
  641. GUI.backgroundColor = new Color(1, 1, 1);
  642. if ( channel.mActiveOverride && channel.mTargetCache != null && channel.mTargetCache.Count > 0 )
  643. {
  644. if ( morph.UseLimit )
  645. {
  646. channel.Percent = EditorGUILayout.Slider(channel.mName, channel.Percent, min, max); //0.0f, 100.0f);
  647. }
  648. else
  649. {
  650. if ( channel.mUseLimit )
  651. channel.Percent = EditorGUILayout.Slider(channel.mName, channel.Percent, channel.mSpinmin, channel.mSpinmax);
  652. else
  653. channel.Percent = EditorGUILayout.Slider(channel.mName, channel.Percent, 0.0f, 100.0f);
  654. }
  655. }
  656. }
  657. bool showmodparams = false;
  658. bool showimport = false;
  659. bool showchannels = true;
  660. void ImportParams(MegaMorph morph)
  661. {
  662. showimport = EditorGUILayout.Foldout(showimport, "Import Params");
  663. if ( showimport )
  664. {
  665. morph.importScale = EditorGUILayout.FloatField("Import Scale", morph.importScale);
  666. morph.flipyz = EditorGUILayout.Toggle("FlipYZ", morph.flipyz);
  667. morph.negx = EditorGUILayout.Toggle("Negate X", morph.negx);
  668. morph.tolerance = EditorGUILayout.FloatField("Tolerance", morph.tolerance);
  669. }
  670. }
  671. bool showadvanced = false;
  672. public override void OnInspectorGUI()
  673. {
  674. MegaMorph morph = (MegaMorph)target;
  675. if ( morph.useUndo )
  676. undoManager.CheckUndo();
  677. PushCols();
  678. if ( GUILayout.Button("Import Morph File") )
  679. {
  680. LoadMorph();
  681. EditorUtility.SetDirty(target);
  682. }
  683. // Basic mod stuff
  684. showmodparams = EditorGUILayout.Foldout(showmodparams, "Modifier Common Params");
  685. if ( showmodparams )
  686. {
  687. morph.Label = EditorGUILayout.TextField("Label", morph.Label);
  688. morph.MaxLOD = EditorGUILayout.IntField("MaxLOD", morph.MaxLOD);
  689. morph.ModEnabled = EditorGUILayout.Toggle("Mod Enabled", morph.ModEnabled);
  690. morph.useUndo = EditorGUILayout.Toggle("Use Undo", morph.useUndo);
  691. morph.DisplayGizmo = EditorGUILayout.Toggle("Display Gizmo", morph.DisplayGizmo);
  692. morph.Order = EditorGUILayout.IntField("Order", morph.Order);
  693. morph.gizCol1 = EditorGUILayout.ColorField("Giz Col 1", morph.gizCol1);
  694. morph.gizCol2 = EditorGUILayout.ColorField("Giz Col 2", morph.gizCol2);
  695. }
  696. // Advanced
  697. showadvanced = EditorGUILayout.Foldout(showadvanced, "Advanced Params");
  698. if ( showadvanced )
  699. {
  700. if ( morph.oPoints != null )
  701. {
  702. morph.showmapping = EditorGUILayout.BeginToggleGroup("Show Mapping", morph.showmapping);
  703. morph.mapStart = EditorGUILayout.IntSlider("StartVert", morph.mapStart, 0, morph.oPoints.Length);
  704. morph.mapEnd = EditorGUILayout.IntSlider("endVert", morph.mapEnd, 0, morph.oPoints.Length);
  705. morph.mappingSize = EditorGUILayout.Slider("Size", morph.mappingSize, 0.0005f, 0.1f);
  706. EditorGUILayout.EndToggleGroup();
  707. }
  708. morph.tolerance = EditorGUILayout.Slider("Tolerance", morph.tolerance, 0.0f, 0.01f);
  709. }
  710. morph.UseLimit = EditorGUILayout.BeginToggleGroup("Use Limits", morph.UseLimit);
  711. morph.Min = EditorGUILayout.FloatField("Min", morph.Min);
  712. morph.Max = EditorGUILayout.FloatField("Max", morph.Max);
  713. EditorGUILayout.EndToggleGroup();
  714. morph.animate = EditorGUILayout.Toggle("Animate", morph.animate);
  715. if ( morph.animate )
  716. {
  717. morph.animtime = EditorGUILayout.FloatField("AnimTime", morph.animtime);
  718. morph.looptime = EditorGUILayout.FloatField("LoopTime", morph.looptime);
  719. morph.speed = EditorGUILayout.FloatField("Speed", morph.speed);
  720. morph.repeatMode = (MegaRepeatMode)EditorGUILayout.EnumPopup("RepeatMode", morph.repeatMode);
  721. }
  722. //ImportParams(morph);
  723. EditorGUILayout.BeginHorizontal();
  724. PushCols();
  725. if ( morph.mapping == null || morph.mapping.Length == 0 )
  726. GUI.backgroundColor = Color.red;
  727. else
  728. GUI.backgroundColor = Color.green;
  729. if ( GUILayout.Button("Load Mapping") )
  730. LoadBase(morph);
  731. PopCols();
  732. if ( GUILayout.Button("Add Channel") )
  733. {
  734. if ( morph.chanBank == null )
  735. morph.chanBank = new List<MegaMorphChan>();
  736. MegaMorphChan nc = new MegaMorphChan();
  737. nc.mName = "Empty";
  738. morph.chanBank.Add(nc);
  739. //ChannelMapping(morph, nc); // Create 1 to 1 mapping
  740. }
  741. EditorGUILayout.EndHorizontal();
  742. string bname = "Hide Channels";
  743. if ( !showchannels )
  744. bname = "Show Channels";
  745. if ( GUILayout.Button(bname) )
  746. showchannels = !showchannels;
  747. morph.limitchandisplay = EditorGUILayout.Toggle("Compact Display", morph.limitchandisplay);
  748. if ( showchannels && morph.chanBank != null )
  749. {
  750. if ( morph.limitchandisplay )
  751. {
  752. morph.startchannel = EditorGUILayout.IntField("Start", morph.startchannel);
  753. morph.displaychans = EditorGUILayout.IntField("Display", morph.displaychans);
  754. if ( morph.displaychans < 0 )
  755. morph.displaychans = 0;
  756. if ( morph.startchannel >= morph.chanBank.Count - 1 )
  757. morph.startchannel = morph.chanBank.Count - 1;
  758. if ( morph.startchannel < 0 )
  759. morph.startchannel = 0;
  760. int end = morph.startchannel + morph.displaychans;
  761. if ( end >= morph.chanBank.Count )
  762. end = morph.chanBank.Count;
  763. for ( int i = morph.startchannel; i < end; i++ )
  764. {
  765. PushCols();
  766. if ( (i & 1) == 0 )
  767. GUI.backgroundColor = ChanCol1;
  768. else
  769. GUI.backgroundColor = ChanCol2;
  770. DisplayChannelLim(morph, morph.chanBank[i], i);
  771. PopCols();
  772. }
  773. }
  774. else
  775. {
  776. for ( int i = 0; i < morph.chanBank.Count; i++ )
  777. {
  778. PushCols();
  779. if ( (i & 1) == 0 )
  780. GUI.backgroundColor = ChanCol1;
  781. else
  782. GUI.backgroundColor = ChanCol2;
  783. DisplayChannel(morph, morph.chanBank[i], i);
  784. PopCols();
  785. }
  786. }
  787. }
  788. extraparams = EditorGUILayout.Foldout(extraparams, "Extra Params");
  789. if ( extraparams )
  790. {
  791. ChanCol1 = EditorGUILayout.ColorField("Channel Col 1", ChanCol1);
  792. ChanCol2 = EditorGUILayout.ColorField("Channel Col 2", ChanCol2);
  793. //int mem = CalcMemoryUsage(morph) / 1024;
  794. if ( morph.compressedmem == 0 )
  795. {
  796. morph.memuse = CalcMemoryUsage(morph);
  797. morph.Compress();
  798. }
  799. EditorGUILayout.LabelField("Memory: ", (morph.memuse / 1024) + "KB");
  800. EditorGUILayout.LabelField("Channel Compressed: ", (morph.compressedmem / 1024) + "KB");
  801. }
  802. PopCols();
  803. if ( GUI.changed )
  804. EditorUtility.SetDirty(target);
  805. if ( morph.useUndo )
  806. undoManager.CheckDirty();
  807. }
  808. int MorphedVerts(MegaMorph mr, MegaMorphChan channel)
  809. {
  810. int count = 0;
  811. for ( int v = 0; v < mr.oPoints.Length; v++ )
  812. {
  813. Vector3 p = mr.oPoints[v];
  814. bool morphed = false;
  815. for ( int i = 0; i < channel.mTargetCache.Count; i++ )
  816. {
  817. MegaMorphTarget mt = channel.mTargetCache[i];
  818. if ( !p.Equals(mt.points[v]) )
  819. {
  820. morphed = true;
  821. break;
  822. }
  823. }
  824. if ( morphed )
  825. count++;
  826. }
  827. return count;
  828. }
  829. void ChannelMapping(MegaMorph mr, MegaMorphChan mc)
  830. {
  831. mc.mapping = new int[mr.oPoints.Length];
  832. for ( int i = 0; i < mr.oPoints.Length; i++ )
  833. {
  834. mc.mapping[i] = i;
  835. }
  836. }
  837. void CompressChannel(MegaMorph mr, MegaMorphChan mc)
  838. {
  839. // for now change system to work off mapping, just have 1 to 1 mapping to test its working
  840. mc.mapping = new int[mr.oPoints.Length];
  841. for ( int i = 0; i < mr.oPoints.Length; i++ )
  842. {
  843. mc.mapping[i] = i;
  844. }
  845. #if false
  846. BitArray modded = new BitArray(mr.oPoints.Length);
  847. modded.SetAll(false);
  848. for ( int t = 0; t < mc.mTargetCache.Count; t++ )
  849. {
  850. MegaMorphTarget mt = mc.mTargetCache[t];
  851. for ( int i = 0; i < mr.oPoints.Length; i++ )
  852. {
  853. if ( mt.points[i] != mr.oPoints[i] ) // Have a threshold for this
  854. {
  855. modded[i] = true;
  856. break;
  857. }
  858. }
  859. }
  860. List<int> points = new List<int>();
  861. for ( int i = 0; i < modded.Count; i++ )
  862. {
  863. if ( modded[i] )
  864. points.Add(i);
  865. }
  866. // points now holds indexes of morphed verts for the channel, so now need to collapse points
  867. Vector3[] pts = new Vector3[points.Count];
  868. for ( int t = 0; t < mc.mTargetCache.Count; t++ )
  869. {
  870. MegaMorphTarget mt = mc.mTargetCache[t];
  871. for ( int i = 0; i < points.Count; i++ )
  872. {
  873. pts[i] = mt.points[points[i]];
  874. }
  875. pts.CopyTo(mt.points, 0);
  876. }
  877. // If one target deal with deltas
  878. #endif
  879. }
  880. int CalcCompressedMemory(MegaMorph mr)
  881. {
  882. int mem = 0;
  883. for ( int i = 0; i < mr.chanBank.Count; i++ )
  884. {
  885. MegaMorphChan mc = mr.chanBank[i];
  886. //mem += MorphedVerts(mr, mc) * 12 * mc.mTargetCache.Count;
  887. int mv = MorphedVerts(mr, mc);
  888. int m = mv * 12 * mc.mTargetCache.Count;
  889. mem += m;
  890. EditorGUILayout.LabelField(mc.mName, "Verts: " + mv + " mem: " + m);
  891. }
  892. EditorGUILayout.LabelField("Total: ", (mem / 1024) + "KB");
  893. return mem;
  894. }
  895. int CalcMemoryUsage(MegaMorph mr)
  896. {
  897. int mem = 0;
  898. for ( int i = 0; i < mr.chanBank.Count; i++ )
  899. {
  900. MegaMorphChan mc = mr.chanBank[i];
  901. mem += mc.mTargetCache.Count * 12 * mr.oPoints.Length;
  902. }
  903. return mem;
  904. }
  905. //public delegate bool ParseBinCallbackType(BinaryReader br, string id);
  906. //public delegate void ParseClassCallbackType(string classname, BinaryReader br);
  907. public void ParseFile(String assetpath, ParseClassCallbackType cb)
  908. {
  909. FileStream fs = new FileStream(assetpath, FileMode.Open, FileAccess.Read, System.IO.FileShare.Read);
  910. BinaryReader br = new BinaryReader(fs);
  911. bool processing = true;
  912. while ( processing )
  913. {
  914. string classname = MegaParse.ReadString(br);
  915. if ( classname == "Done" )
  916. break;
  917. int chunkoff = br.ReadInt32();
  918. long fpos = fs.Position;
  919. cb(classname, br);
  920. fs.Position = fpos + chunkoff;
  921. }
  922. br.Close();
  923. }
  924. #if false
  925. static public void Parse(BinaryReader br, ParseBinCallbackType cb)
  926. {
  927. bool readchunk = true;
  928. while ( readchunk )
  929. {
  930. string id = MegaUtils.ReadString(br);
  931. if ( id == "eoc" )
  932. break;
  933. int skip = br.ReadInt32();
  934. long fpos = br.BaseStream.Position;
  935. if ( !cb(br, id) )
  936. {
  937. Debug.Log("Error Loading chunk id " + id);
  938. readchunk = false; // done
  939. break;
  940. }
  941. br.BaseStream.Position = fpos + skip;
  942. }
  943. }
  944. #endif
  945. void MorphCallback(string classname, BinaryReader br)
  946. {
  947. switch ( classname )
  948. {
  949. case "Morph": LoadMorph(br); break;
  950. }
  951. }
  952. int startchan = 0;
  953. void LoadMorph()
  954. {
  955. MegaMorph mr = (MegaMorph)target;
  956. //Modifiers mod = mr.GetComponent<Modifiers>(); // Do this at start and store
  957. string filename = EditorUtility.OpenFilePanel("Morph File", lastpath, "mor");
  958. if ( filename == null || filename.Length < 1 )
  959. return;
  960. lastpath = filename;
  961. startchan = 0;
  962. bool opt = true;
  963. if ( mr.chanBank != null && mr.chanBank.Count > 0 )
  964. opt = EditorUtility.DisplayDialog("Channel Import Option", "Channels already present, do you want to 'Add' or 'Replace' channels in this file?", "Add", "Replace");
  965. // Clear what we have
  966. if ( mr.chanBank != null )
  967. {
  968. if ( opt )
  969. startchan = mr.chanBank.Count;
  970. else
  971. mr.chanBank.Clear();
  972. }
  973. ParseFile(filename, MorphCallback);
  974. mr.animate = false;
  975. float looptime = 0.0f;
  976. // Set Looptime and animate if there is an anim
  977. for ( int i = 0; i < mr.chanBank.Count; i++ )
  978. {
  979. MegaMorphChan mc = mr.chanBank[i];
  980. if ( mc.control != null ) // ISSUE: On 2nd load we suddenly have controls for no reason
  981. {
  982. mr.animate = true;
  983. if ( mc.control.Times != null && mc.control.Times.Length > 0 )
  984. {
  985. float t = mc.control.Times[mc.control.Times.Length - 1];
  986. if ( t > looptime )
  987. looptime = t;
  988. }
  989. }
  990. }
  991. if ( mr.animate )
  992. {
  993. mr.looptime = looptime;
  994. }
  995. mr.compressedmem = 0;
  996. mr.BuildCompress();
  997. }
  998. public void LoadMorph(BinaryReader br)
  999. {
  1000. //Parse(br, ParseMorph);
  1001. MegaParse.Parse(br, ParseMorph);
  1002. }
  1003. bool AnimCallback(BinaryReader br, string id)
  1004. {
  1005. MegaMorph mr = (MegaMorph)target;
  1006. switch ( id )
  1007. {
  1008. case "Chan":
  1009. int cn = br.ReadInt32() + startchan;
  1010. if ( cn < mr.chanBank.Count )
  1011. currentChan = mr.chanBank[cn];
  1012. else
  1013. {
  1014. Debug.LogWarning("Morph File has animation data for a missing target, check your original file and delete unused channels");
  1015. currentChan = null;
  1016. }
  1017. break;
  1018. case "Anim":
  1019. MegaBezFloatKeyControl con = LoadAnim(br);
  1020. if ( currentChan != null )
  1021. {
  1022. currentChan.control = con;
  1023. mr.animtype = MegaMorphAnimType.Bezier;
  1024. }
  1025. break;
  1026. case "MayaAnim":
  1027. MegaBezFloatKeyControl hcon = LoadMayaAnim(br);
  1028. if ( currentChan != null )
  1029. {
  1030. currentChan.control = hcon;
  1031. //currentChan.control = currentChan.hcontrol;
  1032. mr.animtype = MegaMorphAnimType.Hermite;
  1033. }
  1034. break;
  1035. default: return false;
  1036. }
  1037. return true;
  1038. }
  1039. void LoadAnimation(MegaMorph mr, BinaryReader br)
  1040. {
  1041. //Parse(br, AnimCallback);
  1042. MegaParse.Parse(br, AnimCallback);
  1043. }
  1044. // Fbx could have been exported any which way so still need to do try all mappings to find correct
  1045. public bool ParseMorph(BinaryReader br, string id)
  1046. {
  1047. MegaMorph mr = (MegaMorph)target;
  1048. //Debug.Log("ParseMorph " + id);
  1049. switch ( id )
  1050. {
  1051. case "Max": mr.Max = br.ReadSingle(); break;
  1052. case "Min": mr.Min = br.ReadSingle(); break;
  1053. case "UseLim": mr.UseLimit = (br.ReadInt32() == 1); break;
  1054. case "StartPoints": // Mapping
  1055. MegaTargetMesh tm = new MegaTargetMesh();
  1056. tm.verts = MegaParse.ReadP3l(br); // make a vector
  1057. //Debug.Log("num " + tm.verts.Count);
  1058. if ( !TryMapping1(tm, mr) )
  1059. {
  1060. EditorUtility.DisplayDialog("Mapping Failed!", "Mapping failed! Please check the Morph page on the MegaFiers website for reasons for this", "OK");
  1061. EditorUtility.ClearProgressBar();
  1062. return false;
  1063. }
  1064. //Debug.Log("StartPoints " + tm.verts.Count);
  1065. break;
  1066. case "Channel":
  1067. MegaMorphChan chan = LoadChan(br);
  1068. if ( chan != null )
  1069. mr.chanBank.Add(chan);
  1070. break;
  1071. case "Animation":
  1072. LoadAnimation(mr, br);
  1073. break;
  1074. default: return false;
  1075. }
  1076. return true;
  1077. }
  1078. MegaMorphChan currentChan;
  1079. public MegaMorphChan LoadChan(BinaryReader br)
  1080. {
  1081. MegaMorphChan chan = new MegaMorphChan();
  1082. //Debug.Log("Load Chan");
  1083. chan.control = null;
  1084. chan.showparams = false;
  1085. chan.mTargetCache = new List<MegaMorphTarget>();
  1086. currentChan = chan;
  1087. //Parse(br, ParseChan);
  1088. MegaParse.Parse(br, ParseChan);
  1089. for ( int i = 0; i < chan.mTargetCache.Count; i++ )
  1090. {
  1091. if ( chan.mTargetCache[i].points == null || chan.mTargetCache[i].points.Length == 0 )
  1092. return null;
  1093. }
  1094. MegaMorph mr = (MegaMorph)target;
  1095. chan.Rebuild(mr);
  1096. return chan;
  1097. }
  1098. public static MegaBezFloatKeyControl LoadAnim(BinaryReader br)
  1099. {
  1100. //MegaBezFloatKeyControl con = new MegaBezFloatKeyControl();
  1101. //Parse(br, con.Parse);
  1102. //MegaParse.Parse(br, con.Parse);
  1103. //return con;
  1104. return MegaParseBezFloatControl.LoadBezFloatKeyControl(br);
  1105. }
  1106. public static MegaBezFloatKeyControl LoadMayaAnim(BinaryReader br)
  1107. {
  1108. //MegaBezFloatKeyControl con = new MegaBezFloatKeyControl();
  1109. //Parse(br, con.Parse);
  1110. //MegaParse.Parse(br, con.Parse);
  1111. //return con;
  1112. return MegaParseBezFloatControl.LoadBezFloatKeyControl(br);
  1113. }
  1114. public bool ParseChan(BinaryReader br, string id)
  1115. {
  1116. //Debug.Log("ParseChan " + id);
  1117. switch ( id )
  1118. {
  1119. case "Target": currentChan.mTargetCache.Add(LoadTarget(br)); break;
  1120. case "Name": currentChan.mName = MegaParse.ReadString(br); break;
  1121. case "Percent": currentChan.Percent = br.ReadSingle(); break;
  1122. case "SpinMax": currentChan.mSpinmax = br.ReadSingle(); break;
  1123. case "SpinMin": currentChan.mSpinmin = br.ReadSingle(); break;
  1124. case "UseLim": currentChan.mUseLimit = (br.ReadInt32() == 1); break;
  1125. case "Override": currentChan.mActiveOverride = (br.ReadInt32() == 1); break;
  1126. case "Curve": currentChan.mCurvature = br.ReadSingle(); break;
  1127. //case "Anim": currentChan.control = LoadAnim(br); break;
  1128. }
  1129. return true;
  1130. }
  1131. MegaMorphTarget currentTarget;
  1132. void ConvertPoints(Vector3[] verts)
  1133. {
  1134. MegaMorph mr = (MegaMorph)target;
  1135. for ( int i = 0; i < verts.Length; i++ )
  1136. {
  1137. Vector3 p = verts[i] * mr.importScale;
  1138. if ( mr.negx )
  1139. {
  1140. p.x = -p.x;
  1141. }
  1142. if ( mr.flipyz )
  1143. {
  1144. float y = p.y;
  1145. p.y = p.z;
  1146. p.z = y;
  1147. }
  1148. verts[i] = p;
  1149. }
  1150. }
  1151. public bool ParseTarget(BinaryReader br, string id)
  1152. {
  1153. //Debug.Log("ParseTarget " + id);
  1154. switch ( id )
  1155. {
  1156. case "Name": currentTarget.name = MegaParse.ReadString(br); break;
  1157. case "Percent": currentTarget.percent = br.ReadSingle(); break;
  1158. case "TPoints": currentTarget.points = MegaParse.ReadP3v(br); ConvertPoints(currentTarget.points); break;
  1159. case "MoPoints":
  1160. Debug.Log("Got morpho points");
  1161. break;
  1162. }
  1163. return true;
  1164. }
  1165. public MegaMorphTarget LoadTarget(BinaryReader br)
  1166. {
  1167. MegaMorphTarget target = new MegaMorphTarget();
  1168. currentTarget = target;
  1169. //Parse(br, ParseTarget);
  1170. MegaParse.Parse(br, ParseTarget);
  1171. return target;
  1172. }
  1173. bool TryMapping1(MegaTargetMesh tm, MegaMorph morph)
  1174. {
  1175. MegaModifiers mod = morph.GetComponent<MegaModifiers>();
  1176. if ( mod == null )
  1177. {
  1178. EditorUtility.DisplayDialog("Missing ModifyObject!", "No ModifyObject script found on the object", "OK");
  1179. return false;
  1180. }
  1181. int[] mapping = new int[mod.verts.Length];
  1182. #if false
  1183. for ( int i = 0; i < 8; i++ )
  1184. {
  1185. Debug.Log("target vert " + tm.verts[i].ToString("0.000"));
  1186. }
  1187. for ( int i = 0; i < 8; i++ )
  1188. {
  1189. Debug.Log("base vert " + mod.verts[i].ToString("0.000"));
  1190. }
  1191. #endif
  1192. // Get extents for mod verts and for imported meshes, if not the same then scale
  1193. Vector3 min1,max1;
  1194. Vector3 min2,max2;
  1195. Vector3 ex1 = Extents(mod.verts, out min1, out max1);
  1196. Vector3 ex2 = Extents(tm.verts, out min2, out max2);
  1197. // need min max on all axis so we can produce an offset to add
  1198. float d1 = ex1.x;
  1199. float d2 = ex2.x;
  1200. float scl = d1 / d2; //d2 / d1;
  1201. bool flipyz = false;
  1202. bool negx = false;
  1203. #if false
  1204. Debug.Log("min1 " + min1.ToString("0.0000") + " max1 " + max1.ToString("0.0000"));
  1205. Debug.Log("min2 " + min2.ToString("0.0000") + " max2 " + max2.ToString("0.0000"));
  1206. Debug.Log("scale " + scl.ToString("0.0000"));
  1207. Vector3 offset = (min2 * scl) - min1;
  1208. Debug.Log("offset " + offset.ToString("0.0000"));
  1209. for ( int i = 0; i < 8; i++ )
  1210. {
  1211. Vector3 p = tm.verts[i];
  1212. p = (p * scl) - offset;
  1213. //Debug.Log("adj vert " + p.ToString("0.000"));
  1214. }
  1215. #endif
  1216. // So try to match first vert using autoscale and no flip
  1217. bool mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx);
  1218. if ( !mapped )
  1219. {
  1220. flipyz = true;
  1221. mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx);
  1222. if ( !mapped ) //DoMapping(mod, morph, tm, mapping, scl, flipyz, negx) )
  1223. {
  1224. flipyz = false;
  1225. negx = true;
  1226. mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx);
  1227. if ( !mapped )
  1228. {
  1229. flipyz = true;
  1230. mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx);
  1231. //if ( !mapped )
  1232. //{
  1233. // mapped = DoMapping(mod, morph, tm, mapping, scl, flipyz, negx, true);
  1234. //}
  1235. }
  1236. }
  1237. }
  1238. if ( mapped )
  1239. {
  1240. morph.importScale = scl;
  1241. morph.flipyz = flipyz;
  1242. morph.negx = negx;
  1243. morph.mapping = mapping;
  1244. // if mapping was ok set opoints
  1245. morph.oPoints = tm.verts.ToArray();
  1246. for ( int i = 0; i < morph.oPoints.Length; i++ )
  1247. {
  1248. Vector3 p = morph.oPoints[i];
  1249. if ( negx )
  1250. p.x = -p.x;
  1251. if ( flipyz )
  1252. {
  1253. float z = p.z;
  1254. p.z = p.y;
  1255. p.y = z;
  1256. }
  1257. morph.oPoints[i] = p * morph.importScale;
  1258. }
  1259. return true;
  1260. }
  1261. else
  1262. morph.oPoints = tm.verts.ToArray();
  1263. return false;
  1264. }
  1265. MegaModifyObject mo = null;
  1266. public void OnSceneGUI()
  1267. {
  1268. MegaMorph mod = (MegaMorph)target;
  1269. if ( mod.showmapping )
  1270. {
  1271. if ( mod.oPoints != null )
  1272. {
  1273. float vsize = mod.mappingSize;
  1274. float vsize1 = vsize * 0.75f;
  1275. Matrix4x4 tm = mod.gameObject.transform.localToWorldMatrix;
  1276. Handles.matrix = tm; //Matrix4x4.identity;
  1277. Handles.color = Color.green;
  1278. if ( mo == null )
  1279. mo = mod.gameObject.GetComponent<MegaModifyObject>();
  1280. if ( mo )
  1281. {
  1282. for ( int i = 0; i < mo.verts.Length; i++ )
  1283. {
  1284. Vector3 p = mo.verts[i];
  1285. MegaHandles.DotCap(i, p, Quaternion.identity, vsize);
  1286. }
  1287. }
  1288. if ( mod.mapEnd >= mod.oPoints.Length )
  1289. mod.mapEnd = mod.oPoints.Length - 1;
  1290. if ( mod.mapStart > mod.mapEnd )
  1291. mod.mapStart = mod.mapEnd;
  1292. Handles.color = Color.red;
  1293. for ( int i = mod.mapStart; i < mod.mapEnd; i++ )
  1294. {
  1295. Vector3 p = mod.oPoints[i];
  1296. MegaHandles.DotCap(i, p, Quaternion.identity, vsize1);
  1297. }
  1298. Handles.matrix = Matrix4x4.identity;
  1299. }
  1300. }
  1301. }
  1302. }
  1303. // 1497