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); }
// Flow source should be normalized void RunSim(int start, int end) { Vector3 tvel; Vector3 acc; Vector3 dir; float fvel = 0.0f; float falloff = 0.0f; int mframe = 0; Matrix4x4 ftm = invtm; Vector3 flowpos = Vector3.zero; for (int i = start; i < end; i++) { Vector3 pos = particles[i].position; Vector3 vel = particles[i].velocity; float duration = tdt; bool inbounds = true; // Not really correct to do here but it is close enough and will save a lot of cpu time //flowpos = msource.FindFlowPos(pos, ref inbounds, ref ftm, ref fvel); flowpos = msource.FindFlowPos(pos, ref inbounds, ref ftm, ref fvel, ref mframe, ref falloff); while (duration > 0.0001f) { if (inbounds) { Vector3 airvel = ftm.MultiplyVector(frame.GetGridVel(flowpos, ref inbounds)); if (inbounds) { float scl = scale * fvel * falloff; airvel.x *= scl; airvel.y *= scl; airvel.z *= scl; if (airvel.sqrMagnitude > 0.1f) { tvel.x = airvel.x - vel.x; tvel.y = airvel.y - vel.y; tvel.z = airvel.z - vel.z; float l = (tvel.x * tvel.x) + (tvel.y * tvel.y) + (tvel.z * tvel.z); if (l != 0.0f) { //Debug.Log("got one"); l = Mathf.Sqrt(l); float df = coef * l; l = 1.0f / l; dir.x = tvel.x * l; dir.y = tvel.y * l; dir.z = tvel.z * l; float dfm = df * oomass; acc.x = dir.x * dfm; acc.y = dir.y * dfm + gravity; acc.z = dir.z * dfm; vel.x += acc.x * usedt; vel.y += acc.y * usedt; vel.z += acc.z * usedt; pos.x += vel.x * usedt; pos.y += vel.y * usedt; pos.z += vel.z * usedt; } } else { vel.y += gravity * usedt; pos.y += vel.y * usedt; } } else { vel.y += gravity * usedt; pos.y += vel.y * usedt; } } else { vel.y += gravity * usedt; pos.y += vel.y * usedt; } duration -= usedt; } particles[i].position = pos; particles[i].velocity = vel; } }
void RunSim(int start, int end) { Vector3 tvel; Vector3 acc; Vector3 dir; if (interp && framealpha != 0.0f) { RunSimNew(start, end); return; } float scl = source.Scale * scale; for (int i = start; i < end; i++) { Vector3 pos = particles[i].position; Vector3 vel = particles[i].velocity; float duration = tdt; bool inbounds = true; Vector3 flowpos = tm.MultiplyPoint3x4(pos); while (duration > 0.0001f) { Vector3 airvel = invtm.MultiplyVector(frame.GetGridVel(flowpos, ref inbounds)); if (inbounds) { airvel.x *= scl; airvel.y *= scl; airvel.z *= scl; tvel.x = airvel.x - vel.x; tvel.y = airvel.y - vel.y; tvel.z = airvel.z - vel.z; float l = (tvel.x * tvel.x) + (tvel.y * tvel.y) + (tvel.z * tvel.z); if (l != 0.0f) { l = Mathf.Sqrt(l); float df = coef * l; l = 1.0f / l; dir.x = tvel.x * l; dir.y = tvel.y * l; dir.z = tvel.z * l; float dfm = df * oomass; acc.x = dir.x * dfm; acc.y = dir.y * dfm; acc.z = dir.z * dfm; vel.x += acc.x * usedt; vel.y += acc.y * usedt; vel.z += acc.z * usedt; } } pos.x += vel.x * usedt; pos.y += vel.y * usedt; pos.z += vel.z * usedt; duration -= usedt; } particles[i].position = pos; particles[i].velocity = vel; } }
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 Texture3D Create3DTexture(int width, int height, int depth, int frame) { MegaFlowFrame f = frames[frame]; if (width == 0 || height == 0 || depth == 0) { return(null); } width = Mathf.ClosestPowerOfTwo(width); height = Mathf.ClosestPowerOfTwo(height); depth = Mathf.ClosestPowerOfTwo(depth); Texture3D tex = new Texture3D(width, height, depth, TextureFormat.RGB24, false); tex.wrapMode = TextureWrapMode.Repeat; tex.anisoLevel = 0; Color[] cols = new Color[width * height * depth]; float max = 0.0f; for (int i = 0; i < f.vel.Count; i++) { float m = f.vel[i].sqrMagnitude; if (m > max) { max = m; } } float len = Mathf.Sqrt(max); Vector3 p; Color c = Color.white; bool inbounds = false; #if false for (int x = 0; x < width; x++) { p.x = ((float)x / (float)width) * f.size.x; for (int y = 0; y < height; y++) { p.y = ((float)y / (float)height) * f.size.y; for (int z = 0; z < depth; z++) { p.z = ((float)z / (float)depth) * f.size.z; Vector3 vel = f.GetGridVel(p, ref inbounds); vel /= len; c.r = (vel.x * 0.5f) + 0.5f; c.g = (vel.y * 0.5f) + 0.5f; c.b = (vel.z * 0.5f) + 0.5f; cols[(x * depth * height) + (z * height) + y] = c; } } } #endif int ix = 0; for (int z = 0; z < depth; z++) { p.z = ((float)z / (float)depth) * f.size.z; for (int y = 0; y < height; y++) { p.y = ((float)y / (float)height) * f.size.y; for (int x = 0; x < width; x++) { p.x = ((float)x / (float)width) * f.size.x; Vector3 vel = f.GetGridVel(p, ref inbounds); vel /= len; c.r = (vel.x * 0.5f) + 0.5f; c.g = (vel.y * 0.5f) + 0.5f; c.b = (vel.z * 0.5f) + 0.5f; cols[ix++] = c; } } } tex.SetPixels(cols); tex.Apply(); return(tex); }
public Vector3 GetGridVelWorld(Vector3 pos, ref bool inbounds) { return(invgettm.MultiplyVector(flow.GetGridVel(gettm.MultiplyPoint3x4(pos), ref inbounds) * Scale)); }