123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564 |
- using UnityEngine;
- using System;
- using System.Collections.Generic;
- using System.IO;
- [System.Serializable]
- public class MegaFlowVector
- {
- public byte x;
- public byte y;
- public byte z;
- }
- public class MegaFlowFrame : ScriptableObject
- {
- public int[] gridDim = new int[3];
- public int[] gridDim1 = new int[3];
- public int[] gridDim2 = new int[3];
- public int flags;
- public int framenumber = -1;
- public bool somebool;
- public float fval;
- public float fval1;
- public Vector3 spacing;
- public Vector3 size;
- public Vector3 gsize;
- public Vector3 oos;
- public Vector3 offset = Vector3.zero;
- public int memory = 0;
- public List<int> grid = new List<int>();
- public List<Vector3> vel = new List<Vector3>();
- public List<Vector3> force = new List<Vector3>();
- public List<float> smoke = new List<float>();
- public List<Vector3> pos = new List<Vector3>();
- public List<float> psize = new List<float>();
- public List<Color> color = new List<Color>();
- public List<float> rot = new List<float>();
- public List<MegaFlowVector> optvel = new List<MegaFlowVector>();
- public Matrix4x4 tm;
- public Matrix4x4 invtm;
- public GetVel GetGridVel;
- public delegate Vector3 GetVel(Vector3 pos, ref bool inbounds);
- public Sample SampleVel;
- public delegate Vector3 Sample(int x, int y, int z);
- public void DebugFlow(float st, float vt)
- {
- Debug.Log("gridDim " + gridDim[0] + " " + gridDim[1] + " " + gridDim[2]);
- Debug.Log("gridDim1 " + gridDim1[0] + " " + gridDim1[1] + " " + gridDim1[2]);
- Debug.Log("gridDim2 " + gridDim2[0] + " " + gridDim2[1] + " " + gridDim2[2]);
- Debug.Log("flags " + flags);
- Debug.Log("Frame " + framenumber);
- Debug.Log("fvals " + fval + " " + fval1);
- Debug.Log("Spacing " + spacing);
- Debug.Log("Size " + size.x + " " + size.y + " " + size.z);
- Debug.Log("gsize " + gsize.x + " " + gsize.y + " " + gsize.z);
- if ( force.Count > 0 )
- Debug.Log("Have Force Data");
- if ( smoke.Count > 0 )
- {
- Debug.Log("Have Smoke Data");
- #if false
- for ( int x = 0; x < gridDim[0]; x++ )
- {
- for ( int y = 0; y < gridDim[1]; y++ )
- {
- for ( int z = 0; z < gridDim[2]; z++ )
- {
- float p = smoke[(z * gridDim[1] * gridDim[0]) + (y * gridDim[0]) + x];
- if ( Mathf.Abs(p) > st )
- Debug.Log("Smoke[" + x + " " + y + " " + z + "] " + (z * gridDim[1] * gridDim[0]) + (y * gridDim[0]) + x + " " + p);
- }
- }
- }
- #endif
- }
- // Change arrays to Vectors
- if ( vel.Count > 0 )
- {
- Debug.Log("Have Vel Data");
- #if false
- for ( int x = 0; x < gridDim2[0]; x++ )
- {
- for ( int y = 0; y < gridDim2[1]; y++ )
- {
- for ( int z = 0; z < gridDim2[2]; z++ )
- {
- Vector3 p = vel[(z * gridDim2[1] * gridDim2[0]) + (y * gridDim2[0]) + x];
- if ( p.magnitude > vt )
- Debug.Log("Grid[" + x + "," + y + "," + z + "] " + p.x + " " + p.y + " " + p.z);
- }
- }
- }
- #endif
- }
- }
- public Vector3 GetGridVelWorld(Vector3 pos, ref bool inbounds)
- {
- return invtm.MultiplyVector(GetGridVel(tm.MultiplyPoint3x4(pos), ref inbounds));
- }
- public void Prepare(Matrix4x4 wltm)
- {
- if ( optimized )
- {
- if ( gridDim2[2] == 1 )
- {
- SampleVel = SampleVelOpt;
- GetGridVel = GetGridVelOptXY;
- }
- else
- {
- SampleVel = SampleVelOpt;
- GetGridVel = GetGridVelOpt;
- }
- }
- else
- {
- if ( gridDim2[2] == 1 )
- {
- SampleVel = SampleVelFloat;
- GetGridVel = GetGridVelFloatXY;
- }
- else
- {
- SampleVel = SampleVelFloat;
- GetGridVel = GetGridVelFloat;
- }
- }
- //if ( optimized )
- //{
- //GetGridVel = GetGridVelOpt;
- //SampleVel = SampleVelOpt;
- //}
- //else
- //{
- //GetGridVel = GetGridVelFloat;
- //SampleVel = SampleVelFloat;
- //}
- Matrix4x4 offtm = Matrix4x4.TRS((size * 0.5f) + offset, Quaternion.identity, Vector3.one);
- tm = offtm * wltm;
- invtm = tm.inverse;
- }
- public void Init()
- {
- GetGridVel = GetGridVelFloat;
- SampleVel = SampleVelFloat;
- if ( gridDim2[2] == 1 )
- {
- SampleVel = SampleVelFloat;
- GetGridVel = GetGridVelFloatXY;
- }
- else
- {
- SampleVel = SampleVelFloat;
- GetGridVel = GetGridVelFloat;
- }
- smoke.Clear();
- vel.Clear();
- force.Clear();
- grid.Clear();
- pos.Clear();
- psize.Clear();
- color.Clear();
- rot.Clear();
- optvel.Clear();
- }
- public Vector3 GetGridVelFloat(Vector3 pos, ref bool inbounds)
- {
- if ( vel.Count == 0 )
- return Vector3.zero;
- int xi = (int)(pos.x * oos.x);
- int yi = (int)(pos.y * oos.y);
- int zi = (int)(pos.z * oos.z);
- if ( xi < 0 || xi >= gridDim2[0] - 1 )
- {
- inbounds = false;
- return Vector3.zero;
- }
- if ( yi < 0 || yi >= gridDim2[1] - 1 )
- {
- inbounds = false;
- return Vector3.zero;
- }
- if ( zi < 0 || zi >= gridDim2[2] - 1 )
- {
- inbounds = false;
- return Vector3.zero;
- }
- inbounds = true;
- int xi1 = (xi + 1) * gridDim2[2] * gridDim2[1];
- int yi1 = yi + 1;
- int zi1 = (zi + 1) * gridDim2[1];
- float xr = Mathf.Abs((pos.x - (xi * spacing.x)) * oos.x);
- float yr = Mathf.Abs((pos.y - (yi * spacing.y)) * oos.y);
- float zr = Mathf.Abs((pos.z - (zi * spacing.z)) * oos.z);
- xi *= gridDim2[2] * gridDim2[1];
- zi *= gridDim2[1];
- Vector3 V000 = vel[xi + zi + yi];
- Vector3 V100 = vel[xi1 + zi + yi];
- Vector3 V110 = vel[xi1 + zi + yi1];
- Vector3 V010 = vel[xi + zi + yi1];
- Vector3 V001 = vel[xi + zi1 + yi];
- Vector3 V101 = vel[xi1 + zi1 + yi];
- Vector3 V111 = vel[xi1 + zi1 + yi1];
- Vector3 V011 = vel[xi + zi1 + yi1];
- float omx = 1.0f - xr;
- float omy = 1.0f - yr;
- float omz = 1.0f - zr;
- Vector3 Vxyz;
- float c1 = omx * omy * omz;
- float c2 = xr * omy * omz;
- float c3 = omx * yr * omz;
- float c4 = omx * omy * zr;
- float c5 = xr * omy * zr;
- float c6 = omx * yr * zr;
- float c7 = xr * yr * omz;
- float c8 = xr * yr * zr;
- 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;
- 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;
- 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;
- return Vxyz;
- }
- public const float oadj = 1.0f / 255.0f;
- public Vector3 GetGridVelOpt(Vector3 pos, ref bool inbounds)
- {
- if ( optvel.Count == 0 )
- return Vector3.zero;
- int xi = (int)(pos.x * oos.x);
- int yi = (int)(pos.y * oos.y);
- int zi = (int)(pos.z * oos.z);
- if ( xi < 0 || xi >= gridDim2[0] - 1 )
- {
- inbounds = false;
- return Vector3.zero;
- }
- if ( yi < 0 || yi >= gridDim2[1] - 1 )
- {
- inbounds = false;
- return Vector3.zero;
- }
- if ( zi < 0 || zi >= gridDim2[2] - 1 )
- {
- inbounds = false;
- return Vector3.zero;
- }
- inbounds = true;
- float xr = Mathf.Abs((pos.x - (xi * spacing.x)) * oos.x);
- float yr = Mathf.Abs((pos.y - (yi * spacing.y)) * oos.y);
- float zr = Mathf.Abs((pos.z - (zi * spacing.z)) * oos.z);
- int xi1 = (xi + 1) * gridDim2[2] * gridDim2[1];
- int yi1 = yi + 1;
- int zi1 = (zi + 1) * gridDim2[1];
- xi *= gridDim2[2] * gridDim2[1];
- zi *= gridDim2[1];
- MegaFlowVector mv = optvel[xi + zi + yi];
- Vector3 V000;
- V000.x = (float)mv.x;
- V000.y = (float)mv.y;
- V000.z = (float)mv.z;
- mv = optvel[xi1 + zi + yi];
- Vector3 V100;
- V100.x = (float)mv.x;
- V100.y = (float)mv.y;
- V100.z = (float)mv.z;
- mv = optvel[xi1 + zi + yi1];
- Vector3 V110;
- V110.x = (float)mv.x;
- V110.y = (float)mv.y;
- V110.z = (float)mv.z;
- mv = optvel[xi + zi + yi1];
- Vector3 V010;
- V010.x = (float)mv.x;
- V010.y = (float)mv.y;
- V010.z = (float)mv.z;
-
- mv = optvel[xi + zi1 + yi];
- Vector3 V001;
- V001.x = (float)mv.x;
- V001.y = (float)mv.y;
- V001.z = (float)mv.z;
- mv = optvel[xi1 + zi1 + yi];
- Vector3 V101;
- V101.x = (float)mv.x;
- V101.y = (float)mv.y;
- V101.z = (float)mv.z;
- mv = optvel[xi1 + zi1 + yi1];
- Vector3 V111;
- V111.x = (float)mv.x;
- V111.y = (float)mv.y;
- V111.z = (float)mv.z;
- mv = optvel[xi + zi1 + yi1];
- Vector3 V011;
- V011.x = (float)mv.x;
- V011.y = (float)mv.y;
- V011.z = (float)mv.z;
- float omx = 1.0f - xr;
- float omy = 1.0f - yr;
- float omz = 1.0f - zr;
- Vector3 Vxyz = V000 * omx * omy * omz +
- V100 * xr * omy * omz +
- V010 * omx * yr * omz +
- V001 * omx * omy * zr +
- V101 * xr * omy * zr +
- V011 * omx * yr * zr +
- V110 * xr * yr * omz +
- V111 * xr * yr * zr;
- Vxyz.x = ((Vxyz.x * oadj) - 0.5f) * maxval.x;
- Vxyz.y = ((Vxyz.y * oadj) - 0.5f) * maxval.y;
- Vxyz.z = ((Vxyz.z * oadj) - 0.5f) * maxval.z;
- return Vxyz;
- }
- public Vector3 maxval;
- public bool optimized = false;
- public Vector3 SampleVelFloat(int x, int y, int z)
- {
- return vel[(x * gridDim2[2] * gridDim2[1]) + (z * gridDim2[1]) + y];
- }
- public Vector3 SampleVelOpt(int x, int y, int z)
- {
- MegaFlowVector mv = optvel[(x * gridDim2[2] * gridDim2[1]) + (z * gridDim2[1]) + y];
- Vector3 v;
- v.x = (((float)mv.x * oadj) - 0.5f) * maxval.x;
- v.y = (((float)mv.y * oadj) - 0.5f) * maxval.y;
- v.z = (((float)mv.z * oadj) - 0.5f) * maxval.z;
- return v;
- }
- public void Optimize()
- {
- Vector3 max = Vector3.zero;
- if ( optvel == null )
- optvel = new List<MegaFlowVector>();
- optvel.Clear();
- for ( int i = 0; i < vel.Count; i++ )
- {
- Vector3 v = vel[i];
- if ( Mathf.Abs(v.x) > max.x )
- max.x = Mathf.Abs(v.x);
- if ( Mathf.Abs(v.y) > max.y )
- max.y = Mathf.Abs(v.y);
- if ( Mathf.Abs(v.z) > max.z )
- max.z = Mathf.Abs(v.z);
- }
- maxval = max;
- for ( int i = 0; i < vel.Count; i++ )
- {
- MegaFlowVector mv = new MegaFlowVector();
- Vector3 v = vel[i];
- mv.x = (byte)(((v.x / maxval.x) + 1.0f) * 0.5f * 255.0f);
- mv.y = (byte)(((v.y / maxval.y) + 1.0f) * 0.5f * 255.0f);
- mv.z = (byte)(((v.z / maxval.z) + 1.0f) * 0.5f * 255.0f);
- optvel.Add(mv);
- }
- optimized = true;
- //GetGridVel = GetGridVelOpt;
- //SampleVel = SampleVelOpt;
- if ( gridDim2[2] == 1 )
- {
- SampleVel = SampleVelOpt;
- GetGridVel = GetGridVelOptXY;
- }
- else
- {
- SampleVel = SampleVelOpt;
- GetGridVel = GetGridVelOpt;
- }
- maxval *= 2.0f;
- vel.Clear();
- GC.Collect();
- }
- // 2D
- public Vector3 GetGridVelFloatXY(Vector3 pos, ref bool inbounds)
- {
- if ( vel.Count == 0 )
- return Vector3.zero;
- int xi = (int)(pos.x * oos.x);
- int yi = (int)(pos.y * oos.y);
- if ( xi < 0 || xi >= gridDim2[0] - 1 || yi < 0 || yi >= gridDim2[1] - 1 )
- {
- inbounds = false;
- return Vector3.zero;
- }
- inbounds = true;
- int xi1 = (xi + 1) * gridDim2[2] * gridDim2[1];
- int yi1 = yi + 1;
- float xr = Mathf.Abs((pos.x - (xi * spacing.x)) * oos.x);
- float yr = Mathf.Abs((pos.y - (yi * spacing.y)) * oos.y);
- xi *= gridDim2[2] * gridDim2[1];
- Vector3 V000 = vel[xi + yi];
- Vector3 V100 = vel[xi1 + yi];
- Vector3 V110 = vel[xi1 + yi1];
- Vector3 V010 = vel[xi + yi1];
- float omx = 1.0f - xr;
- float omy = 1.0f - yr;
- Vector3 Vxyz;
- float c1 = omx * omy;
- float c2 = xr * omy;
- float c3 = omx * yr;
- float c4 = xr * yr;
- Vxyz.x = V000.x * c1 + V100.x * c2 + V010.x * c3 + V110.x * c4;
- Vxyz.y = V000.y * c1 + V100.y * c2 + V010.y * c3 + V110.y * c4;
- Vxyz.z = 0.0f; //V000.z * c1 + V100.z * c2 + V010.z * c3 + V110.z * c4;
- return Vxyz;
- }
- public Vector3 GetGridVelOptXY(Vector3 pos, ref bool inbounds)
- {
- if ( optvel.Count == 0 )
- return Vector3.zero;
- int xi = (int)(pos.x * oos.x);
- int yi = (int)(pos.y * oos.y);
- if ( xi < 0 || xi >= gridDim2[0] - 1 )
- {
- inbounds = false;
- return Vector3.zero;
- }
- if ( yi < 0 || yi >= gridDim2[1] - 1 )
- {
- inbounds = false;
- return Vector3.zero;
- }
- inbounds = true;
- float xr = Mathf.Abs((pos.x - (xi * spacing.x)) * oos.x);
- float yr = Mathf.Abs((pos.y - (yi * spacing.y)) * oos.y);
- int xi1 = (xi + 1) * gridDim2[2] * gridDim2[1];
- int yi1 = yi + 1;
- xi *= gridDim2[2] * gridDim2[1];
- MegaFlowVector mv = optvel[xi + yi];
- Vector3 V000;
- V000.x = (float)mv.x;
- V000.y = (float)mv.y;
- V000.z = (float)mv.z;
- mv = optvel[xi1 + yi];
- Vector3 V100;
- V100.x = (float)mv.x;
- V100.y = (float)mv.y;
- V100.z = (float)mv.z;
- mv = optvel[xi1 + yi1];
- Vector3 V110;
- V110.x = (float)mv.x;
- V110.y = (float)mv.y;
- V110.z = (float)mv.z;
- mv = optvel[xi + yi1];
- Vector3 V010;
- V010.x = (float)mv.x;
- V010.y = (float)mv.y;
- V010.z = (float)mv.z;
- float omx = 1.0f - xr;
- float omy = 1.0f - yr;
- Vector3 Vxyz = V000 * omx * omy + V100 * xr * omy + V010 * omx * yr + V110 * xr * yr;
- Vxyz.x = ((Vxyz.x * oadj) - 0.5f) * maxval.x;
- Vxyz.y = ((Vxyz.y * oadj) - 0.5f) * maxval.y;
- Vxyz.z = 0.0f; //((Vxyz.z * oadj) - 0.5f) * maxval.z;
- return Vxyz;
- }
- }
|