public void ApplyBehavior(VerletPoint point, float delta)
 {
     if (!point.Touched)
     {
         point.ApplyForce(Gravity * point.GravityScale);
     }
 }
        /// <summary>
        /// Create a verlet link.
        /// </summary>
        /// <param name="a">First verlet point</param>
        /// <param name="b">First verlet point</param>
        /// <param name="restingDistance">Resting distance</param>
        /// <param name="minimalDistance">Minimal link distance. Use `-1` to disable.</param>
        /// <param name="maximalDistance">Maximal link distance. Use `-1` to disable.</param>
        /// <param name="tearSensitivity">Distance required to break the link. Use `-1` to create an unbreakable link.</param>
        /// <param name="tearSensitivityFactor">Distance factor required to break the link. Use `-1` to create an unbreakable link.</param>
        /// <param name="stiffness">Stiffness of the link</param>
        /// <param name="width">Width of the link</param>
        /// <param name="color">Link color</param>
        /// <param name="visible">Show link</param>
        /// <returns>Verlet link</returns>
        public VerletLink CreateLink(
            VerletPoint a,
            VerletPoint b,
            float?restingDistance       = null,
            float?minimalDistance       = null,
            float?maximalDistance       = null,
            float?tearSensitivity       = null,
            float?tearSensitivityFactor = null,
            float?stiffness             = null,
            float?width  = null,
            Color?color  = null,
            bool?visible = null)
        {
            var link = new VerletLink(this, a, b);

            a.AddLink(link);
            AddChild(link);

            link.Visible         = visible ?? link.Visible;
            link.RestingDistance = restingDistance ?? link.RestingDistance;
            link.MinimalDistance = minimalDistance ?? link.MinimalDistance;
            link.MaximalDistance = maximalDistance ?? link.MaximalDistance;
            link.TearSensitivity = tearSensitivity ?? link.TearSensitivity;
            link.Stiffness       = stiffness ?? link.Stiffness;
            link.Modulate        = color ?? link.Modulate;
            link.Width           = width ?? link.Width;

            if (tearSensitivityFactor.HasValue)
            {
                link.TearSensitivity = link.RestingDistance * tearSensitivityFactor.Value;
            }

            return(link);
        }
示例#3
0
        /// <summary>
        /// Create a verlet ragdoll.
        /// </summary>
        /// <param name="world">Verlet world</param>
        /// <param name="centerPosition">Center position</param>
        /// <param name="height">Body height</param>
        /// <param name="gravityScale">Gravity scale</param>
        /// <param name="tearSensitivityFactor">Distance factor required to break links. Use '-1' to create an unbreakable ragdoll</param>
        /// <param name="pointRadius">Point radius</param>
        /// <param name="drawIntermediatePoints">Draw all ragdoll points</param>
        /// <param name="drawSupportLinks">Draw support links</param>
        public VerletRagdoll(VerletWorld world, Vector2 centerPosition, float height, float gravityScale = 1, float tearSensitivityFactor = -1, float pointRadius = 10f, bool drawIntermediatePoints = false, bool drawSupportLinks = false)
        {
            Vector2 genPos()
            {
                return(centerPosition + MathUtils.RandVector2(-5, 5, -5, 5));
            }

            VerletPoint createPoint(float mass, float?radius = null, bool?visible = null)
            {
                var point = world.CreatePoint(genPos(), mass: mass, radius: radius ?? pointRadius, visible: visible ?? drawIntermediatePoints);

                point.GravityScale = gravityScale;
                return(point);
            }

            var headSize   = pointRadius * 3;
            var handSize   = pointRadius * 2;
            var footSize   = pointRadius * 1.5f;
            var headLength = height / 7.5f;

            head     = createPoint(4, radius: headSize, visible: true);
            shoulder = createPoint(26);
            world.CreateLink(head, shoulder, restingDistance: 5 / 4 * headLength, tearSensitivityFactor: tearSensitivityFactor, stiffness: 1);

            elbowLeft  = createPoint(2);
            elbowRight = createPoint(2);
            world.CreateLink(elbowLeft, shoulder, restingDistance: 3 / 2 * headLength, tearSensitivityFactor: tearSensitivityFactor, stiffness: 1);
            world.CreateLink(elbowRight, shoulder, restingDistance: 3 / 2 * headLength, tearSensitivityFactor: tearSensitivityFactor, stiffness: 1);

            handLeft  = createPoint(2, radius: handSize, visible: true);
            handRight = createPoint(2, radius: handSize, visible: true);
            world.CreateLink(handLeft, elbowLeft, restingDistance: 2 * headLength, tearSensitivityFactor: tearSensitivityFactor, stiffness: 1);
            world.CreateLink(handRight, elbowRight, restingDistance: 2 * headLength, tearSensitivityFactor: tearSensitivityFactor, stiffness: 1);

            pelvis = createPoint(15);
            world.CreateLink(pelvis, shoulder, restingDistance: 3.5f * headLength, tearSensitivityFactor: tearSensitivityFactor, stiffness: 0.8f);
            world.CreateLink(pelvis, head, restingDistance: 4.75f * headLength, tearSensitivityFactor: tearSensitivityFactor, stiffness: 0.02f, visible: drawSupportLinks, color: Colors.LightBlue.WithAlpha(64));

            kneeLeft  = createPoint(10);
            kneeRight = createPoint(10);
            world.CreateLink(kneeLeft, pelvis, restingDistance: 2 * headLength, tearSensitivityFactor: tearSensitivityFactor, stiffness: 1);
            world.CreateLink(kneeRight, pelvis, restingDistance: 2 * headLength, tearSensitivityFactor: tearSensitivityFactor, stiffness: 1);

            footLeft  = createPoint(20, radius: footSize, visible: true);
            footRight = createPoint(20, radius: footSize, visible: true);
            world.CreateLink(footLeft, kneeLeft, restingDistance: 2 * headLength, tearSensitivityFactor: tearSensitivityFactor, stiffness: 1);
            world.CreateLink(footRight, kneeRight, restingDistance: 2 * headLength, tearSensitivityFactor: tearSensitivityFactor, stiffness: 1);
            world.CreateLink(footLeft, shoulder, restingDistance: 7.5f * headLength, tearSensitivityFactor: tearSensitivityFactor, stiffness: 0.001f, visible: drawSupportLinks, color: Colors.LightBlue.WithAlpha(64));
            world.CreateLink(footRight, shoulder, restingDistance: 7.5f * headLength, tearSensitivityFactor: tearSensitivityFactor, stiffness: 0.001f, visible: drawSupportLinks, color: Colors.LightBlue.WithAlpha(64));
        }
        /// <summary>
        /// Create a simple verlet link.
        /// </summary>
        /// <param name="world">World</param>
        /// <param name="a">Point A</param>
        /// <param name="b">Point B</param>
        public VerletLink(VerletWorld world, VerletPoint a, VerletPoint b)
        {
            A          = a;
            B          = b;
            this.world = world;

            PositionA = A.GlobalPosition;
            PositionB = B.GlobalPosition;

            if (RestingDistance == 0)
            {
                // Calculate resting distance from points position
                RestingDistance = (PositionB - PositionA).Length();
            }
        }
        /// <summary>
        /// Create a verlet point.
        /// </summary>
        /// <param name="initialPosition">Initial position</param>
        /// <param name="mass">Mass</param>
        /// <param name="gravityScale">Gravity scale</param>
        /// <param name="radius">Radius</param>
        /// <param name="color">Color</param>
        /// <param name="visible">Show point</param>
        /// <returns>Verlet point</returns>
        public VerletPoint CreatePoint(Vector2?initialPosition = null, float?mass = null, float?gravityScale = null, float?radius = null, Color?color = null, bool?visible = null)
        {
            var point = new VerletPoint(this);

            points.Add(point);
            AddChild(point);

            point.Mass         = mass ?? point.Mass;
            point.GravityScale = gravityScale ?? point.GravityScale;
            point.Radius       = radius ?? point.Radius;
            point.Visible      = visible ?? point.Visible;
            point.Modulate     = color ?? point.Modulate;

            if (initialPosition.HasValue)
            {
                point.MoveToPosition(initialPosition.Value);
            }

            return(point);
        }