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

📄 tool.cs

📁 Particle System Test Application on C#
💻 CS
📖 第 1 页 / 共 3 页
字号:
using System;
using System.Collections;
using Microsoft.DirectX;

namespace ParticleSystems
{
	namespace Verlet
	{
		namespace Tools
		{
            /// <summary>
            /// Tools contains a lot of help functions intended to make it 
            /// easier for the experimenting developer.
            /// </summary>
			public class Tools
			{
				static private Random mRandom = new Random();

				private Tools()
				{
				}

				/// <summary>
				/// Generates a random number that lies within a limit
				/// </summary>
				/// <param name="min">The lower limit</param>
				/// <param name="max">The upper limit</param>
				/// <returns>A random number</returns>
				public static float GetRandomNumber(float min, float max)
				{
					return (max - min) * (float)mRandom.NextDouble() + min;
				}

				/// <summary>
				/// Generates a random number between -1 and 1
				/// </summary>
				/// <returns>A random number</returns>
				public static float GetNormalizedRandomNumber()
				{
					return GetRandomNumber(-1.0f, 1.0f);
				}

				/// <summary>
				/// Generates a normalized random vector;
				/// </summary>
				/// <returns>A normalized random vector</returns>
				public static Vector3 GetNormalizedRandomVector()
				{
					Vector3 lVector = new Vector3(
						GetNormalizedRandomNumber(), 
						GetNormalizedRandomNumber(), 
						GetNormalizedRandomNumber());
					lVector.Normalize();
					return lVector;
				}

				/// <summary>
				/// Generates a random vector of a specified length
				/// </summary>
				/// <param name="length">Length of random vector</param>
				/// <returns>A random vector of specified length</returns>
				public static Vector3 RandomVector(float length)
				{
					Vector3 lVector = GetNormalizedRandomVector();
					lVector.Multiply(length);
					return lVector;
				}

				/// <summary>
				/// Gives each particle in a particle system a random increase 
				/// of velocity in a random direction
				/// </summary>
				/// <param name="maxVelocity">Maximum speed increase</param>
				/// <param name="ps">A particle system</param>
				public static void Shake(
					float maxVelocity, 
					ParticleSystem ps)
				{
					float lTimeDelta = ps.TimeDelta;
					Particle[] lParticles = ps.Particles;

					foreach(Particle lParticle in lParticles)
					{
						lParticle.IncreaseVelocity(
							lTimeDelta, 
							RandomVector(
								maxVelocity * GetNormalizedRandomNumber()));
					}
				}

				/// <summary>
				/// ITwoParticleConstraintFactory is used by some of the 
				/// algorithms in Tools to give a developer the possibilty
				/// of controlling what constraints should be created by the 
				/// algorithm
				/// </summary>
				public interface ITwoParticleConstraintFactory
				{

                    /// <summary>
                    /// Creates a constraint between two particles and append
                    /// it too the particle system using the transaction
                    /// </summary>
                    /// <param name="transaction">A transaction</param>
                    /// <param name="particle1">A particle</param>
                    /// <param name="particle2">A particle</param>
                    void CreateConstraint(
                        ParticleSystem.Transaction transaction,
						Particle particle1, 
						Particle particle2);
				}

				/// <summary>
				/// StickConstraintFactory is an implementation of 
				/// ITwoParticleConstraintFactory that creates stick constraints
				/// </summary>
				public class StickConstraintFactory : ITwoParticleConstraintFactory
				{
					/// <summary>
					/// Constructor
					/// </summary>
					public StickConstraintFactory()
					{
					}

                    /// <summary>
                    /// Creates a constraint between two particles and append
                    /// it too the particle system using the transaction
                    /// </summary>
                    /// <param name="transaction">A transaction</param>
                    /// <param name="particle1">A particle</param>
                    /// <param name="particle2">A particle</param>
                    public void CreateConstraint(
                        ParticleSystem.Transaction transaction,
                        Particle particle1, 
                        Particle particle2)
                    {
                        transaction.AddConstraint(
                            new Constraints.Stick(particle1, particle2));
					}

				}

				/// <summary>
				/// RopeConstraintFactory is an implementation of 
				/// ITwoParticleConstraintFactory that creates rope constraints.
				/// </summary>
				public class RopeConstraintFactory : ITwoParticleConstraintFactory
				{
					/// <summary>
					/// Constructor
					/// </summary>
					public RopeConstraintFactory()
					{
						mScale = 1.0f;
					}

					/// <summary>
					/// Constructor for a RopeConstraintFactory that create
					/// Rope constraints that are enlonged by scale parameter
					/// </summary>
					/// <param name="scale">scale must be larger or equal to 1.0f</param>
					public RopeConstraintFactory(float scale)
					{
						mScale = scale;
					}

                    /// <summary>
                    /// Creates a constraint between two particles and append
                    /// it too the particle system using the transaction
                    /// </summary>
                    /// <param name="transaction">A transaction</param>
                    /// <param name="particle1">A particle</param>
                    /// <param name="particle2">A particle</param>
                    public void CreateConstraint(
                        ParticleSystem.Transaction transaction,
                        Particle particle1, 
                        Particle particle2)
                    {
                        transaction.AddConstraint(
                            new Constraints.Rope(mScale, particle1, particle2));
                    }

					private float mScale;

				}

                /// <summary>
                /// SoftStickConstraintFactory is an implementation of 
                /// ITwoParticleConstraintFactory that creates soft stick 
                /// constraints.
                /// </summary>
                public class SoftStickConstraintFactory : ITwoParticleConstraintFactory
                {
                    /// <summary>
                    /// Constructor
                    /// </summary>
                    /// <param name="stiffness">Must be be between 0.0f and 1.0f</param>
                    public SoftStickConstraintFactory(float stiffness)
                    {
                        mStiffness = stiffness;
                    }

                    /// <summary>
                    /// Creates a constraint between two particles and append
                    /// it too the particle system using the transaction
                    /// </summary>
                    /// <param name="transaction">A transaction</param>
                    /// <param name="particle1">A particle</param>
                    /// <param name="particle2">A particle</param>
                    public void CreateConstraint(
                        ParticleSystem.Transaction transaction,
                        Particle particle1, 
                        Particle particle2)
                    {
                        Constraints.SoftStick lSoftStick = 
                            new Constraints.SoftStick(mStiffness, particle1, particle2);
                        transaction.AddConstraint(lSoftStick);
                        transaction.AddEffect(lSoftStick);
                    }

                    private float mStiffness;

                }

                private static void AddParticlesToTransaction(
					ArrayList particles,
					ParticleSystem.Transaction transaction)
				{
                    foreach(Particle lParticle in particles)
                    {
                        transaction.AddParticle(lParticle);
                    }
				}


				private static Particle[] ConvertArrayListToParticleList(
					ArrayList particles)
				{
					Particle[] lParticles = new Particle[particles.Count];

					particles.CopyTo(lParticles);

					return lParticles;
				}

				/// <summary>
				/// Creates a chain of particles and constraints between two
				/// particles
				/// </summary>
				/// <param name="particle1">A particle</param>
				/// <param name="particle2">A particle</param>
				/// <param name="mass">The mass of the chain</param>
				/// <param name="links">How many links in chain</param>
				/// <param name="constraintFactory">A constraint factory</param>
				/// <param name="transaction">A transaction</param>
				/// <returns></returns>
				public static Particle[] CreateChain(
					Particle particle1,
					Particle particle2,
					float mass,
					int links,
					ITwoParticleConstraintFactory constraintFactory,
					ParticleSystem.Transaction transaction)
				{
					if( !(mass > float.Epsilon) )
					{
						throw new Exception("mass parameter must be greater than 0");
					}
					if( links < 1 )
					{
						throw new Exception("links parameter must be greater than 0");
					}

					ArrayList lCreatedParticles = new ArrayList();

					float lMass = mass / links;

					Particle lPreviousParticle = particle1;
					Vector3 lStep = (particle2.Position - particle1.Position);
					lStep.Scale(1.0f / (float)links);

					for( int lIter = 0; lIter < links - 1; ++lIter )
					{
						Vector3 lNext = lPreviousParticle.Position + lStep;

						Particle lNextParticle = new Particle(
							lMass, 
							lNext);

						lCreatedParticles.Add(lNextParticle);
						constraintFactory.CreateConstraint(
                            transaction,
							lPreviousParticle, 
							lNextParticle);

						lPreviousParticle = lNextParticle;
					}

                    constraintFactory.CreateConstraint(
                        transaction,
						lPreviousParticle, 
						particle2);

                    AddParticlesToTransaction(lCreatedParticles, transaction);
                    return ConvertArrayListToParticleList(lCreatedParticles);
				}

				/// <summary>
				/// Enables a developer to modify particles created by some
				/// algorithms in Tools before constraints are created. 
				/// Originally I thought a transform matrix would be enough
				/// but I later realized I wanted to do non-linear transforms
				/// </summary>
				public interface IParticlePreProcessor
				{
                    /// <summary>
                    /// Applies the preproccessor on a set of particles
                    /// </summary>
                    /// <param name="particles">A set of particles</param>
					void Apply(ArrayList particles);
				}

				/// <summary>
				/// Base class for particle pre processors that shall be 
				/// chainable
				/// </summary>
				public abstract class ChainableParticlePreProcessor : IParticlePreProcessor
				{
					/// <summary>
					/// Constructor
					/// </summary>
					public ChainableParticlePreProcessor()
					{
						mNextPreProcessor = null;
					}

					/// <summary>
					/// Constructor
					/// </summary>
					/// <param name="nextPreProcessor">next preprocessor in the chain</param>
					public ChainableParticlePreProcessor(IParticlePreProcessor nextPreProcessor)
					{
						mNextPreProcessor = nextPreProcessor;
					}


                    /// <summary>
                    /// Applies the preproccessor on a set of particles
                    /// </summary>
                    /// <param name="particles">A set of particles</param>
                    public void Apply(ArrayList particles)
					{
						ApplyThisPreProcessor(particles);
						if( mNextPreProcessor != null )
						{
							mNextPreProcessor.Apply(particles);
						}
					}

					/// <summary>
					/// Abstract method. Inheritors should implement this to
					/// apply their preprocessing step
					/// </summary>
					/// <param name="particles"></param>
					protected abstract void ApplyThisPreProcessor(ArrayList particles);

					private IParticlePreProcessor mNextPreProcessor;
				}

				/// <summary>
				/// Does a null transform
				/// </summary>
				public class NullParticlePreProcessor : ChainableParticlePreProcessor
				{
                    /// <summary>
                    /// Constructor
                    /// </summary>

⌨️ 快捷键说明

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