protected internal override void Process(Single deltaSeconds, ref ParticleIterator iterator)
#endif
        {
            Single deltaPitch = this.RotationRate.X * deltaSeconds;
            Single deltaYaw   = this.RotationRate.Y * deltaSeconds;
            Single deltaRoll  = this.RotationRate.Z * deltaSeconds;

            var particle = iterator.First;

            do
            {
#if UNSAFE
                particle->Rotation.X += deltaPitch;
                particle->Rotation.Y += deltaYaw;
                particle->Rotation.Z += deltaRoll;
#else
                particle.Rotation.X += deltaPitch;
                particle.Rotation.Y += deltaYaw;
                particle.Rotation.Z += deltaRoll;
#endif
            }
#if UNSAFE
            while (iterator.MoveNext(&particle));
#else
            while (iterator.MoveNext(ref particle));
#endif
        }
        protected internal override void Process(Single deltaSeconds, ref ParticleIterator iterator)
#endif
        {
            Single initialForceDeltaX = this.InitialForce.X * deltaSeconds;
            Single initialForceDeltaY = this.InitialForce.Y * deltaSeconds;
            Single initialForceDeltaZ = this.InitialForce.Z * deltaSeconds;

            Single finalForceDeltaX = this.FinalForce.X * deltaSeconds;
            Single finalForceDeltaY = this.FinalForce.Y * deltaSeconds;
            Single finalForceDeltaZ = this.FinalForce.Z * deltaSeconds;

            var particle = iterator.First;

            do
            {
#if UNSAFE
                particle->Velocity.X += initialForceDeltaX + ((finalForceDeltaX - initialForceDeltaX) * particle->Age);
                particle->Velocity.Y += initialForceDeltaY + ((finalForceDeltaY - initialForceDeltaY) * particle->Age);
                particle->Velocity.Z += initialForceDeltaZ + ((finalForceDeltaZ - initialForceDeltaZ) * particle->Age);
#else
                particle.Velocity.X += initialForceDeltaX + ((finalForceDeltaX - initialForceDeltaX) * particle.Age);
                particle.Velocity.Y += initialForceDeltaY + ((finalForceDeltaY - initialForceDeltaY) * particle.Age);
                particle.Velocity.Z += initialForceDeltaZ + ((finalForceDeltaZ - initialForceDeltaZ) * particle.Age);
#endif
            }
#if UNSAFE
            while (iterator.MoveNext(&particle));
#else
            while (iterator.MoveNext(ref particle));
#endif
        }
        protected internal override void Process(Single deltaSeconds, ref ParticleIterator iterator)
#endif
        {
            Single inverseCoefficientDelta = -(this.DampingCoefficient * deltaSeconds);

            var particle = iterator.First;

            do
            {
#if UNSAFE
                particle->Velocity.X += particle->Velocity.X * inverseCoefficientDelta;
                particle->Velocity.Y += particle->Velocity.Y * inverseCoefficientDelta;
                particle->Velocity.Z += particle->Velocity.Z * inverseCoefficientDelta;
#else
                particle.Velocity.X += particle.Velocity.X * inverseCoefficientDelta;
                particle.Velocity.Y += particle.Velocity.Y * inverseCoefficientDelta;
                particle.Velocity.Z += particle.Velocity.Z * inverseCoefficientDelta;
#endif
            }
#if UNSAFE
            while (iterator.MoveNext(&particle));
#else
            while (iterator.MoveNext(ref particle));
#endif
        }
Beispiel #4
0
        protected internal override void Process(Single deltaSeconds, ref ParticleIterator iterator)
#endif
        {
            Vector3 initialColour = this.InitialColour;
            Vector3 delta   = this.FinalColour - initialColour;
            
            var particle = iterator.First;

            do
            {
#if UNSAFE
                particle->Colour.X = (initialColour.X + (delta.X * particle->Age));
                particle->Colour.Y = (initialColour.Y + (delta.Y * particle->Age));
                particle->Colour.Z = (initialColour.Z + (delta.Z * particle->Age));
#else
                particle.Colour.X = (initialColour.X + (delta.X * particle.Age));
                particle.Colour.Y = (initialColour.Y + (delta.Y * particle.Age));
                particle.Colour.Z = (initialColour.Z + (delta.Z * particle.Age));
#endif
            }
#if UNSAFE
            while (iterator.MoveNext(&particle));
#else
            while (iterator.MoveNext(ref particle));
#endif
        }
Beispiel #5
0
        protected internal override void Process(Single deltaSeconds, ref ParticleIterator iterator)
#endif
        {
            Single deltaStrength = this.Strength * deltaSeconds;

            Single deltaGravityX = this.GravityVector.X * deltaStrength;
            Single deltaGravityY = this.GravityVector.Y * deltaStrength;
            Single deltaGravityZ = this.GravityVector.Z * deltaStrength;

            var particle = iterator.First;

            do
            {
#if UNSAFE
                particle->Velocity.X += deltaGravityX;
                particle->Velocity.Y += deltaGravityY;
                particle->Velocity.Z += deltaGravityZ;
#else
                particle.Velocity.X += deltaGravityX;
                particle.Velocity.Y += deltaGravityY;
                particle.Velocity.Z += deltaGravityZ;
#endif
            }
#if UNSAFE
            while (iterator.MoveNext(&particle));
#else
            while (iterator.MoveNext(ref particle));
#endif
        }
        protected internal override void Process(Single deltaSeconds, ref ParticleIterator iterator)
#endif
        {
            var particle = iterator.First;

            do
            {
#if UNSAFE
                Single age = particle->Age;
#else
                Single age = particle.Age;
#endif

                if (age < this.Median)
#if UNSAFE
                    particle->Colour.W = this.InitialOpacity + ((this.MedianOpacity - this.InitialOpacity) * (age / this.Median));
#else
                    particle.Colour.W = this.InitialOpacity + ((this.MedianOpacity - this.InitialOpacity) * (age / this.Median));
#endif
                else
#if UNSAFE
                    particle->Colour.W = this.MedianOpacity + ((this.FinalOpacity - this.MedianOpacity) * ((age - this.Median) / (1f - this.Median)));
#else
                    particle.Colour.W = this.MedianOpacity + ((this.FinalOpacity - this.MedianOpacity) * ((age - this.Median) / (1f - this.Median)));
#endif
            }
#if UNSAFE
            while (iterator.MoveNext(&particle));
#else
            while (iterator.MoveNext(ref particle));
#endif
        }
        public unsafe ParticleBuffer(int size)
        {
            Size = size;
            // add one extra spot in memory for margin between head and tail
            // so the iterator can see that it's at the end
            _nativePointer = Marshal.AllocHGlobal(SizeInBytes);
            BufferEnd = (Particle*)(_nativePointer + SizeInBytes);
            Head = (Particle*)_nativePointer;
            Tail = (Particle*)_nativePointer;

            _iterator = new ParticleIterator(this);

            GC.AddMemoryPressure(SizeInBytes);
        }
Beispiel #8
0
        /// <summary>
        /// Performs rendering of particles.
        /// </summary>
        /// <param name="iterator">The particle iterator object.</param>
        /// <param name="context">The render context containing rendering information.</param>
        protected override void Render(ref RenderContext context, ref ParticleIterator iterator)
        {
            Vector2 origin = new Vector2(context.Texture.Width / 2f, context.Texture.Height / 2f);

            this.SpriteBatch.Begin(SpriteSortMode.Deferred, context.BlendState, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullNone, null, this.Transformation);
            {
#if UNSAFE
                unsafe
                {
                    Particle* particle = iterator.First;
#else
                    Particle particle = iterator.First;
#endif
                    do
                    {
#if UNSAFE
                        Single scale = particle->Scale / context.Texture.Width;

                        Vector2 position = new Vector2
                        {
                            X = particle->Position.X,
                            Y = particle->Position.Y
                        };

                        this.SpriteBatch.Draw(context.Texture, position, null, new Color(particle->Colour), particle->Rotation.Z, origin, scale, SpriteEffects.None, 0f);
#else
                        Single scale = particle.Scale / context.Texture.Width;

                        Vector2 position = new Vector2
                        {
                            X = particle.Position.X,
                            Y = particle.Position.Y
                        };

                        this.SpriteBatch.Draw(context.Texture, position, null, new Color(particle.Colour), particle.Rotation.Z, origin, scale, SpriteEffects.None, 0f);
#endif
                    }
#if UNSAFE
                    while (iterator.MoveNext(&particle));
#else
                    while (iterator.MoveNext(ref particle));
#endif
#if UNSAFE
                }
#endif
                this.SpriteBatch.End();
            }
        }
Beispiel #9
0
        protected internal override void Process(Single deltaSeconds, ref ParticleIterator iterator)
#endif
        {
            Single squareRadius = (this.Radius * this.Radius);

            Single deltaStrength = this.Strength * deltaSeconds;

            Single deltaForceX = this.ForceVector.X * deltaStrength;
            Single deltaForceY = this.ForceVector.Y * deltaStrength;
            Single deltaForceZ = this.ForceVector.Z * deltaStrength;

            Vector3 forcePosition = this.Position;

            var particle = iterator.First;

            do
            {
#if UNSAFE
                Vector3 position = particle->Position;
#else
                Vector3 position = particle.Position;
#endif
                Single distanceX = forcePosition.X - position.X;
                Single distanceY = forcePosition.Y - position.Y;
                Single distanceZ = forcePosition.Z - position.Z;

                Single squareDistance = ((distanceX * distanceX) + (distanceY * distanceY) + (distanceZ * distanceZ));

                if (squareDistance < squareRadius)
                {
#if UNSAFE
                    particle->Velocity.X += deltaForceX;
                    particle->Velocity.Y += deltaForceY;
                    particle->Velocity.Z += deltaForceZ;
#else
                    particle.Velocity.X += deltaForceX;
                    particle.Velocity.Y += deltaForceY;
                    particle.Velocity.Z += deltaForceZ;
#endif
                }
            }
#if UNSAFE
            while (iterator.MoveNext(&particle));
#else
            while (iterator.MoveNext(ref particle));
#endif
        }
Beispiel #10
0
        protected internal override void Process(Single deltaSeconds, ref ParticleIterator iterator)
#endif
        {
            Single h = ((this.HueShift * deltaSeconds) * Calculator.Pi) / 180f;

            Single u = Calculator.Cos(h);
            Single w = Calculator.Sin(h);

            Matrix hueTransform = new Matrix(1f, 0f, 0f, 0f,
                                             0f, u,  -w, 0f,
                                             0f, w,   u, 0f,
                                             0f, 0f, 0f, 1f);

            var particle = iterator.First;

#if UNSAFE
            Vector4 colour = particle->Colour;
#else
            Vector4 colour = particle.Colour;
#endif
            do
            {
                // Convert the current colour of the particle to YIQ colour space...
                Vector4.Transform(ref colour, ref HueShiftModifier.YiqTransform, out colour);

                // Transform the colour in YIQ space...
                Vector4.Transform(ref colour, ref hueTransform, out colour);

                // Convert the colour back to RGB space...
                Vector4.Transform(ref colour, ref HueShiftModifier.RgbTransform, out colour);

#if UNSAFE
                particle->Colour.X = colour.X;
                particle->Colour.Y = colour.Y;
                particle->Colour.Z = colour.Z;
#else
                particle.Colour.X = colour.X;
                particle.Colour.Y = colour.Y;
                particle.Colour.Z = colour.Z;
#endif
            }
#if UNSAFE
            while (iterator.MoveNext(&particle));
#else
            while (iterator.MoveNext(ref particle));
#endif
        }
Beispiel #11
0
        protected internal override void Process(Single deltaSeconds, ref ParticleIterator iterator)
#endif
        {
            var particle = iterator.First;

            do
            {
#if UNSAFE
                particle->Scale = this.InitialScale + ((this.FinalScale - this.InitialScale) * particle->Age);
#else
                particle.Scale = this.InitialScale + ((this.FinalScale - this.InitialScale) * particle.Age);
#endif
            }
#if UNSAFE
            while (iterator.MoveNext(&particle));
#else
            while (iterator.MoveNext(ref particle));
#endif
        }
Beispiel #12
0
        protected internal override void Process(Single deltaSeconds, ref ParticleIterator iterator)
#endif
        {
            Single w;
            Vector3 x, y;

            var particle = iterator.First;

            do
            {
#if UNSAFE
                Single age = particle->Age;
#else
                Single age = particle.Age;
#endif
                if (age < this.Median)
                {
                    x = this.InitialColour;
                    y = this.MedianColour;
                    w = age / this.Median;
                }
                else
                {
                    x = this.MedianColour;
                    y = this.FinalColour;
                    w = (age - this.Median) / (1f - this.Median);
                }
#if UNSAFE
                particle->Colour.X = x.X + ((y.X - x.X) * w);
                particle->Colour.Y = x.Y + ((y.Y - x.Y) * w);
                particle->Colour.Z = x.Z + ((y.Z - x.Z) * w);
#else
                particle.Colour.X = x.X + ((y.X - x.X) * w);
                particle.Colour.Y = x.Y + ((y.Y - x.Y) * w);
                particle.Colour.Z = x.Z + ((y.Z - x.Z) * w);
#endif
            }
#if UNSAFE
            while (iterator.MoveNext(&particle));
#else
            while (iterator.MoveNext(ref particle));
#endif
        }
Beispiel #13
0
        protected internal override void Process(Single deltaSeconds, ref ParticleIterator iterator)
#endif
        {
            var particle = iterator.First;

            do
            {
#if UNSAFE
                particle->Colour.W = this.InitialOpacity - (this.InitialOpacity * particle->Age);
#else
                particle.Colour.W = this.InitialOpacity - (this.InitialOpacity * particle.Age);
#endif
            }
#if UNSAFE
            while (iterator.MoveNext(&particle));
#else
            while (iterator.MoveNext(ref particle));
#endif
        }
        protected internal override void Process(Single deltaSeconds, ref ParticleIterator iterator)
#endif
        {
            Single squareMaximumVelocity = (this.MaximumVelocity * this.MaximumVelocity);

            var particle = iterator.First;

            do
            {
#if UNSAFE
                Vector3 velocity = particle->Velocity;
#else
                Vector3 velocity = particle.Velocity;
#endif
                Single squareVelocity = ((velocity.X * velocity.X) +
                                         (velocity.Y * velocity.Y) +
                                         (velocity.Z * velocity.Z));

                if (squareVelocity > squareMaximumVelocity)
                {
                    Single actualVelocity = Calculator.Sqrt(squareVelocity);

#if UNSAFE
                    particle->Velocity.X = (particle->Velocity.X / actualVelocity) * this.MaximumVelocity;
                    particle->Velocity.Y = (particle->Velocity.Y / actualVelocity) * this.MaximumVelocity;
                    particle->Velocity.Z = (particle->Velocity.Z / actualVelocity) * this.MaximumVelocity;
#else
                    particle.Velocity.X = (particle.Velocity.X / actualVelocity) * this.MaximumVelocity;
                    particle.Velocity.Y = (particle.Velocity.Y / actualVelocity) * this.MaximumVelocity;
                    particle.Velocity.Z = (particle.Velocity.Z / actualVelocity) * this.MaximumVelocity;
#endif
                }
            }
#if UNSAFE
            while (iterator.MoveNext(&particle));
#else
            while (iterator.MoveNext(ref particle));
#endif
        }
Beispiel #15
0
        /// <summary>
        /// Performs rendering of particles.
        /// </summary>
        /// <param name="iterator">The particle iterator object.</param>
        /// <param name="context">The render context containing rendering information.</param>
        protected override void Render(ref RenderContext context, ref ParticleIterator iterator)
        {
            Int32 vertexCount = 0;
            Vector3 cameraPos = context.CameraPosition;
            Vector3 rotationAxis = context.BillboardRotationalAxis;
            bool squareTexture = (context.Texture.Height == context.Texture.Width);
            float aspectRatio = context.Texture.Height / (float)context.Texture.Width ;

            SetDataOptions setDataOptions = SetDataOptions.NoOverwrite;

            //Use the SpriteBatch style of filling buffers
            //http://blogs.msdn.com/b/shawnhar/archive/2010/07/07/setdataoptions-nooverwrite-versus-discard.aspx
            if (_vertexBufferPosition + context.Count * VerticesPerParticle > NumVertices)
            {
                //Too much to fit in the remaining space - start at the beginning and discard
                _vertexBufferPosition = 0;
                setDataOptions = SetDataOptions.Discard;
            }

#if UNSAFE
            unsafe
            {
                fixed (ParticleVertex* vertexArray = Vertices)
                {
                    ParticleVertex* verts = vertexArray +_vertexBufferPosition;
#else
                    int vertexIndex = _vertexBufferPosition;
#endif
                    var particle = iterator.First;
                    do
                    {
#if UNSAFE
                        Single scale = particle->Scale;
                        Vector3 position = particle->Position;
                        Vector3 rotation = particle->Rotation;
                        Vector4 colour = particle->Colour;
                        //Work out our world transform - and set a flag to avoid some multiplies if world ends up as zero
                        bool worldIsNotIdentity = true;
                        Matrix effectWorld;
                        if (context.WorldIsIdentity)
                        {
                            if (particle->EffectProxyIndex > 0)
                            {
                                effectWorld = ParticleEffectProxy.Proxies[particle->EffectProxyIndex].World;
                            }
                            else
                            {
                                worldIsNotIdentity = false;
                                effectWorld = Matrix.Identity; //Makes the compiler happy though we will never actually use it.
                            }
                        }
                        else
                        {
                            effectWorld = particle->EffectProxyIndex > 0 ? ParticleEffectProxy.Proxies[particle->EffectProxyIndex].FinalWorld : context.World;
                        }

#else
                        Single scale = particle.Scale;
                        Vector3 position = particle.Position;
                        Vector3 rotation = particle.Rotation;
                        Vector4 colour = particle.Colour;
                        //If we have a proxy then multiply in the proxy world matrix
                        bool worldIsNotIdentity = true;
                        Matrix effectWorld;
                        if (context.WorldIsIdentity)
                        {
                            if (particle.EffectProxyIndex > 0)
                            {
                                effectWorld = ParticleEffectProxy.Proxies[particle.EffectProxyIndex].World;
                            }
                            else
                            {
                                worldIsNotIdentity = false;
                                effectWorld = Matrix.Identity;
                                    //Makes the compiler happy though we will never actually use it.
                            }
                        }
                        else
                        {
                            effectWorld = particle.EffectProxyIndex > 0
                                              ? ParticleEffectProxy.Proxies[particle.EffectProxyIndex].FinalWorld
                                              : context.World;
                        }
#endif

                        //Individual particle transformations - scale and rotation
                        //The Rotation setup will fill in the top 3x3 so we just need to initialise 44
                        var transform = new Matrix {M44 = 1};

                        float scaleX = scale;
                        float scaleY = squareTexture ? scale : scale * aspectRatio;
                        //ScaleZ is always 1 so no need multiple into M_3

                        //Inline the rotation and scale calculations and do each element in one go
                        //Fast rotation matrix - see http://en.wikipedia.org/wiki/Rotation_matrix#General_rotations
                        //This set matches
                        //Matrix temp2 = Matrix.CreateRotationX(rotation.X) * Matrix.CreateRotationY(rotation.Y) * Matrix.CreateRotationZ(rotation.Z); //Matches math od Rotx*RotY*RotZ
                        //var cosX = (float) Math.Cos(rotation.X);
                        //var cosY = (float) Math.Cos(rotation.Y);
                        //var cosZ = (float) Math.Cos(rotation.Z);
                        //var sinX = (float) Math.Sin(rotation.X);
                        //var sinY = (float) Math.Sin(rotation.Y);
                        //var sinZ = (float) Math.Sin(rotation.Z);
                        //transform.M11 = cosY*cosZ;
                        //transform.M12 = cosY * sinZ;
                        //transform.M13 = -sinY;
                        //transform.M21 = sinX*sinY*cosZ - cosX * sinZ;
                        //transform.M22 = sinX*sinY*sinZ + cosX*cosZ;
                        //transform.M23 = sinX*cosY;
                        //transform.M31 = cosX*sinY*cosZ + sinX * sinZ;
                        //transform.M32 = cosX*sinY*sinZ - sinX * cosZ;
                        //transform.M33 = cosX * cosY;

                        //This set matches
                        //Matrix temp2 = Matrix.CreateScale(new VEctor3(scaleX, scaleY,1) * Matrix.CreateRotationZ(rotation.Z) * Matrix.CreateRotationX(rotation.Y) * Matrix.CreateRotationY(rotation.X) ; //Matches YawPitchRoll order
                        //Matrix temp = Matrix.CreateScale(new VEctor3(scaleX, scaleY,1) * Matrix.CreateFromYawPitchRoll(rotation.X, rotation.Y, rotation.Z);
                        //TODO - can we optimise out a rotation e.g.fast path if rotation.Y=0 etc
                        //TODO - can we optimise out rotation(s) if we know its a billboard? That overwrites much of the transform
                        var cosX = (float)Math.Cos(rotation.Y);
                        var cosY = (float)Math.Cos(rotation.X);
                        var cosZ = (float)Math.Cos(rotation.Z);
                        var sinX = (float)Math.Sin(rotation.Y);
                        var sinY = (float)Math.Sin(rotation.X);
                        var sinZ = (float)Math.Sin(rotation.Z);
                        var cosYcosZ = cosY*cosZ;
                        var cosYsinZ = cosY*sinZ;
                        var sinXsinY = sinX*sinY;
                        transform.M11 = (cosYcosZ + sinXsinY * sinZ) * scaleX;
                        transform.M12 = (cosX * sinZ) * scaleX;
                        transform.M13 = (sinX * cosYsinZ - sinY * cosZ) * scaleX;
                        transform.M21 = (sinXsinY * cosZ - cosYsinZ) * scaleY;
                        transform.M22 = (cosX * cosZ) *scaleY;
                        transform.M23 = (sinY * sinZ + sinX * cosYcosZ) * scaleY;
                        transform.M31 = cosX * sinY;
                        transform.M32 = -sinX;
                        transform.M33 = cosX * cosY;

                        switch (context.BillboardStyle)
                        {
                            case BillboardStyle.None:
                                //Position the particle without a multiplication!
                                transform.M41 = position.X;
                                transform.M42 = position.Y;
                                transform.M43 = position.Z;
                                //Just apply the world
                                //TODO - we can just do this in Basic effect instead of per vertex - only if there is no proxy, sort of a fast path!
                                if (worldIsNotIdentity)
                                {
                                    Matrix.Multiply(ref transform, ref effectWorld, out transform);
                                }
                                break;

                            default: //Its billboarded

                                Vector3 worldPos;
                                if (worldIsNotIdentity)
                                {
                                    Vector3.Transform(ref position, ref effectWorld, out worldPos);
                                }
                                else
                                {
                                    worldPos = position;
                                }


                                //Apply the billboard (which includes the world translation)
                                Matrix billboardMatrix;
                                if (context.BillboardStyle == BillboardStyle.Spherical)
                                {
                                    //Spherical billboards (always face the camera)
                                    Matrix.CreateBillboard(ref worldPos, ref cameraPos, ref Up, Forward,
                                                           out billboardMatrix);
                                }
                                else
                                {
                                    //HACK: For progenitor DBP use the velocity as the axis for a per particle axis
                                    if (context.UseVelocityAsBillboardAxis)
                                    {
#if UNSAFE
                                        Matrix.CreateConstrainedBillboard(ref worldPos, ref cameraPos, ref particle->Velocity,
                                                                          Forward, null, out billboardMatrix);
#else
                                        Matrix.CreateConstrainedBillboard(ref worldPos, ref cameraPos, ref particle.Velocity,
                                                                          Forward, null, out billboardMatrix);

#endif
                                    }
                                    else
                                    {
                                        //Cylindrical billboards have a vector they are allowed to rotate around
                                        Matrix.CreateConstrainedBillboard(ref worldPos, ref cameraPos, ref rotationAxis,
                                                                          Forward, null, out billboardMatrix);
                                    }


                                }

                                Matrix.Multiply(ref transform, ref billboardMatrix, out transform);
                                break;
                        }

                        Vector3 v1;
                        Vector3 v2;
                        Vector3 v3;
                        Vector3 v4;

                        Vector3.Transform(ref inv1, ref transform, out v1);
                        Vector3.Transform(ref inv2, ref transform, out v2);
                        Vector3.Transform(ref inv3, ref transform, out v3);
                        Vector3.Transform(ref inv4, ref transform, out v4);
#if UNSAFE

                        //inline particle value assignments - removes 4 calls with their parameters and its a struct anyway
                        verts->Position.X = v1.X;
                        verts->Position.Y = v1.Y;
                        verts->Position.Z = v1.Z;
                        verts->Colour.X = colour.X;
                        verts->Colour.Y = colour.Y;
                        verts->Colour.Z = colour.Z;
                        verts->Colour.W = colour.W;
                        verts++;

                        verts->Position.X = v2.X;
                        verts->Position.Y = v2.Y;
                        verts->Position.Z = v2.Z;
                        verts->Colour.X = colour.X;
                        verts->Colour.Y = colour.Y;
                        verts->Colour.Z = colour.Z;
                        verts->Colour.W = colour.W;
                        verts++;

                        verts->Position.X = v3.X;
                        verts->Position.Y = v3.Y;
                        verts->Position.Z = v3.Z;
                        verts->Colour.X = colour.X;
                        verts->Colour.Y = colour.Y;
                        verts->Colour.Z = colour.Z;
                        verts->Colour.W = colour.W;
                        verts++;

                        verts->Position.X = v4.X;
                        verts->Position.Y = v4.Y;
                        verts->Position.Z = v4.Z;
                        verts->Colour.X = colour.X;
                        verts->Colour.Y = colour.Y;
                        verts->Colour.Z = colour.Z;
                        verts->Colour.W = colour.W;
                        verts++;
#else
                        //inline particle value assignments - removes 4 calls with their parameters and its a struct anyway

                        this.Vertices[vertexIndex].Position = v1;
                        this.Vertices[vertexIndex].Colour = colour;
                        this.Vertices[vertexIndex++].TextureCoordinate = uv1;
                        this.Vertices[vertexIndex].Position = v2;
                        this.Vertices[vertexIndex].Colour = colour;
                        this.Vertices[vertexIndex++].TextureCoordinate = uv2;
                        this.Vertices[vertexIndex].Position = v3;
                        this.Vertices[vertexIndex].Colour = colour;
                        this.Vertices[vertexIndex++].TextureCoordinate = uv3;
                        this.Vertices[vertexIndex].Position = v4;
                        this.Vertices[vertexIndex].Colour = colour;
                        this.Vertices[vertexIndex++].TextureCoordinate = uv4;
#endif
                        vertexCount += 4;
                    }
#if UNSAFE
                    while (iterator.MoveNext(&particle));
#else
                    while (iterator.MoveNext(ref particle));
#endif

                    base.GraphicsDeviceService.GraphicsDevice.BlendState = context.BlendState;
                    this.BasicEffect.Texture = context.Texture;

                    //Xbox need the vertex buffer to be set to null before SetData is called
                    //Windows does not
                    //TODO: Is this a bug? see http://forums.create.msdn.com/forums/p/61885/399495.aspx#399495
#if XBOX
                    if (setDataOptions == SetDataOptions.Discard)
                    {
                        base.GraphicsDeviceService.GraphicsDevice.SetVertexBuffer(null);
                    }
#endif
                    _vertexBuffer.SetData(_vertexBufferPosition * ParticleVertex.Size, Vertices, _vertexBufferPosition, vertexCount, ParticleVertex.Size, setDataOptions);
                    Debug.WriteLine(String.Format("position: {0} Count: {1} Hint: {2}", _vertexBufferPosition, vertexCount, setDataOptions));
                    base.GraphicsDeviceService.GraphicsDevice.SetVertexBuffer(_vertexBuffer);

                    foreach (EffectPass pass in this.BasicEffect.CurrentTechnique.Passes)
                    {
                        pass.Apply();

                        base.GraphicsDeviceService.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, _vertexBufferPosition, vertexCount,
                                                                                        _vertexBufferPosition/4*6, vertexCount/2);
                    }

                    //Move to the next free part of the array
                    _vertexBufferPosition += vertexCount;
#if UNSAFE
                }
            }
#endif
        }
Beispiel #16
0
        /// <summary>
        /// Renders the specified particle effect.
        /// </summary>
        /// <param name="effect">The particle effect to render.</param>
        /// <param name="worldMatrix">The world transformation matrix.</param>
        /// <param name="viewMatrix">The view matrix.</param>
        /// <param name="projectionMatrix">The projection matrix.</param>
        /// <param name="cameraPosition">The camera matrix.</param>
        public void RenderEffect(ParticleEffect effect, ref Matrix worldMatrix,
                                                        ref Matrix viewMatrix,
                                                        ref Matrix projectionMatrix,
                                                        ref Vector3 cameraPosition)
        {
#if UNSAFE
            unsafe
#endif
            {
                this.PreRender(ref worldMatrix, ref viewMatrix, ref projectionMatrix);

                //Pre-multiply any proxies world matrices with the passed in world matrix
                if (effect.Proxies != null && worldMatrix != Matrix.Identity)
                {
                    effect.SetFinalWorld(ref worldMatrix);
                }

                for (Int32 i = 0; i < effect.Emitters.Count; i++)
                {
                    AbstractEmitter emitter = effect.Emitters[i];

                    // Skip if the emitter does not have a texture...
                    if (emitter.ParticleTexture == null)
                        continue;

                    // Skip if the emitter blend mode is set to 'None'...
                    if (emitter.BlendMode == EmitterBlendMode.None)
                        continue;

                    // Skip if the emitter has no active particles...
                    if (emitter.ActiveParticlesCount == 0)
                        continue;

                    BlendState blendState = BlendStateFactory.GetBlendState(emitter.BlendMode);



                    RenderContext context = new RenderContext(emitter.BillboardStyle, emitter.BillboardRotationalAxis, blendState, emitter.ParticleTexture, ref worldMatrix, ref viewMatrix, ref projectionMatrix, ref cameraPosition, emitter.ActiveParticlesCount, emitter.UseVelocityAsBillboardAxis);

                    Counters.ParticlesDrawn += emitter.ActiveParticlesCount;
#if UNSAFE
                    fixed (Particle* buffer = emitter.Particles)
#else
                    Particle[] buffer = emitter.Particles;
#endif
                    {
                        ParticleIterator iterator = new ParticleIterator(buffer, emitter.Budget, emitter.ActiveIndex, emitter.ActiveParticlesCount);

                        this.Render(ref context, ref iterator);
                    }
                }
            }
        }
Beispiel #17
0
 /// <summary>
 /// Performs rendering of particles.
 /// </summary>
 /// <param name="context">The render context containing rendering information.</param>
 /// <param name="iterator">The particle iterator object.</param>
 protected abstract void Render(ref RenderContext context, ref ParticleIterator iterator);
Beispiel #18
0
        /// <summary>
        /// Processes active particles.
        /// </summary>
        /// <param name="deltaSeconds">Elapsed time in whole and fractional seconds.</param>
        /// <param name="iterator">A particle iterator object.</param>
#if UNSAFE
        protected internal override unsafe void Process(Single deltaSeconds, ref ParticleIterator iterator)
Beispiel #19
0
        /// <summary>
        /// Updates the particle emitter.
        /// </summary>
        /// <param name="deltaSeconds">Elapsed time in whole and fractional seconds.</param>
        public void Update(Single deltaSeconds)
        {
            Check.True(this.Initialised, "Emitter has not yet been initialised!");

            this.TotalSeconds += deltaSeconds;

            this.Controllers.Update(deltaSeconds);

            if (this.ActiveParticlesCount < 1)
            {
                return;
            }
#if UNSAFE
            unsafe
#endif
            {
#if UNSAFE
                fixed(Particle *particleArray = this.Particles)
#endif
                {
                    // Copy the state of the ring buffer as we will modify it as particles die...
                    var currentIndex         = this.ActiveIndex;
                    var currentParticleCount = this.ActiveParticlesCount;

                    for (var i = 0; i < currentParticleCount; i++)
                    {
#if UNSAFE
                        // Get a pointer to the particle in the buffer...
                        Particle *particle = particleArray + currentIndex;

                        // Calculate the age of the particle in seconds...
                        var actualAge = this.TotalSeconds - particle->Inception;
#else
                        // Extract the particle from the buffer...
                        Particle particle = this.Particles[currentIndex];

                        // Calculate the age of the particle in seconds...
                        var actualAge = this.TotalSeconds - particle.Inception;
#endif
                        // Check to see if the particle has expired...
                        if (actualAge > this.Term)
                        {
                            // Increment the index of the first active particle...
                            this.ActiveIndex = (this.ActiveIndex + 1) % this.Budget;

                            // Decrement the active particles count...
                            this.ActiveParticlesCount = (this.ActiveParticlesCount - 1);
                        }
                        else
                        {
#if UNSAFE
                            // Calculate the normalized age of the particle...
                            particle->Age = actualAge / this.Term;

                            //HACK: For progenitor DBP use the velocity as the axis for a per particle axis
                            if (!UseVelocityAsBillboardAxis)
                            {
                                // Apply particle movement...
                                particle->Position.X += (particle->Velocity.X * deltaSeconds);
                                particle->Position.Y += (particle->Velocity.Y * deltaSeconds);
                                particle->Position.Z += (particle->Velocity.Z * deltaSeconds);
                            }
                            else
                            {
                                particle->Velocity.Normalize();
                            }
#else
                            // Calculate the normalized age of the particle...
                            particle.Age = actualAge / this.Term;

                            // Apply particle movement...
                            particle.Position.X += (particle.Velocity.X * deltaSeconds);
                            particle.Position.Y += (particle.Velocity.Y * deltaSeconds);
                            particle.Position.Z += (particle.Velocity.Z * deltaSeconds);

                            // Put the mutated particle back in the buffer...
                            this.Particles[currentIndex] = particle;
#endif
                        }

                        currentIndex = (currentIndex + 1) % this.Budget;
                    }

                    if (this.ActiveParticlesCount > 0)
                    {
#if UNSAFE
                        var buffer = particleArray;
#else
                        var buffer = this.Particles;
#endif
                        var iterator = new ParticleIterator(buffer, this.Budget, this.ActiveIndex, this.ActiveParticlesCount);

                        this.Modifiers.RunProcessors(deltaSeconds, ref iterator);
                    }
                }
            }
        }
Beispiel #20
0
 /// <summary>
 /// Performs rendering of particles.
 /// </summary>
 /// <param name="context">The render context containing rendering information.</param>
 /// <param name="iterator">The particle iterator object.</param>
 protected abstract void Render(ref RenderContext context, ref ParticleIterator iterator);
Beispiel #21
0
        protected internal override void Process(Single deltaSeconds, ref ParticleIterator iterator)
#endif
        {
            Single deltaStrength = this.Strength * deltaSeconds;

            Single deltaForceX = this.Force.X * deltaStrength;
            Single deltaForceY = this.Force.Y * deltaStrength;
            Single deltaForceZ = this.Force.Z * deltaStrength;

            var particle = iterator.First;

            do
            {
#if UNSAFE
                Vector3 position = particle->Position;
#else
                Vector3 position = particle.Position;
#endif

                if (position.X > (this.Position.X - this.HalfWidth))
                    if (position.X < (this.Position.X + this.HalfWidth))
                        if (position.Y > (this.Position.Y - this.HalfHeight))
                            if (position.Y < (this.Position.Y + this.HalfHeight))
                                if (position.Z > (this.Position.Z - this.HalfDepth))
                                    if (position.Z < (this.Position.Z + this.HalfDepth))
                                    {
#if UNSAFE
                                        particle->Velocity.X += deltaForceX;
                                        particle->Velocity.Y += deltaForceY;
                                        particle->Velocity.Z += deltaForceZ;
#else
                                        particle.Velocity.X += deltaForceX;
                                        particle.Velocity.Y += deltaForceY;
                                        particle.Velocity.Z += deltaForceZ;
#endif
                                    }
            }
#if UNSAFE
            while (iterator.MoveNext(&particle));
#else
            while (iterator.MoveNext(ref particle));
#endif
        }
        /// <summary>
        /// Processes active particles.
        /// </summary>
        /// <param name="deltaSeconds">Elapsed time in whole and fractional seconds.</param>
        /// <param name="iterator">A particle iterator object.</param>
#if UNSAFE
        protected internal override unsafe void Process(Single deltaSeconds, ref ParticleIterator iterator)
Beispiel #23
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(ParticleIterator obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
Beispiel #24
0
 protected internal abstract void Process(Single deltaSeconds, ref ParticleIterator iterator);
Beispiel #25
0
                public BaseObject Create()
                {
                    ParticleIterator emptyInstance = new ParticleIterator(CreatedWhenConstruct.CWC_NotToCreate);

                    return(emptyInstance);
                }