MegaFlowFrame.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. using UnityEngine;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. [System.Serializable]
  6. public class MegaFlowVector
  7. {
  8. public byte x;
  9. public byte y;
  10. public byte z;
  11. }
  12. public class MegaFlowFrame : ScriptableObject
  13. {
  14. public int[] gridDim = new int[3];
  15. public int[] gridDim1 = new int[3];
  16. public int[] gridDim2 = new int[3];
  17. public int flags;
  18. public int framenumber = -1;
  19. public bool somebool;
  20. public float fval;
  21. public float fval1;
  22. public Vector3 spacing;
  23. public Vector3 size;
  24. public Vector3 gsize;
  25. public Vector3 oos;
  26. public Vector3 offset = Vector3.zero;
  27. public int memory = 0;
  28. public List<int> grid = new List<int>();
  29. public List<Vector3> vel = new List<Vector3>();
  30. public List<Vector3> force = new List<Vector3>();
  31. public List<float> smoke = new List<float>();
  32. public List<Vector3> pos = new List<Vector3>();
  33. public List<float> psize = new List<float>();
  34. public List<Color> color = new List<Color>();
  35. public List<float> rot = new List<float>();
  36. public List<MegaFlowVector> optvel = new List<MegaFlowVector>();
  37. public Matrix4x4 tm;
  38. public Matrix4x4 invtm;
  39. public GetVel GetGridVel;
  40. public delegate Vector3 GetVel(Vector3 pos, ref bool inbounds);
  41. public Sample SampleVel;
  42. public delegate Vector3 Sample(int x, int y, int z);
  43. public void DebugFlow(float st, float vt)
  44. {
  45. Debug.Log("gridDim " + gridDim[0] + " " + gridDim[1] + " " + gridDim[2]);
  46. Debug.Log("gridDim1 " + gridDim1[0] + " " + gridDim1[1] + " " + gridDim1[2]);
  47. Debug.Log("gridDim2 " + gridDim2[0] + " " + gridDim2[1] + " " + gridDim2[2]);
  48. Debug.Log("flags " + flags);
  49. Debug.Log("Frame " + framenumber);
  50. Debug.Log("fvals " + fval + " " + fval1);
  51. Debug.Log("Spacing " + spacing);
  52. Debug.Log("Size " + size.x + " " + size.y + " " + size.z);
  53. Debug.Log("gsize " + gsize.x + " " + gsize.y + " " + gsize.z);
  54. if ( force.Count > 0 )
  55. Debug.Log("Have Force Data");
  56. if ( smoke.Count > 0 )
  57. {
  58. Debug.Log("Have Smoke Data");
  59. #if false
  60. for ( int x = 0; x < gridDim[0]; x++ )
  61. {
  62. for ( int y = 0; y < gridDim[1]; y++ )
  63. {
  64. for ( int z = 0; z < gridDim[2]; z++ )
  65. {
  66. float p = smoke[(z * gridDim[1] * gridDim[0]) + (y * gridDim[0]) + x];
  67. if ( Mathf.Abs(p) > st )
  68. Debug.Log("Smoke[" + x + " " + y + " " + z + "] " + (z * gridDim[1] * gridDim[0]) + (y * gridDim[0]) + x + " " + p);
  69. }
  70. }
  71. }
  72. #endif
  73. }
  74. // Change arrays to Vectors
  75. if ( vel.Count > 0 )
  76. {
  77. Debug.Log("Have Vel Data");
  78. #if false
  79. for ( int x = 0; x < gridDim2[0]; x++ )
  80. {
  81. for ( int y = 0; y < gridDim2[1]; y++ )
  82. {
  83. for ( int z = 0; z < gridDim2[2]; z++ )
  84. {
  85. Vector3 p = vel[(z * gridDim2[1] * gridDim2[0]) + (y * gridDim2[0]) + x];
  86. if ( p.magnitude > vt )
  87. Debug.Log("Grid[" + x + "," + y + "," + z + "] " + p.x + " " + p.y + " " + p.z);
  88. }
  89. }
  90. }
  91. #endif
  92. }
  93. }
  94. public Vector3 GetGridVelWorld(Vector3 pos, ref bool inbounds)
  95. {
  96. return invtm.MultiplyVector(GetGridVel(tm.MultiplyPoint3x4(pos), ref inbounds));
  97. }
  98. public void Prepare(Matrix4x4 wltm)
  99. {
  100. if ( optimized )
  101. {
  102. if ( gridDim2[2] == 1 )
  103. {
  104. SampleVel = SampleVelOpt;
  105. GetGridVel = GetGridVelOptXY;
  106. }
  107. else
  108. {
  109. SampleVel = SampleVelOpt;
  110. GetGridVel = GetGridVelOpt;
  111. }
  112. }
  113. else
  114. {
  115. if ( gridDim2[2] == 1 )
  116. {
  117. SampleVel = SampleVelFloat;
  118. GetGridVel = GetGridVelFloatXY;
  119. }
  120. else
  121. {
  122. SampleVel = SampleVelFloat;
  123. GetGridVel = GetGridVelFloat;
  124. }
  125. }
  126. //if ( optimized )
  127. //{
  128. //GetGridVel = GetGridVelOpt;
  129. //SampleVel = SampleVelOpt;
  130. //}
  131. //else
  132. //{
  133. //GetGridVel = GetGridVelFloat;
  134. //SampleVel = SampleVelFloat;
  135. //}
  136. Matrix4x4 offtm = Matrix4x4.TRS((size * 0.5f) + offset, Quaternion.identity, Vector3.one);
  137. tm = offtm * wltm;
  138. invtm = tm.inverse;
  139. }
  140. public void Init()
  141. {
  142. GetGridVel = GetGridVelFloat;
  143. SampleVel = SampleVelFloat;
  144. if ( gridDim2[2] == 1 )
  145. {
  146. SampleVel = SampleVelFloat;
  147. GetGridVel = GetGridVelFloatXY;
  148. }
  149. else
  150. {
  151. SampleVel = SampleVelFloat;
  152. GetGridVel = GetGridVelFloat;
  153. }
  154. smoke.Clear();
  155. vel.Clear();
  156. force.Clear();
  157. grid.Clear();
  158. pos.Clear();
  159. psize.Clear();
  160. color.Clear();
  161. rot.Clear();
  162. optvel.Clear();
  163. }
  164. public Vector3 GetGridVelFloat(Vector3 pos, ref bool inbounds)
  165. {
  166. if ( vel.Count == 0 )
  167. return Vector3.zero;
  168. int xi = (int)(pos.x * oos.x);
  169. int yi = (int)(pos.y * oos.y);
  170. int zi = (int)(pos.z * oos.z);
  171. if ( xi < 0 || xi >= gridDim2[0] - 1 )
  172. {
  173. inbounds = false;
  174. return Vector3.zero;
  175. }
  176. if ( yi < 0 || yi >= gridDim2[1] - 1 )
  177. {
  178. inbounds = false;
  179. return Vector3.zero;
  180. }
  181. if ( zi < 0 || zi >= gridDim2[2] - 1 )
  182. {
  183. inbounds = false;
  184. return Vector3.zero;
  185. }
  186. inbounds = true;
  187. int xi1 = (xi + 1) * gridDim2[2] * gridDim2[1];
  188. int yi1 = yi + 1;
  189. int zi1 = (zi + 1) * gridDim2[1];
  190. float xr = Mathf.Abs((pos.x - (xi * spacing.x)) * oos.x);
  191. float yr = Mathf.Abs((pos.y - (yi * spacing.y)) * oos.y);
  192. float zr = Mathf.Abs((pos.z - (zi * spacing.z)) * oos.z);
  193. xi *= gridDim2[2] * gridDim2[1];
  194. zi *= gridDim2[1];
  195. Vector3 V000 = vel[xi + zi + yi];
  196. Vector3 V100 = vel[xi1 + zi + yi];
  197. Vector3 V110 = vel[xi1 + zi + yi1];
  198. Vector3 V010 = vel[xi + zi + yi1];
  199. Vector3 V001 = vel[xi + zi1 + yi];
  200. Vector3 V101 = vel[xi1 + zi1 + yi];
  201. Vector3 V111 = vel[xi1 + zi1 + yi1];
  202. Vector3 V011 = vel[xi + zi1 + yi1];
  203. float omx = 1.0f - xr;
  204. float omy = 1.0f - yr;
  205. float omz = 1.0f - zr;
  206. Vector3 Vxyz;
  207. float c1 = omx * omy * omz;
  208. float c2 = xr * omy * omz;
  209. float c3 = omx * yr * omz;
  210. float c4 = omx * omy * zr;
  211. float c5 = xr * omy * zr;
  212. float c6 = omx * yr * zr;
  213. float c7 = xr * yr * omz;
  214. float c8 = xr * yr * zr;
  215. Vxyz.x = V000.x * c1 + V100.x * c2 + V010.x * c3 + V001.x * c4 + V101.x * c5 + V011.x * c6 + V110.x * c7 + V111.x * c8;
  216. Vxyz.y = V000.y * c1 + V100.y * c2 + V010.y * c3 + V001.y * c4 + V101.y * c5 + V011.y * c6 + V110.y * c7 + V111.y * c8;
  217. Vxyz.z = V000.z * c1 + V100.z * c2 + V010.z * c3 + V001.z * c4 + V101.z * c5 + V011.z * c6 + V110.z * c7 + V111.z * c8;
  218. return Vxyz;
  219. }
  220. public const float oadj = 1.0f / 255.0f;
  221. public Vector3 GetGridVelOpt(Vector3 pos, ref bool inbounds)
  222. {
  223. if ( optvel.Count == 0 )
  224. return Vector3.zero;
  225. int xi = (int)(pos.x * oos.x);
  226. int yi = (int)(pos.y * oos.y);
  227. int zi = (int)(pos.z * oos.z);
  228. if ( xi < 0 || xi >= gridDim2[0] - 1 )
  229. {
  230. inbounds = false;
  231. return Vector3.zero;
  232. }
  233. if ( yi < 0 || yi >= gridDim2[1] - 1 )
  234. {
  235. inbounds = false;
  236. return Vector3.zero;
  237. }
  238. if ( zi < 0 || zi >= gridDim2[2] - 1 )
  239. {
  240. inbounds = false;
  241. return Vector3.zero;
  242. }
  243. inbounds = true;
  244. float xr = Mathf.Abs((pos.x - (xi * spacing.x)) * oos.x);
  245. float yr = Mathf.Abs((pos.y - (yi * spacing.y)) * oos.y);
  246. float zr = Mathf.Abs((pos.z - (zi * spacing.z)) * oos.z);
  247. int xi1 = (xi + 1) * gridDim2[2] * gridDim2[1];
  248. int yi1 = yi + 1;
  249. int zi1 = (zi + 1) * gridDim2[1];
  250. xi *= gridDim2[2] * gridDim2[1];
  251. zi *= gridDim2[1];
  252. MegaFlowVector mv = optvel[xi + zi + yi];
  253. Vector3 V000;
  254. V000.x = (float)mv.x;
  255. V000.y = (float)mv.y;
  256. V000.z = (float)mv.z;
  257. mv = optvel[xi1 + zi + yi];
  258. Vector3 V100;
  259. V100.x = (float)mv.x;
  260. V100.y = (float)mv.y;
  261. V100.z = (float)mv.z;
  262. mv = optvel[xi1 + zi + yi1];
  263. Vector3 V110;
  264. V110.x = (float)mv.x;
  265. V110.y = (float)mv.y;
  266. V110.z = (float)mv.z;
  267. mv = optvel[xi + zi + yi1];
  268. Vector3 V010;
  269. V010.x = (float)mv.x;
  270. V010.y = (float)mv.y;
  271. V010.z = (float)mv.z;
  272. mv = optvel[xi + zi1 + yi];
  273. Vector3 V001;
  274. V001.x = (float)mv.x;
  275. V001.y = (float)mv.y;
  276. V001.z = (float)mv.z;
  277. mv = optvel[xi1 + zi1 + yi];
  278. Vector3 V101;
  279. V101.x = (float)mv.x;
  280. V101.y = (float)mv.y;
  281. V101.z = (float)mv.z;
  282. mv = optvel[xi1 + zi1 + yi1];
  283. Vector3 V111;
  284. V111.x = (float)mv.x;
  285. V111.y = (float)mv.y;
  286. V111.z = (float)mv.z;
  287. mv = optvel[xi + zi1 + yi1];
  288. Vector3 V011;
  289. V011.x = (float)mv.x;
  290. V011.y = (float)mv.y;
  291. V011.z = (float)mv.z;
  292. float omx = 1.0f - xr;
  293. float omy = 1.0f - yr;
  294. float omz = 1.0f - zr;
  295. Vector3 Vxyz = V000 * omx * omy * omz +
  296. V100 * xr * omy * omz +
  297. V010 * omx * yr * omz +
  298. V001 * omx * omy * zr +
  299. V101 * xr * omy * zr +
  300. V011 * omx * yr * zr +
  301. V110 * xr * yr * omz +
  302. V111 * xr * yr * zr;
  303. Vxyz.x = ((Vxyz.x * oadj) - 0.5f) * maxval.x;
  304. Vxyz.y = ((Vxyz.y * oadj) - 0.5f) * maxval.y;
  305. Vxyz.z = ((Vxyz.z * oadj) - 0.5f) * maxval.z;
  306. return Vxyz;
  307. }
  308. public Vector3 maxval;
  309. public bool optimized = false;
  310. public Vector3 SampleVelFloat(int x, int y, int z)
  311. {
  312. return vel[(x * gridDim2[2] * gridDim2[1]) + (z * gridDim2[1]) + y];
  313. }
  314. public Vector3 SampleVelOpt(int x, int y, int z)
  315. {
  316. MegaFlowVector mv = optvel[(x * gridDim2[2] * gridDim2[1]) + (z * gridDim2[1]) + y];
  317. Vector3 v;
  318. v.x = (((float)mv.x * oadj) - 0.5f) * maxval.x;
  319. v.y = (((float)mv.y * oadj) - 0.5f) * maxval.y;
  320. v.z = (((float)mv.z * oadj) - 0.5f) * maxval.z;
  321. return v;
  322. }
  323. public void Optimize()
  324. {
  325. Vector3 max = Vector3.zero;
  326. if ( optvel == null )
  327. optvel = new List<MegaFlowVector>();
  328. optvel.Clear();
  329. for ( int i = 0; i < vel.Count; i++ )
  330. {
  331. Vector3 v = vel[i];
  332. if ( Mathf.Abs(v.x) > max.x )
  333. max.x = Mathf.Abs(v.x);
  334. if ( Mathf.Abs(v.y) > max.y )
  335. max.y = Mathf.Abs(v.y);
  336. if ( Mathf.Abs(v.z) > max.z )
  337. max.z = Mathf.Abs(v.z);
  338. }
  339. maxval = max;
  340. for ( int i = 0; i < vel.Count; i++ )
  341. {
  342. MegaFlowVector mv = new MegaFlowVector();
  343. Vector3 v = vel[i];
  344. mv.x = (byte)(((v.x / maxval.x) + 1.0f) * 0.5f * 255.0f);
  345. mv.y = (byte)(((v.y / maxval.y) + 1.0f) * 0.5f * 255.0f);
  346. mv.z = (byte)(((v.z / maxval.z) + 1.0f) * 0.5f * 255.0f);
  347. optvel.Add(mv);
  348. }
  349. optimized = true;
  350. //GetGridVel = GetGridVelOpt;
  351. //SampleVel = SampleVelOpt;
  352. if ( gridDim2[2] == 1 )
  353. {
  354. SampleVel = SampleVelOpt;
  355. GetGridVel = GetGridVelOptXY;
  356. }
  357. else
  358. {
  359. SampleVel = SampleVelOpt;
  360. GetGridVel = GetGridVelOpt;
  361. }
  362. maxval *= 2.0f;
  363. vel.Clear();
  364. GC.Collect();
  365. }
  366. // 2D
  367. public Vector3 GetGridVelFloatXY(Vector3 pos, ref bool inbounds)
  368. {
  369. if ( vel.Count == 0 )
  370. return Vector3.zero;
  371. int xi = (int)(pos.x * oos.x);
  372. int yi = (int)(pos.y * oos.y);
  373. if ( xi < 0 || xi >= gridDim2[0] - 1 || yi < 0 || yi >= gridDim2[1] - 1 )
  374. {
  375. inbounds = false;
  376. return Vector3.zero;
  377. }
  378. inbounds = true;
  379. int xi1 = (xi + 1) * gridDim2[2] * gridDim2[1];
  380. int yi1 = yi + 1;
  381. float xr = Mathf.Abs((pos.x - (xi * spacing.x)) * oos.x);
  382. float yr = Mathf.Abs((pos.y - (yi * spacing.y)) * oos.y);
  383. xi *= gridDim2[2] * gridDim2[1];
  384. Vector3 V000 = vel[xi + yi];
  385. Vector3 V100 = vel[xi1 + yi];
  386. Vector3 V110 = vel[xi1 + yi1];
  387. Vector3 V010 = vel[xi + yi1];
  388. float omx = 1.0f - xr;
  389. float omy = 1.0f - yr;
  390. Vector3 Vxyz;
  391. float c1 = omx * omy;
  392. float c2 = xr * omy;
  393. float c3 = omx * yr;
  394. float c4 = xr * yr;
  395. Vxyz.x = V000.x * c1 + V100.x * c2 + V010.x * c3 + V110.x * c4;
  396. Vxyz.y = V000.y * c1 + V100.y * c2 + V010.y * c3 + V110.y * c4;
  397. Vxyz.z = 0.0f; //V000.z * c1 + V100.z * c2 + V010.z * c3 + V110.z * c4;
  398. return Vxyz;
  399. }
  400. public Vector3 GetGridVelOptXY(Vector3 pos, ref bool inbounds)
  401. {
  402. if ( optvel.Count == 0 )
  403. return Vector3.zero;
  404. int xi = (int)(pos.x * oos.x);
  405. int yi = (int)(pos.y * oos.y);
  406. if ( xi < 0 || xi >= gridDim2[0] - 1 )
  407. {
  408. inbounds = false;
  409. return Vector3.zero;
  410. }
  411. if ( yi < 0 || yi >= gridDim2[1] - 1 )
  412. {
  413. inbounds = false;
  414. return Vector3.zero;
  415. }
  416. inbounds = true;
  417. float xr = Mathf.Abs((pos.x - (xi * spacing.x)) * oos.x);
  418. float yr = Mathf.Abs((pos.y - (yi * spacing.y)) * oos.y);
  419. int xi1 = (xi + 1) * gridDim2[2] * gridDim2[1];
  420. int yi1 = yi + 1;
  421. xi *= gridDim2[2] * gridDim2[1];
  422. MegaFlowVector mv = optvel[xi + yi];
  423. Vector3 V000;
  424. V000.x = (float)mv.x;
  425. V000.y = (float)mv.y;
  426. V000.z = (float)mv.z;
  427. mv = optvel[xi1 + yi];
  428. Vector3 V100;
  429. V100.x = (float)mv.x;
  430. V100.y = (float)mv.y;
  431. V100.z = (float)mv.z;
  432. mv = optvel[xi1 + yi1];
  433. Vector3 V110;
  434. V110.x = (float)mv.x;
  435. V110.y = (float)mv.y;
  436. V110.z = (float)mv.z;
  437. mv = optvel[xi + yi1];
  438. Vector3 V010;
  439. V010.x = (float)mv.x;
  440. V010.y = (float)mv.y;
  441. V010.z = (float)mv.z;
  442. float omx = 1.0f - xr;
  443. float omy = 1.0f - yr;
  444. Vector3 Vxyz = V000 * omx * omy + V100 * xr * omy + V010 * omx * yr + V110 * xr * yr;
  445. Vxyz.x = ((Vxyz.x * oadj) - 0.5f) * maxval.x;
  446. Vxyz.y = ((Vxyz.y * oadj) - 0.5f) * maxval.y;
  447. Vxyz.z = 0.0f; //((Vxyz.z * oadj) - 0.5f) * maxval.z;
  448. return Vxyz;
  449. }
  450. }