static void ParseFluid(MegaFlowFrame flow, MegaFlowXMLNode node) { for (int i = 0; i < node.values.Count; i++) { MegaFlowXMLValue val = node.values[i]; switch (val.name) { case "grid": { string[] vals = val.value.Split(','); flow.gridDim2[0] = int.Parse(vals[0]); flow.gridDim2[1] = int.Parse(vals[1]); flow.gridDim2[2] = int.Parse(vals[2]); break; } case "size": { string[] vals = val.value.Split(','); index = 0; Vector3 bmin = ReadV3(vals); Vector3 bmax = ReadV3(vals); flow.size = bmax - bmin; flow.gsize = flow.size; // griddim should have a name change flow.spacing.x = flow.size.x / flow.gridDim2[0]; flow.spacing.y = flow.size.y / flow.gridDim2[1]; flow.spacing.z = flow.size.z / flow.gridDim2[2]; flow.oos.x = 1.0f / flow.spacing.x; flow.oos.y = 1.0f / flow.spacing.y; flow.oos.z = 1.0f / flow.spacing.z; break; } default: Debug.Log("Unknown Fluid attribute " + val.name); break; } } for (int i = 0; i < node.children.Count; i++) { MegaFlowXMLNode n = (MegaFlowXMLNode)node.children[i]; switch (n.tagName) { case "Vel": ParseVel(flow, n); break; case "Force": break; case "Density": break; default: Debug.Log("Unknown Fluid node " + n.tagName); break; } } }
// NetCDF example /* * netCDF volume { * dimensions: * nx = 3; * ny = 3; * nz = 3; * * variables: * float field_data(nx, ny, nz); * * data: * field_data = * 0, 0, 0 * 0, 0, 0 * 0, 5, 0 * * 0, 0, 5 * 0, 0, 0 * 0, 0, 0 * * 5, 0, 0 * 0, 0, 0 * 0, 0, 0; * } */ static public void SaveNetCDF(MegaFlowFrame flow, string filename) { StreamWriter file = new StreamWriter(filename); file.Write("netCDF volume {\n"); file.Write("dimensions:\n"); file.Write("\tnx = " + flow.gridDim2[0].ToString("0.#####") + ";\n"); file.Write("\tny = " + flow.gridDim2[1].ToString("0.#####") + ";\n"); file.Write("\tnz = " + flow.gridDim2[2].ToString("0.#####") + ";\n"); file.Write("\nvariables:\n\t float field_data(nx, ny, nz);\n"); file.Write("\ndata:\n"); file.Write("\tfield_data =\n"); for (int z = 0; z < flow.gridDim2[2]; z++) { for (int y = 0; y < flow.gridDim2[1]; y++) { for (int x = 0; x < flow.gridDim2[0]; x++) { WriteV3Adj(file, flow.vel[(x * flow.gridDim2[2] * flow.gridDim2[1]) + ((flow.gridDim2[2] - z - 1) * flow.gridDim2[1]) + y]); } file.Write("\n"); } file.Write("\n\n"); } file.Write("}"); file.Close(); }
static public void SaveFGA(MegaFlowFrame flow, string filename) { StreamWriter file = new StreamWriter(filename); file.Write(flow.gridDim2[0].ToString("0.#####") + ","); file.Write(flow.gridDim2[1].ToString("0.#####") + ","); file.Write(flow.gridDim2[2].ToString("0.#####") + ","); Vector3 sz = flow.size * 0.5f; WriteV3(file, -sz); WriteV3(file, sz); for (int z = 0; z < flow.gridDim2[2]; z++) { for (int y = 0; y < flow.gridDim2[1]; y++) { for (int x = 0; x < flow.gridDim2[0]; x++) { WriteV3Adj(file, flow.vel[(x * flow.gridDim2[2] * flow.gridDim2[1]) + ((flow.gridDim2[2] - z - 1) * flow.gridDim2[1]) + y]); } } } file.Close(); }
static public void ParseSmoke(MegaFlowFrame flow, BinaryReader br) { if (ReadChunk(br)) { int count = br.ReadInt32(); while (count > 0) { ushort cw = br.ReadUInt16(); count--; if (cw == 0xffff) { ushort zc = br.ReadUInt16(); count--; for (int i = 0; i < zc; i++) { flow.smoke.Add(0.0f); } } else { float val = (float)cw / 65535.0f; //32768.0f; // / (float)cw; flow.smoke.Add(val); } } br.ReadSingle(); // val1 float } }
public void DestroyFrame(int f) { if (f >= 0 && f < frames.Count) { MegaFlowFrame frame = frames[f]; frames.RemoveAt(f); if (flow == frame) { if (frames.Count > 0) { flow = frames[0]; } else { flow = null; } } if (Application.isEditor) { DestroyImmediate(frame); } else { Destroy(frame); } } }
public void UpdateSim() { if (source && particle && source.frames.Count > 0) { frame = source.frames[framenum]; tdt = Time.deltaTime; //Matrix4x4 offtm = Matrix4x4.TRS(frame.size * 0.5f, Quaternion.identity, Vector3.one); Matrix4x4 offtm = Matrix4x4.TRS((frame.size * 0.5f) + frame.offset, Quaternion.identity, Vector3.one); tm = offtm * source.transform.worldToLocalMatrix; invtm = tm.inverse; float p = source.Density; float A = area; float Re = source.Reynolds; coef = 1.0f * p * A * Mathf.Pow(Re, -0.5f); t += Time.deltaTime; int count = particle.particleCount; particles = particle.particles; RunSim(0, count); particle.particles = particles; } }
void Update() { if ( source && target ) { flow = source.frames[framenum]; SaveFlowPosition(target.position, target.rotation, (target.position - lastpos) / Time.deltaTime, flowscale); lastpos = target.position; } }
void Update() { if (source && target) { flow = source.frames[framenum]; SaveFlowPosition(target.position, target.rotation, (target.position - lastpos) / Time.deltaTime, flowscale); lastpos = target.position; } }
public void SetFrame(int f) { if (msource && msource.source) { if (f >= 0 && f < msource.source.frames.Count) { frame = msource.source.frames[f]; framenum = f; } } }
public void SetFrame(int f) { if ( msource && msource.source ) { if ( f >= 0 && f < msource.source.frames.Count ) { frame = msource.source.frames[f]; framenum = f; } } }
public void SetFrame1(int f) { if ( source ) { if ( f >= 0 && f < source.frames.Count ) { frame1 = source.frames[f]; framenum1 = f; } } }
public void SetFrame(int f) { if (source) { if (f >= 0 && f < source.frames.Count) { frame = source.frames[f]; framenum = f; } } }
static public void LoadFGA(MegaFlowFrame flow, string filename) { StreamReader reader = File.OpenText(filename); string file = reader.ReadToEnd(); string[] vals = file.Split(','); index = 0; flow.gridDim2[0] = (int)float.Parse(vals[index++]); flow.gridDim2[1] = (int)float.Parse(vals[index++]); flow.gridDim2[2] = (int)float.Parse(vals[index++]); Vector3 bmin = ReadV3(vals); Vector3 bmax = ReadV3(vals); flow.size = bmax - bmin; flow.gsize = flow.size; // griddim should have a name change flow.spacing.x = flow.size.x / flow.gridDim2[0]; flow.spacing.y = flow.size.y / flow.gridDim2[1]; flow.spacing.z = flow.size.z / flow.gridDim2[2]; flow.oos.x = 1.0f / flow.spacing.x; flow.oos.y = 1.0f / flow.spacing.y; flow.oos.z = 1.0f / flow.spacing.z; //Debug.Log("spacing " + flow.spacing); //Debug.Log("griddim " + flow.gridDim2[0] + " " + flow.gridDim2[1] + " " + flow.gridDim2[2]); flow.vel.Clear(); Vector3[] vels = new Vector3[flow.gridDim2[0] * flow.gridDim2[1] * flow.gridDim2[2]]; for (int z = 0; z < flow.gridDim2[2]; z++) { for (int y = 0; y < flow.gridDim2[1]; y++) { for (int x = 0; x < flow.gridDim2[0]; x++) { vels[(x * flow.gridDim2[2] * flow.gridDim2[1]) + ((flow.gridDim2[2] - z - 1) * flow.gridDim2[1]) + y] = ReadV3Adj(vals); } } } flow.framenumber = 0; flow.vel.AddRange(vels); reader.Close(); reader = null; GC.Collect(); }
static public void Parse(MegaFlowFrame flow, BinaryReader br) { int head = br.ReadInt16(); // head val flow.framenumber = br.ReadInt32(); flow.fval = br.ReadSingle(); flow.spacing.x = br.ReadSingle(); flow.spacing.y = flow.spacing.x; flow.spacing.z = flow.spacing.x; flow.oos.x = 1.0f / flow.spacing.x; flow.oos.y = 1.0f / flow.spacing.y; flow.oos.z = 1.0f / flow.spacing.z; flow.size.x = br.ReadSingle(); flow.size.z = br.ReadSingle(); flow.size.y = br.ReadSingle(); flow.gsize.x = br.ReadSingle(); flow.gsize.z = br.ReadSingle(); flow.gsize.y = br.ReadSingle(); flow.gridDim[0] = br.ReadInt32(); flow.gridDim[2] = br.ReadInt32(); flow.gridDim[1] = br.ReadInt32(); flow.gridDim1[0] = br.ReadInt32(); flow.gridDim1[2] = br.ReadInt32(); flow.gridDim1[1] = br.ReadInt32(); flow.gridDim2[0] = br.ReadInt32(); flow.gridDim2[2] = br.ReadInt32(); flow.gridDim2[1] = br.ReadInt32(); flow.somebool = br.ReadBoolean(); flow.flags = br.ReadInt32(); if ( head == 31 ) br.ReadInt32(); flow.fval1 = br.ReadSingle(); if ( (flow.flags & 8) != 0 ) ParseSmoke(flow, br); else Debug.Log("No Smoke"); if ( (flow.flags & 0x20) != 0 ) ParseVelocity(flow, br); else Debug.Log("No Vel"); ParseGrid(flow, br); }
public static MegaFlowFrame LoadFrame(string filename) { MegaFlowFrame flow = null; if (File.Exists(filename)) { flow = ScriptableObject.CreateInstance <MegaFlowFrame>(); Load(flow, filename); } return(flow); }
static public void ParseXML1(MegaFlowFrame flow, MegaFlowXMLNode node) { foreach (MegaFlowXMLNode n in node.children) { switch (n.tagName) { case "Fluid": ParseFluid(flow, n); break; default: Debug.Log("Unknown Fluid Node " + n.tagName); break; } } }
public void OptimizeData() { for (int i = 0; i < frames.Count; i++) { MegaFlowFrame frame = frames[i]; if (frame.optvel == null || frame.optvel.Count == 0) { frame.Optimize(); } } CalcMemUse(); }
public static MegaFlowFrame LoadFrame(string filename) { MegaFlowFrame flow = null; //Debug.Log("FGA file " + filename); if (File.Exists(filename)) { flow = ScriptableObject.CreateInstance <MegaFlowFrame>(); flow.Init(); LoadFGA(flow, filename); } return(flow); }
public Vector3 GetVelocity(Vector3 pos) { if (source) { MegaFlowFrame frame = source.frames[framenum]; if (frame && frame.GetGridVel != null) { return(frame.GetGridVelWorld(pos, ref inbounds)); } } return(Vector3.zero); }
public void Resample(MegaFlowFrame sf, int gx, int gy, int gz) { MegaFlowFrame newf = ScriptableObject.CreateInstance <MegaFlowFrame>(); newf.gridDim2[0] = gx; newf.gridDim2[1] = gy; newf.gridDim2[2] = gz; newf.size = sf.size; newf.gsize = newf.size; // griddim should have a name change newf.spacing.x = newf.size.x / newf.gridDim2[0]; newf.spacing.y = newf.size.y / newf.gridDim2[1]; newf.spacing.z = newf.size.z / newf.gridDim2[2]; newf.oos.x = 1.0f / newf.spacing.x; newf.oos.y = 1.0f / newf.spacing.y; newf.oos.z = 1.0f / newf.spacing.z; float adjx = sf.spacing.x * 0.5f; float adjy = sf.spacing.y * 0.5f; float adjz = sf.spacing.z * 0.5f; bool inbounds = false; Prepare(); Vector3[] cells = new Vector3[gx * gy * gz]; Vector3 p; for (int x = 0; x < gx; x++) { p.x = (((float)x / (float)gx) * sf.size.x) + adjx; for (int y = 0; y < gy; y++) { p.y = (((float)y / (float)gy) * sf.size.y) + adjy; for (int z = 0; z < gz; z++) { p.z = (((float)z / (float)gz) * sf.size.z) + adjz; cells[(x * gz * gy) + (z * gy) + y] = sf.GetGridVel(p, ref inbounds); } } } newf.vel.AddRange(cells); AddFrame(newf); }
public void SetFrame(int f) { if (frames.Count > 0) { f = Mathf.Clamp(f, 0, frames.Count - 1); flow = frames[f]; frame = f; } else { frame = 0; flow = null; } }
static public void Load(MegaFlowFrame flow, string filename) { FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, System.IO.FileShare.Read); BinaryReader br = new BinaryReader(fs); if ( br != null ) { flow.Init(); Parse(flow, br); br.Close(); } fs.Close(); }
static public void LoadFLW(MegaFlowFrame flow, string filename) { StreamReader streamReader = new StreamReader(filename); string data = streamReader.ReadToEnd(); streamReader.Close(); MegaFlowXMLReader xml = new MegaFlowXMLReader(); MegaFlowXMLNode node = xml.read(data); ParseXML1(flow, node); xml = null; data = null; GC.Collect(); }
static public void Load(MegaFlowFrame flow, string filename) { FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, System.IO.FileShare.Read); BinaryReader br = new BinaryReader(fs); if (br != null) { flow.Init(); Parse(flow, br); br.Close(); } fs.Close(); }
public void AddFrame(MegaFlowFrame frame) { if (frame) { if (frames == null) { frames = new List <MegaFlowFrame>(); } frames.Add(frame); if (flow == null) { flow = frame; } } }
public static MegaFlowFrame LoadFrame(string filename, int frame) { MegaFlowFrame flow = null; char[] splits = { '_' }; string fname = filename; // use unity get path string[] names = fname.Split(splits); if (names.Length > 0) { string newfname = names[0] + "_" + frame.ToString("0000") + ".fxd"; flow = LoadFrame(newfname); } return(flow); }
void Update() { if (source && particle && source.frames.Count > 0) { //tdt = Time.deltaTime; //tm = source.transform.worldToLocalMatrix; //invtm = source.transform.localToWorldMatrix; framenum = Mathf.Clamp(framenum, 0, source.frames.Count - 1); frame = source.frames[framenum]; framenum1 = Mathf.Clamp(framenum1, 0, source.frames.Count - 1); frame1 = source.frames[framenum1]; source.Prepare(); tdt = Time.deltaTime; //Matrix4x4 offtm = Matrix4x4.TRS(frame.size * 0.5f, Quaternion.identity, Vector3.one); Matrix4x4 offtm = Matrix4x4.TRS((frame.size * 0.5f) + frame.offset, Quaternion.identity, Vector3.one); tm = offtm * source.transform.worldToLocalMatrix; invtm = tm.inverse; offtm = Matrix4x4.TRS((frame1.size * 0.5f) + frame1.offset, Quaternion.identity, Vector3.one); tm1 = offtm * source.transform.worldToLocalMatrix; invtm1 = tm1.inverse; float p = source.Density; float A = Area; float Re = source.Reynolds; coef = 1.0f * p * A * Mathf.Pow(Re, -0.5f); t += Time.deltaTime; int count = particle.particleCount; particles = particle.particles; RunSim(0, count); particle.particles = particles; } }
public void DrawMoveGizmo() { if (source) { flow = source.frames[framenum]; } if (flow) { Matrix4x4 offtm = Matrix4x4.TRS(-flow.size * 0.5f, Quaternion.identity, Vector3.one); framegizmotm = transform.localToWorldMatrix * offtm; Gizmos.matrix = framegizmotm; Vector3 min = Vector3.zero; Vector3 max = flow.size; MegaFlow.DrawBox(min, max); Gizmos.matrix = Matrix4x4.identity; } }
public void CalcMemUse() { memoryuse = 0; for (int i = 0; i < frames.Count; i++) { MegaFlowFrame frame = frames[i]; if (frame.optimized) { frame.memory = frame.gridDim2[0] * frame.gridDim2[1] * frame.gridDim2[2] * 3; } else { frame.memory = frame.gridDim2[0] * frame.gridDim2[1] * frame.gridDim2[2] * 12; } memoryuse += frame.memory; } }
public void DestroyFrames() { flow = null; for (int i = 0; i < frames.Count; i++) { MegaFlowFrame frame = frames[i]; if (Application.isEditor) { DestroyImmediate(frame); } else { Destroy(frame); } } frames.Clear(); GC.Collect(); }
public void NormalizeFrame(int f) { MegaFlowFrame fr = frames[f]; float max = 0.0f; for (int i = 0; i < fr.vel.Count; i++) { float vs = fr.vel[i].magnitude; if (vs > max) { max = vs; } } for (int i = 0; i < fr.vel.Count; i++) { fr.vel[i] = fr.vel[i] / max; } }
void Update() { if (frames.Count > 0) { Animate(); frame = Mathf.Clamp(frame, 0, frames.Count - 1); flow = frames[frame]; if (flow.SampleVel == null) { if (flow.optimized) { if (flow.gridDim2[2] == 1) { flow.SampleVel = flow.SampleVelOpt; flow.GetGridVel = flow.GetGridVelOptXY; } else { flow.SampleVel = flow.SampleVelOpt; flow.GetGridVel = flow.GetGridVelOpt; } } else { if (flow.gridDim2[2] == 1) { flow.SampleVel = flow.SampleVelFloat; flow.GetGridVel = flow.GetGridVelFloatXY; } else { flow.SampleVel = flow.SampleVelFloat; flow.GetGridVel = flow.GetGridVelFloat; } } } } }
public static MegaFlowFrame LoadFrame(string filename, int frame, string namesplit) { int decformat = 0; MegaFlowFrame flow = null; string dir = Path.GetDirectoryName(filename); string file = Path.GetFileNameWithoutExtension(filename); file = MegaFlowFGA.MakeFileName(file, ref decformat); #if false char[] splits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; string[] names; if (namesplit.Length > 0) { names = file.Split(namesplit[0]); names[0] += namesplit[0]; } else { names = file.Split(splits); } if (names.Length > 0) { string newfname = dir + "/" + names[0] + frame.ToString("0000") + ".fxd"; flow = LoadFrame(newfname); } #else if (file.Length > 0) { string newfname = dir + "/" + file + frame.ToString("D" + decformat) + ".fxd"; flow = LoadFrame(newfname); } #endif return(flow); }
static void ParseVel(MegaFlowFrame flow, MegaFlowXMLNode node) { for (int i = 0; i < node.values.Count; i++) { MegaFlowXMLValue val = node.values[i]; switch (val.name) { case "data": { string[] vals = val.value.Split(','); index = 0; //int len = vals.Length / 3; flow.vel.Clear(); Vector3[] vels = new Vector3[flow.gridDim2[0] * flow.gridDim2[1] * flow.gridDim2[2]]; for (int z = 0; z < flow.gridDim2[2]; z++) { for (int y = 0; y < flow.gridDim2[1]; y++) { for (int x = 0; x < flow.gridDim2[0]; x++) { vels[(x * flow.gridDim2[2] * flow.gridDim2[1]) + ((flow.gridDim2[2] - z - 1) * flow.gridDim2[1]) + y] = ReadV3Adj(vals); } } } flow.framenumber = 0; flow.vel.AddRange(vels); break; } default: Debug.Log("Unknown Vel attribute " + val.name); break; } } }
static public void ParseGrid(MegaFlowFrame flow, BinaryReader br) { #if false if (ReadChunk(br)) { for (int i = 0; i < flow.gridDim[0] * flow.gridDim[1] * flow.gridDim[2]; i++) { flow.grid.Add(0); } int length = br.ReadInt32(); byte[] data = br.ReadBytes(length); int index = 0; int si = 0; while (si < length) { byte ch = data[si++]; if (si >= length) { break; } if (ch == 255) { index += data[si++]; } else { flow.grid[index] = ch; } } } #endif }
static public void LoadFGA(MegaFlowFrame flow, string filename) { StreamReader reader = File.OpenText(filename); string file = reader.ReadToEnd(); string[] vals = file.Split(','); index = 0; flow.gridDim2[0] = int.Parse(vals[index++]); flow.gridDim2[1] = int.Parse(vals[index++]); flow.gridDim2[2] = int.Parse(vals[index++]); Vector3 bmin = ReadV3(vals); Vector3 bmax = ReadV3(vals); flow.size = bmax - bmin; flow.gsize = flow.size; // griddim should have a name change flow.spacing.x = flow.size.x / flow.gridDim2[0]; flow.spacing.y = flow.size.y / flow.gridDim2[1]; flow.spacing.z = flow.size.z / flow.gridDim2[2]; flow.oos.x = 1.0f / flow.spacing.x; flow.oos.y = 1.0f / flow.spacing.y; flow.oos.z = 1.0f / flow.spacing.z; //Debug.Log("spacing " + flow.spacing); //Debug.Log("griddim " + flow.gridDim2[0] + " " + flow.gridDim2[1] + " " + flow.gridDim2[2]); flow.vel.Clear(); Vector3[] vels = new Vector3[flow.gridDim2[0] * flow.gridDim2[1] * flow.gridDim2[2]]; for ( int z = 0; z < flow.gridDim2[2]; z++ ) { for ( int y = 0; y < flow.gridDim2[1]; y++ ) { for ( int x = 0; x < flow.gridDim2[0]; x++ ) vels[(x * flow.gridDim2[2] * flow.gridDim2[1]) + ((flow.gridDim2[2] - z - 1) * flow.gridDim2[1]) + y] = ReadV3Adj(vals); } } flow.framenumber = 0; flow.vel.AddRange(vels); reader.Close(); reader = null; GC.Collect(); }
// ff = do next byte of zeros then read words till // 7fff = do next word of zeros // Guess any shortfall in length is padded with zeroes static public void ParseVelocity(MegaFlowFrame flow, BinaryReader br) { int len = flow.gridDim2[0] * flow.gridDim2[1] * flow.gridDim2[2]; for ( int j = 0; j < 3; j++ ) { if ( ReadChunk(br) ) { int count = br.ReadInt32(); int index = 0; while ( count > 0 ) { ushort data = br.ReadUInt16(); count--; if ( data == 0x7fff ) { ushort zc = br.ReadUInt16(); count--; for ( int z = 0; z < zc; z++ ) { if ( j == 0 ) { flow.vel.Add(Vector3.zero); index++; } else { Vector3 v = flow.vel[index]; switch ( j ) { case 0: v.x = 0.0f; break; case 1: v.z = 0.0f; break; case 2: v.y = 0.0f; break; } flow.vel[index++] = v; } } } else { short v = (short)data; float val = (float)v / 32767.0f; //32768.0f if ( j == 0 ) { flow.vel.Add(new Vector3(val, 0.0f, 0.0f)); index++; } else { Vector3 v1 = flow.vel[index]; switch ( j ) { case 0: v1.x = val; break; case 1: v1.z = val; break; case 2: v1.y = val; break; } flow.vel[index++] = v1; } } } for ( int p = index; p < len; p++ ) { if ( j == 0 ) { flow.vel.Add(Vector3.zero); index++; } else { Vector3 v1 = flow.vel[index]; switch ( j ) { case 0: v1.x = 0.0f; break; case 1: v1.z = 0.0f; break; case 2: v1.y = 0.0f; break; } flow.vel[index++] = v1; } } } } }
static public void ParseForce(MegaFlowFrame flow, BinaryReader br) { }
static public void SaveFGA(MegaFlowFrame flow, string filename) { StreamWriter file = new StreamWriter(filename); file.Write(flow.gridDim2[0].ToString("0.#####") + ","); file.Write(flow.gridDim2[1].ToString("0.#####") + ","); file.Write(flow.gridDim2[2].ToString("0.#####") + ","); Vector3 sz = flow.size * 0.5f; WriteV3(file, -sz); WriteV3(file, sz); for ( int z = 0; z < flow.gridDim2[2]; z++ ) { for ( int y = 0; y < flow.gridDim2[1]; y++ ) { for ( int x = 0; x < flow.gridDim2[0]; x++ ) WriteV3Adj(file, flow.vel[(x * flow.gridDim2[2] * flow.gridDim2[1]) + ((flow.gridDim2[2] - z - 1) * flow.gridDim2[1]) + y]); } } file.Close(); }
void Update() { if ( source && source.frames.Count > 0 ) { framenum = Mathf.Clamp(framenum, 0, source.frames.Count - 1); frame = source.frames[framenum]; float scl = source.Scale * scale; Vector3 Fshape = Vector3.zero; // Random force due to particle shape Vector3 Fgrv = new Vector3(0.0f, -Gravity, 0.0f); float duration = Time.deltaTime; pos = transform.position; bool inbounds = true; float p = density; float A = Area; float Re = reynolds; float coef = 1.0f * p * A * Mathf.Pow(Re, -0.5f); Vector3 flowpos = pos; //source.transform.worldToLocalMatrix.MultiplyPoint3x4(pos); // This should be in source already //Matrix4x4 offtm = Matrix4x4.TRS((frame.size * 0.5f) + frame.offset, Quaternion.identity, Vector3.one); //Matrix4x4 tm = offtm * source.transform.worldToLocalMatrix; //Matrix4x4 invtm = tm.inverse; Vector3 airvel = Vector3.zero; while ( duration > 0.0f ) { //Vector3 airvel = invtm.MultiplyVector(frame.GetGridVel(tm.MultiplyPoint3x4(flowpos), ref inbounds) * scl); airvel = frame.GetGridVelWorld(flowpos, ref inbounds) * scl; //invtm.MultiplyVector(frame.GetGridVel(tm.MultiplyPoint3x4(flowpos), ref inbounds) * scl); if ( !inbounds ) { airvel = new Vector3(scale, 0.0f, 0.0f); flowpos += vel * dt; } else { Vector3 tvel = airvel - vel; float U = tvel.magnitude; float df = coef * U; Vector3 dir = tvel.normalized; Vector3 Fdrag = dir * df; Vector3 Fp = Fdrag + Fshape + Fgrv; Vector3 acc = Fp / mass; vel += acc * dt; flowpos += vel * dt; } duration -= dt; } if ( flowpos.y < source.floor ) flowpos.y = source.floor; transform.position = flowpos; //source.transform.localToWorldMatrix.MultiplyPoint3x4(flowpos); rot += rotspeed * Time.deltaTime; Quaternion r = Quaternion.Euler(rot); Vector3 fdir = flowpos - pos; switch ( align ) { case MegaFlowAlign.Flow: { r = Quaternion.identity; Quaternion ar = lastalign; if ( airvel != Vector3.zero ) ar = Quaternion.LookRotation(airvel) * Quaternion.Euler(alignrot); r = r * ar; lastalign = ar; } break; case MegaFlowAlign.Object: { r = Quaternion.identity; Quaternion ar = lastalign; if ( fdir != Vector3.zero ) ar = Quaternion.LookRotation(fdir) * Quaternion.Euler(alignrot); r = r * ar; lastalign = ar; } break; } #if false if ( align ) { r = Quaternion.identity; Quaternion ar = lastalign; if ( fdir != Vector3.zero ) ar = Quaternion.LookRotation(flowpos - pos) * Quaternion.Euler(alignrot); r = r * ar; lastalign = ar; } #endif transform.rotation = r; //Quaternion.Euler(r); //ot); if ( usegradient ) { if ( !mat ) { Renderer rend = GetComponent<Renderer>(); if ( rend && rend.material ) mat = rend.material; } if ( mat ) { float spd = airvel.magnitude; float a = Mathf.Clamp01((spd - speedlow) / (speedhigh - speedlow)); mat.color = gradient.Evaluate(a); } } } if ( rend1 == null ) rend1 = GetComponent<Renderer>(); if ( rend1 && !rend1.enabled ) rend1.enabled = true; }
public void SetFrame(int f) { if ( frames.Count > 0 ) { f = Mathf.Clamp(f, 0, frames.Count - 1); flow = frames[f]; frame = f; } else { frame = 0; flow = null; } }
void Update() { if ( msource && msource.source && particle ) { msource.framenum = framenum; framenum = Mathf.Clamp(framenum, 0, msource.source.frames.Count - 1); frame = msource.source.frames[framenum]; msource.source.Prepare(); tdt = Time.deltaTime; Matrix4x4 offtm = Matrix4x4.TRS(frame.size * 0.5f, Quaternion.identity, Vector3.one); tm = offtm * msource.source.transform.worldToLocalMatrix; invtm = tm.inverse; float p = msource.source.Density; float A = area; float Re = msource.source.Reynolds; oomass = 1.0f / mass; coef = 1.0f * p * A * Mathf.Pow(Re, -0.5f); usedt = dt; if ( usedt > tdt ) usedt = tdt; int count = particle.GetParticles(particles); if ( !UseThreading || Cores < 1 || !Application.isPlaying ) RunSim(0, count); else { if ( Cores == 0 ) Cores = SystemInfo.processorCount - 1; if ( tasks == null ) MakeThreads(); int step = count / (Cores + 1); if ( Cores > 0 ) { int index = step; for ( int i = 0; i < tasks.Length; i++ ) { tasks[i].start = index; tasks[i].end = index + step; index += step; } tasks[Cores - 1].end = count; for ( int i = 0; i < tasks.Length; i++ ) tasks[i].pauseevent.Set(); } RunSim(0, step); WaitJobs(); } particle.SetParticles(particles, count); } }
public void DestroyFrame(int f) { if ( f >= 0 && f < frames.Count ) { MegaFlowFrame frame = frames[f]; frames.RemoveAt(f); if ( flow == frame ) { if ( frames.Count > 0 ) flow = frames[0]; else flow = null; } if ( Application.isEditor ) DestroyImmediate(frame); else Destroy(frame); } }
static public void ParseSmoke(MegaFlowFrame flow, BinaryReader br) { if ( ReadChunk(br) ) { int count = br.ReadInt32(); while ( count > 0 ) { ushort cw = br.ReadUInt16(); count--; if ( cw == 0xffff ) { ushort zc = br.ReadUInt16(); count--; for ( int i = 0; i < zc; i++ ) flow.smoke.Add(0.0f); } else { float val = (float)cw / 65535.0f; //32768.0f; // / (float)cw; flow.smoke.Add(val); } } br.ReadSingle(); // val1 float } }
void Update() { if ( source && particle && source.frames.Count > 0 ) { //tdt = Time.deltaTime; //tm = source.transform.worldToLocalMatrix; //invtm = source.transform.localToWorldMatrix; framenum = Mathf.Clamp(framenum, 0, source.frames.Count - 1); frame = source.frames[framenum]; framenum1 = Mathf.Clamp(framenum1, 0, source.frames.Count - 1); frame1 = source.frames[framenum1]; source.Prepare(); tdt = Time.deltaTime; //Matrix4x4 offtm = Matrix4x4.TRS(frame.size * 0.5f, Quaternion.identity, Vector3.one); Matrix4x4 offtm = Matrix4x4.TRS((frame.size * 0.5f) + frame.offset, Quaternion.identity, Vector3.one); tm = offtm * source.transform.worldToLocalMatrix; invtm = tm.inverse; offtm = Matrix4x4.TRS((frame1.size * 0.5f) + frame1.offset, Quaternion.identity, Vector3.one); tm1 = offtm * source.transform.worldToLocalMatrix; invtm1 = tm1.inverse; float p = source.Density; float A = Area; float Re = source.Reynolds; coef = 1.0f * p * A * Mathf.Pow(Re, -0.5f); t += Time.deltaTime; int count = particle.particleCount; particles = particle.particles; RunSim(0, count); particle.particles = particles; } }
public void AddFrame(MegaFlowFrame frame) { if ( frame ) { if ( frames == null ) frames = new List<MegaFlowFrame>(); frames.Add(frame); if ( flow == null ) flow = frame; } }
public void DestroyFrames() { flow = null; for ( int i = 0; i < frames.Count; i++ ) { MegaFlowFrame frame = frames[i]; if ( Application.isEditor ) DestroyImmediate(frame); else Destroy(frame); } frames.Clear(); GC.Collect(); }
static void ParseVel(MegaFlowFrame flow, MegaFlowXMLNode node) { for ( int i = 0; i < node.values.Count; i++ ) { MegaFlowXMLValue val = node.values[i]; switch ( val.name ) { case "data": { string[] vals = val.value.Split(','); index = 0; //int len = vals.Length / 3; flow.vel.Clear(); Vector3[] vels = new Vector3[flow.gridDim2[0] * flow.gridDim2[1] * flow.gridDim2[2]]; for ( int z = 0; z < flow.gridDim2[2]; z++ ) { for ( int y = 0; y < flow.gridDim2[1]; y++ ) { for ( int x = 0; x < flow.gridDim2[0]; x++ ) vels[(x * flow.gridDim2[2] * flow.gridDim2[1]) + ((flow.gridDim2[2] - z - 1) * flow.gridDim2[1]) + y] = ReadV3Adj(vals); } } flow.framenumber = 0; flow.vel.AddRange(vels); break; } default: Debug.Log("Unknown Vel attribute " + val.name); break; } } }
public void UpdateSim() { if ( source && particle && source.frames.Count > 0 ) { frame = source.frames[framenum]; tdt = Time.deltaTime; //Matrix4x4 offtm = Matrix4x4.TRS(frame.size * 0.5f, Quaternion.identity, Vector3.one); Matrix4x4 offtm = Matrix4x4.TRS((frame.size * 0.5f) + frame.offset, Quaternion.identity, Vector3.one); tm = offtm * source.transform.worldToLocalMatrix; invtm = tm.inverse; float p = source.Density; float A = area; float Re = source.Reynolds; coef = 1.0f * p * A * Mathf.Pow(Re, -0.5f); t += Time.deltaTime; int count = particle.particleCount; particles = particle.particles; RunSim(0, count); particle.particles = particles; } }
void Update() { if ( frames.Count > 0 ) { Animate(); frame = Mathf.Clamp(frame, 0, frames.Count - 1); flow = frames[frame]; if ( flow.SampleVel == null ) { if ( flow.optimized ) { flow.SampleVel = flow.SampleVelOpt; flow.GetGridVel = flow.GetGridVelOpt; } else { flow.SampleVel = flow.SampleVelFloat; flow.GetGridVel = flow.GetGridVelFloat; } } } }
static public void ParseGrid(MegaFlowFrame flow, BinaryReader br) { if ( ReadChunk(br) ) { for ( int i = 0; i < flow.gridDim[0] * flow.gridDim[1] * flow.gridDim[2]; i++ ) flow.grid.Add(0); int length = br.ReadInt32(); byte[] data = br.ReadBytes(length); int index = 0; int si = 0; while ( si < length ) { byte ch = data[si++]; if ( si >= length ) break; if ( ch == 255 ) index += data[si++]; else flow.grid[index] = ch; } } }
static public void ParseXML1(MegaFlowFrame flow, MegaFlowXMLNode node) { foreach ( MegaFlowXMLNode n in node.children ) { switch ( n.tagName ) { case "Fluid": ParseFluid(flow, n); break; default: Debug.Log("Unknown Fluid Node " + n.tagName); break; } } }
void Update() { if ( msource && msource.source && particle ) { msource.framenum = framenum; framenum = Mathf.Clamp(framenum, 0, msource.source.frames.Count - 1); frame = msource.source.frames[framenum]; source.Prepare(); tdt = Time.deltaTime; Matrix4x4 offtm = Matrix4x4.TRS(frame.size * 0.5f, Quaternion.identity, Vector3.one); tm = offtm * msource.source.transform.worldToLocalMatrix; invtm = tm.inverse; float p = msource.source.Density; float A = area; float Re = msource.source.Reynolds; oomass = 1.0f / mass; coef = 1.0f * p * A * Mathf.Pow(Re, -0.5f); usedt = dt; if ( usedt > tdt ) usedt = tdt; int count = particle.GetParticles(particles); RunSim(0, count); particle.SetParticles(particles, count); } }
static void ParseFluid(MegaFlowFrame flow, MegaFlowXMLNode node) { for ( int i = 0; i < node.values.Count; i++ ) { MegaFlowXMLValue val = node.values[i]; switch ( val.name ) { case "grid": { string[] vals = val.value.Split(','); flow.gridDim2[0] = int.Parse(vals[0]); flow.gridDim2[1] = int.Parse(vals[1]); flow.gridDim2[2] = int.Parse(vals[2]); break; } case "size": { string[] vals = val.value.Split(','); index = 0; Vector3 bmin = ReadV3(vals); Vector3 bmax = ReadV3(vals); flow.size = bmax - bmin; flow.gsize = flow.size; // griddim should have a name change flow.spacing.x = flow.size.x / flow.gridDim2[0]; flow.spacing.y = flow.size.y / flow.gridDim2[1]; flow.spacing.z = flow.size.z / flow.gridDim2[2]; flow.oos.x = 1.0f / flow.spacing.x; flow.oos.y = 1.0f / flow.spacing.y; flow.oos.z = 1.0f / flow.spacing.z; break; } default: Debug.Log("Unknown Fluid attribute " + val.name); break; } } for ( int i = 0; i < node.children.Count; i++ ) { MegaFlowXMLNode n = (MegaFlowXMLNode)node.children[i]; switch ( n.tagName ) { case "Vel": ParseVel(flow, n); break; case "Force": break; case "Density": break; default: Debug.Log("Unknown Fluid node " + n.tagName); break; } } }
public void DrawMoveGizmo() { if ( source ) flow = source.frames[framenum]; if ( flow ) { Matrix4x4 offtm = Matrix4x4.TRS(-flow.size * 0.5f, Quaternion.identity, Vector3.one); framegizmotm = transform.localToWorldMatrix * offtm; Gizmos.matrix = framegizmotm; Vector3 min = Vector3.zero; Vector3 max = flow.size; MegaFlow.DrawBox(min, max); Gizmos.matrix = Matrix4x4.identity; } }
public void Resample(MegaFlowFrame sf, int gx, int gy, int gz) { MegaFlowFrame newf = ScriptableObject.CreateInstance<MegaFlowFrame>(); newf.gridDim2[0] = gx; newf.gridDim2[1] = gy; newf.gridDim2[2] = gz; newf.size = sf.size; newf.gsize = newf.size; // griddim should have a name change newf.spacing.x = newf.size.x / newf.gridDim2[0]; newf.spacing.y = newf.size.y / newf.gridDim2[1]; newf.spacing.z = newf.size.z / newf.gridDim2[2]; newf.oos.x = 1.0f / newf.spacing.x; newf.oos.y = 1.0f / newf.spacing.y; newf.oos.z = 1.0f / newf.spacing.z; float adjx = sf.spacing.x * 0.5f; float adjy = sf.spacing.y * 0.5f; float adjz = sf.spacing.z * 0.5f; bool inbounds = false; Prepare(); Vector3[] cells = new Vector3[gx * gy * gz]; Vector3 p; for ( int x = 0; x < gx; x++ ) { p.x = (((float)x / (float)gx) * sf.size.x) + adjx; for ( int y = 0; y < gy; y++ ) { p.y = (((float)y / (float)gy) * sf.size.y) + adjy; for ( int z = 0; z < gz; z++ ) { p.z = (((float)z / (float)gz) * sf.size.z) + adjz; cells[(x * gz * gy) + (z * gy) + y] = sf.GetGridVel(p, ref inbounds); } } } newf.vel.AddRange(cells); AddFrame(newf); }