/// <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); }
/// <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(); }
/// <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); }