private void PartialAdvectCenter(int x0, int y0, int width, int height, float delta, Vector2 pos) { for (int x = x0; x < x0 + width; x++) { for (int y = y0; y < y0 + height; y++) { if (OldDensity[x, y].LengthSquared() > 1) { var velocity = fluidSystem.VelocityAt( pos + (new Vector2(x, y) * Resolution)) * VISCOSITY; // This is ran in parallel, this may not touch the other compound clouds float dx = x + (delta * velocity.x); float dy = y + (delta * velocity.y); // So this is clamped to not go to the other clouds dx = dx.Clamp(x0 - 0.5f, x0 + width + 0.5f); dy = dy.Clamp(y0 - 0.5f, y0 + height + 0.5f); CalculateMovementFactors(dx, dy, out var q0, out var q1, out var r0, out var r1, out var s1, out var s0, out var t1, out var t0); Density[q0, r0] += OldDensity[x, y] * s0 * t0; Density[q0, r1] += OldDensity[x, y] * s0 * t1; Density[q1, r0] += OldDensity[x, y] * s1 * t0; Density[q1, r1] += OldDensity[x, y] * s1 * t1; } } } }
private void PartialAdvectCenter(int x0, int y0, int width, int height, float delta, Vector2 pos) { for (int x = x0; x < x0 + width; x++) { for (int y = y0; y < y0 + height; y++) { if (OldDensity[x, y].LengthSquared() > 1) { // TODO: give each cloud a viscosity value in the // JSON file and use it instead. const float viscosity = 0.0525f; var velocity = fluidSystem.VelocityAt( pos + (new Vector2(x, y) * Resolution)) * viscosity; // This is ran in parallel, this may not touch the other compound clouds float dx = x + (delta * velocity.x); float dy = y + (delta * velocity.y); // So this is clamped to not go to the other clouds dx = dx.Clamp(x0 - 0.5f, x0 + width + 0.5f); dy = dy.Clamp(y0 - 0.5f, y0 + height + 0.5f); int q0 = (int)Math.Floor(dx); int q1 = q0 + 1; int r0 = (int)Math.Floor(dy); int r1 = r0 + 1; float s1 = Math.Abs(dx - q0); float s0 = 1.0f - s1; float t1 = Math.Abs(dy - r0); float t0 = 1.0f - t1; Density[q0, r0] += OldDensity[x, y] * s0 * t0; Density[q0, r1] += OldDensity[x, y] * s0 * t1; Density[q1, r0] += OldDensity[x, y] * s1 * t0; Density[q1, r1] += OldDensity[x, y] * s1 * t1; } } } }
private void PartialAdvectCenter(int x0, int y0, int width, int height, float delta, Vector2 pos) { for (int x = x0; x < x0 + width; x++) { for (int y = y0; y < y0 + height; y++) { if (OldDensity[x, y].LengthSquared() > 1) { var velocity = fluidSystem.VelocityAt( pos + (new Vector2(x, y) * Resolution)) * VISCOSITY; // This is ran in parallel, this may not touch the other compound clouds float dx = x + (delta * velocity.x); float dy = y + (delta * velocity.y); // So this is clamped to not go to the other clouds dx = dx.Clamp(x0 - 0.5f, x0 + width + 0.5f); dy = dy.Clamp(y0 - 0.5f, y0 + height + 0.5f); CalculateMovementFactors(dx, dy, out var q0, out var q1, out var r0, out var r1, out var s1, out var s0, out var t1, out var t0); // NOTE: we add modulo to avoid overflow due to large time steps // This makes this function a duplicate of PartialAdvectEdges // TODO: check for refactorization (and in general of the whole file) --Maxonovien q0 = q0.PositiveModulo(Size); q1 = q1.PositiveModulo(Size); r0 = r0.PositiveModulo(Size); r1 = r1.PositiveModulo(Size); Density[q0, r0] += OldDensity[x, y] * s0 * t0; Density[q0, r1] += OldDensity[x, y] * s0 * t1; Density[q1, r0] += OldDensity[x, y] * s1 * t0; Density[q1, r1] += OldDensity[x, y] * s1 * t1; } } } }
private void Advect(float[,] oldDens, float[,] density, float dt, Vector2 pos) { for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { density[x, y] = 0; } } for (int x = 1; x < size - 1; x++) { for (int y = 1; y < size - 1; y++) { if (oldDens[x, y] > 1) { // TODO: give each cloud a viscosity value in the // JSON file and use it instead. const float viscosity = 0.0525f; var velocity = fluidSystem.VelocityAt( pos + (new Vector2(x, y) * resolution)) * viscosity; float dx = x + (dt * velocity.x); float dy = y + (dt * velocity.y); dx = dx.Clamp(0.5f, size - 1.5f); dy = dy.Clamp(0.5f, size - 1.5f); int x0 = (int)dx; int x1 = x0 + 1; int y0 = (int)dy; int y1 = y0 + 1; float s1 = dx - x0; float s0 = 1.0f - s1; float t1 = dy - y0; float t0 = 1.0f - t1; density[x0, y0] += oldDens[x, y] * s0 * t0; density[x0, y1] += oldDens[x, y] * s0 * t1; density[x1, y0] += oldDens[x, y] * s1 * t0; density[x1, y1] += oldDens[x, y] * s1 * t1; } } } }
public void AdvectEdges(float delta, Vector2 pos) { int[] edgeValues = { 0, size - 1 }; for (int x = 0; x < size; x++) { // The top edge and bottom edge foreach (int y in edgeValues) { // This code is inlined here to improve performance if (OldDensity[x, y] > 1) { // TODO: give each cloud a viscosity value in the // JSON file and use it instead. const float viscosity = 0.0525f; var velocity = fluidSystem.VelocityAt( pos + (new Vector2(x, y) * resolution)) * viscosity; float dx = x + delta * velocity.x; float dy = y + delta * velocity.y; int x0 = (int)Math.Floor(dx); int x1 = x0 + 1; int y0 = (int)Math.Floor(dy); int y1 = y0 + 1; float s1 = Math.Abs(dx - x0); float s0 = 1.0f - s1; float t1 = Math.Abs(dy - y0); float t0 = 1.0f - t1; parentPlane.AddCloudDensity(index, x0, y0, OldDensity[x, y] * s0 * t0); parentPlane.AddCloudDensity(index, x0, y1, OldDensity[x, y] * s0 * t1); parentPlane.AddCloudDensity(index, x1, y0, OldDensity[x, y] * s1 * t0); parentPlane.AddCloudDensity(index, x1, y1, OldDensity[x, y] * s1 * t1); } } } // The left edge and right edge foreach (int x in edgeValues) { for (int y = 1; y < size - 1; y++) { // This code is inlined here to improve performance if (OldDensity[x, y] > 1) { // TODO: give each cloud a viscosity value in the // JSON file and use it instead. const float viscosity = 0.0525f; var velocity = fluidSystem.VelocityAt( pos + (new Vector2(x, y) * resolution)) * viscosity; float dx = x + delta * velocity.x; float dy = y + delta * velocity.y; int x0 = (int)Math.Floor(dx); int x1 = x0 + 1; int y0 = (int)Math.Floor(dy); int y1 = y0 + 1; float s1 = Math.Abs(dx - x0); float s0 = 1.0f - s1; float t1 = Math.Abs(dy - y0); float t0 = 1.0f - t1; parentPlane.AddCloudDensity(index, x0, y0, OldDensity[x, y] * s0 * t0); parentPlane.AddCloudDensity(index, x0, y1, OldDensity[x, y] * s0 * t1); parentPlane.AddCloudDensity(index, x1, y0, OldDensity[x, y] * s1 * t0); parentPlane.AddCloudDensity(index, x1, y1, OldDensity[x, y] * s1 * t1); } } } }