MegaCacheOBJ.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. using UnityEngine;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. [System.Serializable]
  6. public enum MegaCacheData
  7. {
  8. Mesh,
  9. File,
  10. Image,
  11. }
  12. [System.Serializable]
  13. public class MegaCacheImageFace
  14. {
  15. public int max;
  16. public int[] tris;
  17. }
  18. [System.Serializable]
  19. public enum MegaCacheRepeatMode
  20. {
  21. Loop,
  22. Clamp,
  23. PingPong,
  24. };
  25. [AddComponentMenu("MegaFiers/OBJ Cache")]
  26. [ExecuteInEditMode, RequireComponent(typeof(MeshFilter)), RequireComponent(typeof(MeshRenderer))]
  27. public class MegaCacheOBJ : MonoBehaviour
  28. {
  29. public List<Mesh> meshes = new List<Mesh>();
  30. public int frame = 0;
  31. public bool animate = false;
  32. public float time = 0.0f;
  33. public float speed = 1.0f;
  34. public float looptime = 5.0f;
  35. public float fps = 25.0f;
  36. public MegaCacheRepeatMode loopmode = MegaCacheRepeatMode.Loop;
  37. public int firstframe = 0;
  38. public int lastframe = 1;
  39. public int skip = 0;
  40. public string lastpath = "";
  41. public string cachefile = "";
  42. public int framevertcount = 0;
  43. public int frametricount = 0;
  44. public float scale = 1.0f;
  45. public bool adjustcoord = true;
  46. public bool buildtangents = false;
  47. public bool updatecollider = false;
  48. public bool saveuvs = true;
  49. public bool savenormals = true;
  50. public bool savetangents = true;
  51. public bool optimize = true;
  52. public bool recalcnormals = false;
  53. public bool update = false;
  54. public bool loadmtls = false;
  55. public MegaCacheData datasource = MegaCacheData.Mesh;
  56. public MegaCacheImage cacheimage;
  57. public MeshFilter mf;
  58. public int framecount = 0;
  59. public Vector3[] vertcache;
  60. public Vector3[] normcache;
  61. public Vector4[] tangentcache;
  62. public Vector2[] uvcache;
  63. public MegaCacheImageFace[] subs;
  64. public int decformat = 0;
  65. public bool shownormals = false;
  66. public bool showextras = false;
  67. public float normallen = 1.0f;
  68. public bool showdataimport = true;
  69. public bool showanimation = true;
  70. public bool showdata = false;
  71. //public string namesplit = "";
  72. public string runtimefolder = "";
  73. bool optimized = false;
  74. int lastreadframe = -1;
  75. Mesh lastmesh = null;
  76. int maxv = 0;
  77. int maxsm = 0;
  78. int[] maxsmfc;
  79. FileStream fs;
  80. BinaryReader br;
  81. long[] meshoffs;
  82. public Mesh imagemesh;
  83. static byte[] buffer;
  84. public bool meshchanged = false;
  85. [ContextMenu("Help")]
  86. public void Help()
  87. {
  88. Application.OpenURL("http://www.west-racing.com/mf/?page_id=6226");
  89. }
  90. void Start()
  91. {
  92. mf = GetComponent<MeshFilter>();
  93. #if UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  94. if ( !Application.isEditor )
  95. #else
  96. if ( !Application.isEditor && !Application.isWebPlayer )
  97. #endif
  98. {
  99. if ( datasource == MegaCacheData.File )
  100. {
  101. if ( fs == null )
  102. {
  103. string file = Path.GetFileName(cachefile);
  104. string fullpath = Application.dataPath + "/";
  105. if ( runtimefolder.Length > 0 )
  106. fullpath += runtimefolder + "/";
  107. fullpath += file;
  108. OpenCache(fullpath); //cachefile);
  109. }
  110. }
  111. }
  112. }
  113. public void ChangeSource(MegaCacheData src)
  114. {
  115. if ( src != datasource )
  116. {
  117. CloseCache();
  118. datasource = src;
  119. if ( Application.isEditor )
  120. DestroyImmediate(imagemesh);
  121. else
  122. Destroy(imagemesh);
  123. switch ( datasource )
  124. {
  125. case MegaCacheData.Mesh: break;
  126. case MegaCacheData.File: OpenCache(cachefile); break;
  127. case MegaCacheData.Image: MountImage(cacheimage); break;
  128. }
  129. update = true;
  130. }
  131. }
  132. void Update()
  133. {
  134. int fc = 0;
  135. switch ( datasource )
  136. {
  137. case MegaCacheData.Mesh: fc = meshes.Count - 1; break;
  138. case MegaCacheData.File: fc = framecount - 1; break;
  139. case MegaCacheData.Image:
  140. if ( cacheimage && cacheimage.frames != null )
  141. fc = cacheimage.frames.Count - 1;
  142. break;
  143. }
  144. if ( fc > 0 )
  145. {
  146. if ( animate )
  147. {
  148. looptime = fc / fps;
  149. if ( Application.isPlaying )
  150. time += Time.deltaTime * speed;
  151. float at = time;
  152. switch ( loopmode )
  153. {
  154. case MegaCacheRepeatMode.Loop:
  155. at = Mathf.Repeat(time, Mathf.Abs(looptime));
  156. if ( looptime < 0.0f )
  157. at = looptime - at;
  158. break;
  159. case MegaCacheRepeatMode.PingPong: at = Mathf.PingPong(time, looptime); break;
  160. case MegaCacheRepeatMode.Clamp: at = Mathf.Clamp(time, 0.0f, looptime); break;
  161. }
  162. frame = (int)((at / looptime) * fc);
  163. }
  164. frame = Mathf.Clamp(frame, 0, fc);
  165. if ( frame != lastframe )
  166. meshchanged = true;
  167. if ( datasource == MegaCacheData.Image && cacheimage )
  168. {
  169. if ( imagemesh == null )
  170. imagemesh = new Mesh();
  171. if ( mf.sharedMesh != imagemesh )
  172. {
  173. ClearMesh();
  174. mf.sharedMesh = imagemesh;
  175. }
  176. cacheimage.GetMesh(imagemesh, frame, this);
  177. }
  178. if ( datasource == MegaCacheData.File )
  179. GetFrame(frame);
  180. if ( datasource == MegaCacheData.Mesh )
  181. {
  182. if ( mf && meshes.Count > 0 )
  183. {
  184. if ( mf.sharedMesh != meshes[frame] || update )
  185. {
  186. mf.sharedMesh = meshes[frame];
  187. framevertcount = meshes[frame].vertexCount;
  188. }
  189. }
  190. }
  191. if ( updatecollider && meshchanged )
  192. {
  193. if ( meshCol == null )
  194. meshCol = GetComponent<MeshCollider>();
  195. if ( meshCol != null )
  196. {
  197. meshCol.sharedMesh = null;
  198. meshCol.sharedMesh = mf.sharedMesh;
  199. }
  200. }
  201. }
  202. update = false;
  203. meshchanged = false;
  204. }
  205. MeshCollider meshCol;
  206. void Reset()
  207. {
  208. }
  209. public void AddMesh(Mesh ms)
  210. {
  211. if ( ms )
  212. meshes.Add(ms);
  213. }
  214. public void DestroyMeshes()
  215. {
  216. for ( int i = 0; i < meshes.Count; i++ )
  217. {
  218. if ( Application.isPlaying )
  219. Destroy(meshes[i]);
  220. else
  221. DestroyImmediate(meshes[i]);
  222. }
  223. meshes.Clear();
  224. meshes.TrimExcess();
  225. System.GC.Collect();
  226. ClearMesh();
  227. mf.sharedMesh = new Mesh();
  228. }
  229. public void DestroyImage()
  230. {
  231. if ( cacheimage )
  232. {
  233. if ( Application.isEditor )
  234. DestroyImmediate(cacheimage);
  235. else
  236. Destroy(cacheimage);
  237. cacheimage = null;
  238. }
  239. }
  240. public void ClearMesh()
  241. {
  242. if ( Application.isEditor )
  243. DestroyImmediate(mf.sharedMesh);
  244. else
  245. Destroy(mf.sharedMesh);
  246. mf.sharedMesh = null;
  247. }
  248. public void InitImport()
  249. {
  250. MegaCacheObjImporter.Init();
  251. }
  252. #if false
  253. string MakeFileName(string file, ref int format)
  254. {
  255. Debug.Log("filein " + file);
  256. string ret = "";
  257. format = 0;
  258. for ( int i = file.Length - 1; i >= 0; i-- )
  259. {
  260. char c = file[i];
  261. if ( Char.IsNumber(c) )
  262. {
  263. format++;
  264. }
  265. else
  266. {
  267. ret = file.Substring(0, i + 1);
  268. Debug.Log("ret " + ret + " format " + format);
  269. break;
  270. }
  271. }
  272. return ret;
  273. }
  274. #endif
  275. public Mesh LoadFrame(string filename, int frame)
  276. {
  277. Mesh ms = null;
  278. string dir = Path.GetDirectoryName(filename);
  279. string file = Path.GetFileNameWithoutExtension(filename);
  280. file = MegaCacheUtils.MakeFileName(file, ref decformat);
  281. //if ( file.Length > 0 )
  282. {
  283. string newfname = dir + "/" + file + frame.ToString("D" + decformat) + ".obj";
  284. ms = LoadFrame(newfname);
  285. }
  286. return ms;
  287. }
  288. public void LoadMtl(string filename, int frame)
  289. {
  290. string dir = Path.GetDirectoryName(filename);
  291. string file = Path.GetFileNameWithoutExtension(filename);
  292. file = MegaCacheUtils.MakeFileName(file, ref decformat);
  293. //if ( file.Length > 0 )
  294. {
  295. string newfname = dir + "/" + file + frame.ToString("D" + decformat) + ".mtl";
  296. LoadMtl(newfname);
  297. }
  298. }
  299. // Change this, work from end of file without extension to find first non numeric character, then up to that is filename, and num of nums is format
  300. #if false
  301. public Mesh LoadFrame(string filename, int frame)
  302. {
  303. Mesh ms = null;
  304. char[] splits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
  305. string dir= Path.GetDirectoryName(filename);
  306. string file = Path.GetFileNameWithoutExtension(filename);
  307. string[] names;
  308. if ( namesplit.Length > 0 )
  309. {
  310. names = file.Split(namesplit[0]);
  311. names[0] += namesplit[0];
  312. }
  313. else
  314. names = file.Split(splits);
  315. if ( names.Length > 0 )
  316. {
  317. string newfname = dir + "/" + names[0] + frame.ToString("D" + decformat) + ".obj";
  318. ms = LoadFrame(newfname);
  319. }
  320. return ms;
  321. }
  322. public void LoadMtl(string filename, int frame)
  323. {
  324. char[] splits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
  325. string dir= Path.GetDirectoryName(filename);
  326. string file = Path.GetFileNameWithoutExtension(filename);
  327. string[] names;
  328. if ( namesplit.Length > 0 )
  329. {
  330. names = file.Split(namesplit[0]);
  331. names[0] += namesplit[0];
  332. }
  333. else
  334. names = file.Split(splits);
  335. if ( names.Length > 0 )
  336. {
  337. string newfname = dir + "/" + names[0] + frame.ToString("D" + decformat) + ".mtl";
  338. LoadMtl(newfname);
  339. }
  340. }
  341. #endif
  342. public void LoadMtl(string filename)
  343. {
  344. if ( File.Exists(filename) )
  345. MegaCacheObjImporter.ImportMtl(filename);
  346. }
  347. public Mesh LoadFrame(string filename)
  348. {
  349. Mesh ms = null;
  350. if ( File.Exists(filename) )
  351. ms = MegaCacheObjImporter.ImportFile(filename, scale, adjustcoord, buildtangents, loadmtls, optimize, recalcnormals);
  352. return ms;
  353. }
  354. public void MountImage(MegaCacheImage image)
  355. {
  356. if ( image )
  357. {
  358. subs = new MegaCacheImageFace[image.maxsm];
  359. for ( int i = 0; i < image.maxsm; i++ )
  360. {
  361. MegaCacheImageFace cf = new MegaCacheImageFace();
  362. cf.max = image.smfc[i];
  363. cf.tris = new int[cf.max];
  364. subs[i] = cf;
  365. }
  366. vertcache = new Vector3[image.maxv];
  367. normcache = new Vector3[image.maxv];
  368. tangentcache = new Vector4[image.maxv];
  369. uvcache = new Vector2[image.maxv];
  370. }
  371. }
  372. public void OpenCache(string filename)
  373. {
  374. if ( filename.Length == 0 )
  375. return;
  376. fs = new FileStream(filename, FileMode.Open);
  377. if ( fs != null )
  378. {
  379. br = new BinaryReader(fs);
  380. if ( br != null )
  381. {
  382. int version = br.ReadInt32();
  383. if ( version == 0 )
  384. {
  385. framecount = br.ReadInt32();
  386. optimized = br.ReadBoolean();
  387. maxv = br.ReadInt32();
  388. br.ReadInt32();
  389. maxsm = br.ReadInt32();
  390. subs = new MegaCacheImageFace[maxsm];
  391. for ( int i = 0; i < maxsm; i++ )
  392. {
  393. MegaCacheImageFace cf = new MegaCacheImageFace();
  394. cf.max = br.ReadInt32();
  395. cf.tris = new int[cf.max];
  396. subs[i] = cf;
  397. }
  398. }
  399. vertcache = new Vector3[maxv];
  400. normcache = new Vector3[maxv];
  401. tangentcache = new Vector4[maxv];
  402. uvcache = new Vector2[maxv];
  403. if ( buffer == null || buffer.Length < maxv * 16 )
  404. buffer = new byte[maxv * 16];
  405. meshoffs = new long[framecount];
  406. for ( int i = 0; i < framecount; i++ )
  407. meshoffs[i] = br.ReadInt64();
  408. ClearMesh();
  409. Mesh mesh = new Mesh();
  410. mf.sharedMesh = mesh;
  411. update = true;
  412. }
  413. }
  414. }
  415. void OnDestroy()
  416. {
  417. CloseCache();
  418. }
  419. void OnDrawGizmosSelected()
  420. {
  421. if ( shownormals )
  422. {
  423. Vector3[] verts;
  424. Vector3[] norms;
  425. verts = mf.sharedMesh.vertices;
  426. norms = mf.sharedMesh.normals;
  427. Gizmos.color = Color.red;
  428. Gizmos.matrix = transform.localToWorldMatrix;
  429. float len = normallen * 0.01f;
  430. Color col = Color.black;
  431. for ( int i = 0; i < framevertcount; i++ )
  432. {
  433. col.r = norms[i].x;
  434. col.g = norms[i].y;
  435. col.b = norms[i].z;
  436. Gizmos.color = col;
  437. Gizmos.DrawRay(verts[i], norms[i] * len);
  438. }
  439. Gizmos.matrix = Matrix4x4.identity;
  440. }
  441. }
  442. void GetFrame(int fnum)
  443. {
  444. if ( br == null )
  445. {
  446. OpenCache(cachefile);
  447. }
  448. GetFrame(fnum, mf.sharedMesh);
  449. }
  450. public void GetFrameRef(int fnum, Mesh _mesh)
  451. {
  452. if ( br == null )
  453. {
  454. OpenCache(cachefile);
  455. update = true;
  456. }
  457. GetFrame(fnum, _mesh);
  458. }
  459. public void GetFrame(int fnum, Mesh mesh)
  460. {
  461. if ( fnum != lastreadframe || update || lastmesh == null )
  462. {
  463. MakeMeshFromFrame(fnum, mesh);
  464. lastreadframe = fnum;
  465. lastmesh = mesh;
  466. }
  467. else
  468. {
  469. if ( fnum == lastreadframe && mesh != lastmesh && lastmesh != null )
  470. {
  471. mesh.bounds = lastmesh.bounds;
  472. mesh.subMeshCount = lastmesh.subMeshCount;
  473. mesh.vertices = lastmesh.vertices;
  474. mesh.normals = lastmesh.normals;
  475. mesh.uv = lastmesh.uv;
  476. mesh.tangents = lastmesh.tangents;
  477. for ( int i = 0; i < lastmesh.subMeshCount; i++ )
  478. {
  479. mesh.SetTriangles(lastmesh.GetTriangles(i), i);
  480. }
  481. }
  482. }
  483. }
  484. public void MakeMeshFromFrame(int fnum, Mesh mesh)
  485. {
  486. if ( br != null )
  487. {
  488. fs.Position = meshoffs[fnum];
  489. int vc = br.ReadInt32();
  490. int nc = br.ReadInt32();
  491. int uvc = br.ReadInt32();
  492. int tc = br.ReadInt32();
  493. Vector3 bmin;
  494. Vector3 bmax;
  495. bmin.x = br.ReadSingle();
  496. bmin.y = br.ReadSingle();
  497. bmin.z = br.ReadSingle();
  498. bmax.x = br.ReadSingle();
  499. bmax.y = br.ReadSingle();
  500. bmax.z = br.ReadSingle();
  501. Vector3 bsize = (bmax - bmin) * (1.0f / 65535.0f);
  502. mesh.bounds.SetMinMax(bmin, bmax);
  503. float oo127 = 1.0f / 127.0f;
  504. if ( !optimized )
  505. {
  506. br.Read(buffer, 0, vc * 12);
  507. for ( int i = 0; i < vc; i++ )
  508. {
  509. int ix = i * 12;
  510. vertcache[i].x = System.BitConverter.ToSingle(buffer, ix);
  511. vertcache[i].y = System.BitConverter.ToSingle(buffer, ix + 4);
  512. vertcache[i].z = System.BitConverter.ToSingle(buffer, ix + 8);
  513. }
  514. }
  515. else
  516. {
  517. br.Read(buffer, 0, vc * 6);
  518. for ( int i = 0; i < vc; i++ )
  519. {
  520. int ix = i * 6;
  521. vertcache[i].x = bmin.x + ((float)System.BitConverter.ToUInt16(buffer, ix) * bsize.x);
  522. vertcache[i].y = bmin.y + ((float)System.BitConverter.ToUInt16(buffer, ix + 2) * bsize.y);
  523. vertcache[i].z = bmin.z + ((float)System.BitConverter.ToUInt16(buffer, ix + 4) * bsize.z);
  524. }
  525. }
  526. if ( !optimized )
  527. {
  528. br.Read(buffer, 0, nc * 12);
  529. for ( int i = 0; i < nc; i++ )
  530. {
  531. int ix = i * 12;
  532. normcache[i].x = System.BitConverter.ToSingle(buffer, ix);
  533. normcache[i].y = System.BitConverter.ToSingle(buffer, ix + 4);
  534. normcache[i].z = System.BitConverter.ToSingle(buffer, ix + 8);
  535. }
  536. }
  537. else
  538. {
  539. br.Read(buffer, 0, nc * 3);
  540. for ( int i = 0; i < nc; i++ )
  541. {
  542. int ix = i * 3;
  543. normcache[i].x = (float)((sbyte)buffer[ix]) * oo127;
  544. normcache[i].y = (float)((sbyte)buffer[ix + 1]) * oo127;
  545. normcache[i].z = (float)((sbyte)buffer[ix + 2]) * oo127;
  546. }
  547. }
  548. if ( !optimized )
  549. {
  550. br.Read(buffer, 0, tc * 16);
  551. for ( int i = 0; i < tc; i++ )
  552. {
  553. int ix = i * 16;
  554. tangentcache[i].x = System.BitConverter.ToSingle(buffer, ix);
  555. tangentcache[i].y = System.BitConverter.ToSingle(buffer, ix + 4);
  556. tangentcache[i].z = System.BitConverter.ToSingle(buffer, ix + 8);
  557. tangentcache[i].w = System.BitConverter.ToSingle(buffer, ix + 12);
  558. }
  559. }
  560. else
  561. {
  562. br.Read(buffer, 0, tc * 4);
  563. for ( int i = 0; i < tc; i++ )
  564. {
  565. tangentcache[i].x = (float)((sbyte)buffer[i * 4]) * oo127;
  566. tangentcache[i].y = (float)((sbyte)buffer[i * 4 + 1]) * oo127;
  567. tangentcache[i].z = (float)((sbyte)buffer[i * 4 + 2]) * oo127;
  568. tangentcache[i].w = (float)((sbyte)buffer[i * 4 + 3]) * oo127;
  569. }
  570. }
  571. if ( !optimized )
  572. {
  573. br.Read(buffer, 0, uvc * 8);
  574. for ( int i = 0; i < uvc; i++ )
  575. {
  576. int ix = i * 8;
  577. uvcache[i].x = System.BitConverter.ToSingle(buffer, ix);
  578. uvcache[i].y = System.BitConverter.ToSingle(buffer, ix + 4);
  579. }
  580. }
  581. else
  582. {
  583. Vector2 uvmin;
  584. Vector2 uvmax;
  585. uvmin.x = br.ReadSingle();
  586. uvmin.y = br.ReadSingle();
  587. uvmax.x = br.ReadSingle();
  588. uvmax.y = br.ReadSingle();
  589. Vector2 uvsize = (uvmax - uvmin) * (1.0f / 255.0f);
  590. br.Read(buffer, 0, uvc * 2);
  591. for ( int i = 0; i < uvc; i++ )
  592. {
  593. int ix = i * 2;
  594. uvcache[i].x = uvmin.x + ((float)((byte)buffer[ix]) * uvsize.x);
  595. uvcache[i].y = uvmin.y + ((float)((byte)buffer[ix + 1]) * uvsize.y);
  596. }
  597. }
  598. byte smcount = br.ReadByte();
  599. mesh.subMeshCount = smcount;
  600. mesh.vertices = vertcache;
  601. if ( nc > 0 )
  602. mesh.normals = normcache;
  603. if ( uvc > 0 )
  604. mesh.uv = uvcache;
  605. if ( tc > 0 )
  606. mesh.tangents = tangentcache;
  607. for ( int s = 0; s < smcount; s++ )
  608. {
  609. int trc = br.ReadInt32();
  610. br.Read(buffer, 0, trc * 2);
  611. for ( int f = 0; f < trc; f++ )
  612. subs[s].tris[f] = (int)System.BitConverter.ToUInt16(buffer, f * 2);
  613. for ( int ii = trc; ii < subs[s].max; ii++ )
  614. subs[s].tris[ii] = subs[s].tris[trc];
  615. }
  616. for ( int s = 0; s < smcount; s++ )
  617. mesh.SetTriangles(subs[s].tris, s);
  618. mesh.RecalculateBounds();
  619. }
  620. }
  621. public void CloseCache()
  622. {
  623. if ( br != null )
  624. {
  625. br.Close();
  626. br = null;
  627. }
  628. if ( fs != null )
  629. {
  630. fs.Close();
  631. fs = null;
  632. }
  633. buffer = null;
  634. GC.Collect();
  635. }
  636. public void CreateImageFromCacheFile()
  637. {
  638. if ( br == null )
  639. OpenCache(cachefile);
  640. if ( br != null )
  641. {
  642. if ( cacheimage )
  643. DestroyImage();
  644. MegaCacheImage img = (MegaCacheImage)ScriptableObject.CreateInstance<MegaCacheImage>();
  645. img.maxv = maxv;
  646. img.maxsm = maxsm;
  647. img.smfc = new int[maxsm];
  648. for ( int i = 0; i < maxsm; i++ )
  649. img.smfc[i] = subs[i].max;
  650. Mesh mesh = new Mesh();
  651. for ( int i = 0; i < framecount; i++ )
  652. {
  653. MakeMeshFromFrame(i, mesh);
  654. MegaCacheImageFrame frame = MegaCacheImage.CreateImageFrame(mesh);
  655. img.frames.Add(frame);
  656. }
  657. cacheimage = img;
  658. ChangeSource(MegaCacheData.Image);
  659. if ( Application.isEditor )
  660. DestroyImmediate(mesh);
  661. else
  662. Destroy(mesh);
  663. mesh = null;
  664. GC.Collect();
  665. }
  666. }
  667. }