⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 constraint.cs

📁 Particle System Test Application on C#
💻 CS
字号:
using System;
using Microsoft.DirectX;

namespace ParticleSystems
{
    namespace Verlet
    {
        namespace Constraints
        {

            /// <summary>
            /// An abstract help class for constraints dealing with two 
            /// particles
            /// </summary>
            public abstract class TwoParticleHolder
            {
                /// <summary>
                /// Constructor
                /// </summary>
                /// <param name="particle1">A particle</param>
                /// <param name="particle2">A particle</param>
                public TwoParticleHolder(Particle particle1, Particle particle2)
                {
                    mParticle1 = particle1;
                    mParticle2 = particle2;
                }

                /// <summary>
                /// Particle 1 of the constraint
                /// </summary>
                public Particle Particle1
                {
                    get
                    {
                        return mParticle1;
                    }
                }

                /// <summary>
                /// Particle 2 of the constraint
                /// </summary>
                public Particle Particle2
                {
                    get
                    {
                        return mParticle2;
                    }
                }

                /// <summary>
                /// Particle 1 holder
                /// </summary>
                protected Particle mParticle1;
                /// <summary>
                /// Particle 2 holder
                /// </summary>
                protected Particle mParticle2;
            }

            /// <summary>
            /// Stick implements IConstraint. Stick is a two particle constraint
            /// which emulate a stiff stick connecting two particles.
            /// </summary>
            public class Stick : TwoParticleHolder, IConstraint
            {
                /// <summary>
                /// Constructor
                /// </summary>
                /// <param name="particle1">A particle</param>
                /// <param name="particle2">A particle</param>
                public Stick(Particle particle1, Particle particle2) 
                    : base(particle1, particle2)
                {
                    mLength = (particle1.Position - particle2.Position).Length();
                }

                /// <summary>
                /// Applies the constraint
                /// </summary>
                public void Apply()
                {
                    float lParticle1InvertedMass = mParticle1.InvertedMass;
                    float lParticle2InvertedMass = mParticle2.InvertedMass;

                    Vector3 lDelta = mParticle2.mCurrentPosition - mParticle1.mCurrentPosition;
                    float lDeltaLength = lDelta.Length();

                    float lDiff = (lDeltaLength - mLength) / (lDeltaLength*(lParticle1InvertedMass + lParticle2InvertedMass));

                    mParticle1.mCurrentPosition.Add(lParticle1InvertedMass * lDiff *lDelta);
                    mParticle2.mCurrentPosition.Subtract(lParticle2InvertedMass * lDiff *lDelta);

                }

                /// <summary>
                /// Length of stick
                /// </summary>
                public float Length
                {
                    get
                    {
                        return mLength;
                    }
                }

                private float mLength;
            }

            /// <summary>
            /// Rope implements IConstraint. Rope is a two particle constraint
            /// which intends to emulate a rope connecting two particles. A 
            /// rope may be shorter than the specified length but not longer
            /// </summary>
            public class Rope : TwoParticleHolder, IConstraint
            {
                /// <summary>
                /// Constructor
                /// </summary>
                /// <param name="scale">The length of the rope constraint is multiplied by this parameter</param>
                /// <param name="particle1">A particle</param>
                /// <param name="particle2">A particle</param>
                public Rope(float scale, Particle particle1, Particle particle2) 
                    : base(particle1, particle2)
                {
                    if( scale < 1.0f )
                    {
                        throw new Exception("scale parameter must be 1.0 or larger");
                    }
                    mLength = scale * (particle1.Position - particle2.Position).Length();
                }

                /// <summary>
                /// Constructor
                /// </summary>
                /// <param name="particle1">A particle</param>
                /// <param name="particle2">A particle</param>
                public Rope(Particle particle1, Particle particle2) 
                    : base(particle1, particle2)
                {
                    mLength = (particle1.Position - particle2.Position).Length();
                }

                /// <summary>
                /// Applies the constraint
                /// </summary>
                public void Apply()
                {
                    float lParticle1InvertedMass = mParticle1.InvertedMass;
                    float lParticle2InvertedMass = mParticle2.InvertedMass;

                    Vector3 lDelta = 
                        mParticle2.mCurrentPosition - mParticle1.mCurrentPosition;
                    float lDeltaLength = lDelta.Length();

                    if( lDeltaLength > mLength )
                    {
                        float lDiff = (lDeltaLength - mLength) / 
                            (lDeltaLength * 
                            (lParticle1InvertedMass + lParticle2InvertedMass));

                        mParticle1.mCurrentPosition.Add(
                            lParticle1InvertedMass * lDiff *lDelta);
                        mParticle2.mCurrentPosition.Subtract(
                            lParticle2InvertedMass * lDiff *lDelta);
                    }

                }

                /// <summary>
                /// Length of rope
                /// </summary>
                public float Length
                {
                    get
                    {
                        return mLength;
                    }
                }

                private float mLength;
            }

            /// <summary>
            /// Rope implements IConstraint and IEffect. SoftStick is sort of 
            /// a failed experiment. 
            /// The intention was a stick that when shortened,
            /// instead of immedietly trying to return to its original length 
            /// grew back over ot its original length over time. It's still in
            /// the code as it gives an example of how to implement a contraint
            /// that is changed every update (as it's also an IEffect).
            /// </summary>
            public class SoftStick : TwoParticleHolder, IConstraint, IEffect
            {
                /// <summary>
                /// Constructor
                /// </summary>
                /// <param name="stiffness">The stiffness of the constraint</param>
                /// <param name="particle1">A particle</param>
                /// <param name="particle2">A particle</param>
                public SoftStick(
                    float stiffness, 
                    Particle particle1, 
                    Particle particle2) 
                    : base(particle1, particle2)
                {
                    mStiffness = stiffness;
                    mLength = (particle1.Position - particle2.Position).Length();
                    mDesiredLength = mLength;
                }

                /// <summary>
                /// Applies the effect
                /// </summary>
                /// <param name="timeDelta">The timedelta used by the particle system this iteration</param>
                public void Apply(float timeDelta)
                {
                    float lCurrentDistance = (mParticle2.mCurrentPosition - 
                        mParticle1.mCurrentPosition).Length();
                    float lTimeDeltaCorrectedStiffness = mStiffness * timeDelta;
                    mDesiredLength = 
                        mLength * lTimeDeltaCorrectedStiffness + 
                        lCurrentDistance * ( 1 - lTimeDeltaCorrectedStiffness );
                }

                /// <summary>
                /// Applies the constraint
                /// </summary>
                public void Apply()
                {
                    float lParticle1InvertedMass = mParticle1.InvertedMass;
                    float lParticle2InvertedMass = mParticle2.InvertedMass;

                    Vector3 lDelta = mParticle2.mCurrentPosition - mParticle1.mCurrentPosition;
                    float lDeltaLength = lDelta.Length();

                    float lDiff = (lDeltaLength - mDesiredLength) / (lDeltaLength*(lParticle1InvertedMass + lParticle2InvertedMass));

                    mParticle1.mCurrentPosition.Add(lParticle1InvertedMass * lDiff *lDelta);
                    mParticle2.mCurrentPosition.Subtract(lParticle2InvertedMass * lDiff *lDelta);

                }

                /// <summary>
                /// Length of soft stick
                /// </summary>
                public float Length
                {
                    get
                    {
                        return mLength;
                    }
                }

                private float mStiffness;
                private float mLength;
                private float mDesiredLength;
            }

        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -