Пример #1
0
        /// <summary>
        /// Finds a least penetrating vector.
        /// </summary>
        /// <param name="axis">The axis.</param>
        /// <param name="other">The other.</param>
        /// <param name="penetrationNormal">The penetration normal.</param>
        /// <param name="penetrationLength">Length of the penetration.</param>
        /// <returns>
        /// True, if a least penetrating vector could be found (no Axis separates the bounding volumes).
        /// </returns>
        private bool FindLeastPenetrating(Vector2 axis, BoundingVolume other, ref Vector2 penetrationNormal, ref float penetrationLength)
        {
            float minThis, maxThis, minOther, maxOther;

            // Tests if separating axis exists
            if (TestSeparatingAxis(axis, other, out minThis, out maxThis, out minOther, out maxOther))
            {
                return(false);
            }

            // Find least penetrating axis
            float diff = Math.Min(maxOther, maxThis) - Math.Max(minOther, minThis);

            // Store penetration vector
            if (diff < penetrationLength)
            {
                penetrationLength = diff;
                penetrationNormal = axis;
            }
            return(true);
        }
Пример #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FluidParticle"/> class.
        /// </summary>
        public FluidParticle()
        {
            this.Life        = 0;
            this.Mass        = 1.0f;
            this.Position    = Vector2.Zero;
            this.PositionOld = this.Position;
            this.Velocity    = Vector2.Zero;
            this.Force       = Vector2.Zero;
            this.Density     = Constants.DENSITY_OFFSET;
            // update (integrate) using basic verlet with small drag
            this.Solver = new Verlet
            {
                Damping = 0.01f
            };
            this.BoundingVolume = new PointVolume
            {
                Position = this.Position,
                Margin   = Constants.CELL_SPACE * 0.25f,
            };

            this.UpdatePressure();
        }
Пример #3
0
        /// <summary>
        /// Tests if this bounding volume intersects the other bounding volume,
        /// using the "Separating Axis Test" (SAT).
        /// </summary>
        /// <param name="other">The bounding volume to test against</param>
        /// <param name="penetrationNormal">The penetration vector (direction of the least penetration).</param>
        /// <param name="penetrationLength">Length of the penetration.</param>
        /// <returns>
        /// True, if the both bounding volumes intersect.
        /// </returns>
        public bool Intersects(BoundingVolume other, out Vector2 penetrationNormal, out float penetrationLength)
        {
            penetrationNormal = Vector2.Zero;
            penetrationLength = float.MaxValue;

            // Axis of this
            if (this.Axis != null)
            {
                foreach (var axis in this.Axis)
                {
                    if (!FindLeastPenetrating(axis, other, ref penetrationNormal, ref penetrationLength))
                    {
                        return(false);
                    }
                }
            }

            // Axis of other
            if (other.Axis != null)
            {
                foreach (var axis in other.Axis)
                {
                    if (!FindLeastPenetrating(axis, other, ref penetrationNormal, ref penetrationLength))
                    {
                        return(false);
                    }
                }
            }

            // Flip penetrationDirection to point away from this
            if (Vector2.Dot(other.Position - this.Position, penetrationNormal) > 0.0f)
            {
                Vector2.Mult(ref penetrationNormal, -1.0f, out penetrationNormal);
            }

            return(true);
        }