Exemple #1
0
        private void OnDrawGizmos()
        {
            Gizmos.matrix = transform.localToWorldMatrix;
            Gizmos.color  = Colors.VolumeOutline;
            Gizmos.DrawWireCube(0.5f * ContainerSize, ContainerSize);

            Gizmos.color = Colors.VolumeSolid;
            if (SolidRegions != null)
            {
                foreach (var solid in SolidRegions)
                {
                    Gizmos.DrawCube(0.5f * (solid.Max + solid.Min), solid.Max - solid.Min);
                }
            }

            Gizmos.color = Colors.CellSource;
            if (Sources != null)
            {
                foreach (var source in Sources)
                {
                    Gizmos.DrawCube(GridStepSize * ((Vector3)Vec3Int.FloorToInt(source.Position / GridStepSize) + Vector3.one * 0.5f),
                                    Vector3.one * GridStepSize);
                }
            }

            Gizmos.color = Colors.CellSink;
            if (Sinks != null)
            {
                foreach (var sink in Sinks)
                {
                    Gizmos.DrawCube(GridStepSize * ((Vector3)Vec3Int.FloorToInt(sink / GridStepSize) + Vector3.one * 0.5f),
                                    Vector3.one * GridStepSize);
                }
            }
        }
Exemple #2
0
        public void AddSink(Vector3 pos)
        {
            var p = Vec3Int.FloorToInt(pos / StepSize);

            if (!ValidIndex(p))
            {
                throw new IndexOutOfRangeException($"pos {pos} => p {p} is out of bounds");
            }
            CellType[Idx(p)] = CTYPE_SINK;
        }
Exemple #3
0
        public void AddSource(Source source)
        {
            var p = Vec3Int.FloorToInt(source.Position / StepSize);

            if (!ValidIndex(p))
            {
                throw new IndexOutOfRangeException($"pos {source.Position} => p {p} is out of bounds");
            }
            CellType[Idx(p)] = CTYPE_SOURCE;
            sources.Add(p, source);
        }
Exemple #4
0
        public static float LerpCenters(MacGrid g, float[] q, Vector3 pos)
        {
            Vec3Int p0 = Vec3Int.FloorToInt(pos);
            // Because we're using grid coordinates here, not fluid space, we can rely on the
            // fact the spacing (on one axis) between two samples values is always 1.
            Vector3 alpha = pos - p0;

            // This is just simple trilinear interpolation, written out in full.
            float q00 = (1f - alpha.x) * q[g.Idx(p0.x, p0.y, p0.z)] + alpha.x * q[g.Idx(p0.x + 1, p0.y, p0.z)];
            float q10 = (1f - alpha.x) * q[g.Idx(p0.x, p0.y + 1, p0.z)] + alpha.x * q[g.Idx(p0.x + 1, p0.y + 1, p0.z)];
            float q01 = (1f - alpha.x) * q[g.Idx(p0.x, p0.y, p0.z + 1)] + alpha.x * q[g.Idx(p0.x + 1, p0.y, p0.z + 1)];
            float q11 = (1f - alpha.x) * q[g.Idx(p0.x, p0.y + 1, p0.z + 1)] + alpha.x * q[g.Idx(p0.x + 1, p0.y + 1, p0.z + 1)];

            float q0 = (1f - alpha.y) * q00 + alpha.y * q10;
            float q1 = (1f - alpha.y) * q01 + alpha.y * q11;

            return((1f - alpha.z) * q0 + alpha.z * q1);
        }
Exemple #5
0
        public MacGrid(Vector3 size, float step)
        {
            Size     = size;
            StepSize = step;

            GridSize = Vec3Int.FloorToInt(Size / StepSize);

            Pressure  = new float[GridSize.x * GridSize.y * GridSize.z];
            VelocityX = new float[(GridSize.x + 1) * GridSize.y * GridSize.z];
            VelocityY = new float[GridSize.x * (GridSize.y + 1) * GridSize.z];
            VelocityZ = new float[GridSize.x * GridSize.y * (GridSize.z + 1)];
            CellType  = new byte[GridSize.x * GridSize.y * GridSize.z];

            sources = new Dictionary <Vec3Int, Source>();

            PressureNext  = new float[GridSize.x * GridSize.y * GridSize.z];
            VelocityNextX = new float[(GridSize.x + 1) * GridSize.y * GridSize.z];
            VelocityNextY = new float[GridSize.x * (GridSize.y + 1) * GridSize.z];
            VelocityNextZ = new float[GridSize.x * GridSize.y * (GridSize.z + 1)];
        }
Exemple #6
0
        // Only one of the stagger flags can be set!
        public static float Lerp(MacGrid g, float[] q, Vector3 pos,
                                 bool staggerX = false, bool staggerY = false, bool staggerZ = false)
        {
            Vec3Int staggerAdjustment;

            if (staggerX)
            {
                staggerAdjustment = Vec3Int.right;
            }
            else if (staggerY)
            {
                staggerAdjustment = Vec3Int.up;
            }
            else if (staggerZ)
            {
                staggerAdjustment = Vec3Int.forward;
            }
            else
            {
                staggerAdjustment = Vec3Int.zero;
            }

            // p0 gives us the array-coordinates of lower-back-left sample point next to the given pos.
            Vec3Int p0 = Vec3Int.FloorToInt(pos - staggerAdjustment * 0.5f) + staggerAdjustment;
            // The actual position in grid coordinates is as above but with 0.5f * staggerAdjustment added on the end:
            // p0 is correct for indexing to the array, but the staggering causes a mismatch between indices and coordinates.
            // Because we're using grid based coordinates here, not fluid space, we can rely on the
            // fact the spacing (on one axis) between two samples values is always 1.
            Vector3 alpha = pos - p0 - staggerAdjustment * 0.5f;

            // This is just simple trilinear interpolation, written out in full.
            float q00 = (1f - alpha.x) * q[g.Idx(p0.x, p0.y, p0.z)] + alpha.x * q[g.Idx(p0.x + 1, p0.y, p0.z)];
            float q10 = (1f - alpha.x) * q[g.Idx(p0.x, p0.y + 1, p0.z)] + alpha.x * q[g.Idx(p0.x + 1, p0.y + 1, p0.z)];
            float q01 = (1f - alpha.x) * q[g.Idx(p0.x, p0.y, p0.z + 1)] + alpha.x * q[g.Idx(p0.x + 1, p0.y, p0.z + 1)];
            float q11 = (1f - alpha.x) * q[g.Idx(p0.x, p0.y + 1, p0.z + 1)] + alpha.x * q[g.Idx(p0.x + 1, p0.y + 1, p0.z + 1)];

            float q0 = (1f - alpha.y) * q00 + alpha.y * q10;
            float q1 = (1f - alpha.y) * q01 + alpha.y * q11;

            return((1f - alpha.z) * q0 + alpha.z * q1);
        }