Exemple #1
0
        /// <summary>
        /// Draws the model.
        /// </summary>
        /// <param name="gameTime">The elapsed game time.</param>
        public override void Draw(TimeSpan gameTime)
        {
            if (this.meshes == null)
            {
                return;
            }

            float zOrder = Vector3.DistanceSquared(this.RenderManager.CurrentDrawingCamera3D.Position, this.rootJointTransform.Position);

            this.shouldSkinMeshes |= this.RefreshSkinMatrices();
            this.shouldSkinMeshes |= this.ShouldRefreshMorph();

            var worldTransform = this.rootJointTransform.WorldTransform;

            for (int i = 0; i < this.meshes.Length; i++)
            {
                var currentMesh = this.meshes[i] as SkinnedMesh;

                if (this.shouldSkinMeshes)
                {
                    Timers.BeginAveragedTimer("Skin_" + this.Owner.Name);
                    currentMesh.SetBones(this.skinMatrices, this.Quality, this.morphTargetWeights, true, true);
                    Timers.EndAveragedTimer("Skin_" + this.Owner.Name);

                    this.GraphicsDevice.BindVertexBuffer(currentMesh.VertexBuffer);
                }

                Material currentMaterial = null;
                if (this.Materials?.Length > 0 && this.ModelMesh?.InternalModel?.Materials?.Count > currentMesh.MaterialIndex)
                {
                    string fileMaterialName = this.ModelMesh.InternalModel.Materials[currentMesh.MaterialIndex];

                    var materialComponent = (from m in this.Materials where m.AsignedTo == fileMaterialName select m).FirstOrDefault();
                    if (materialComponent != null)
                    {
                        currentMaterial = materialComponent.Material;
                    }
                    else
                    {
                        currentMaterial = this.Materials[0].Material;
                    }
                }

                if (currentMaterial != null)
                {
                    currentMesh.ZOrder = zOrder;

                    // Draw mesh
                    this.RenderManager.DrawMesh(currentMesh, currentMaterial, worldTransform, this.Owner.IsFinalStatic);
                }
            }

            this.shouldSkinMeshes = false;
            this.rootJointChanged = false;
        }
        private void UpdateParticles(TimeSpan gameTime)
        {
            if (this.ParticleSystem.ZOrdering)
            {
                Vector3 cameraPosition = this.RenderManager.CurrentDrawingCamera3D.Position;
                Vector3.Transform(ref cameraPosition, ref this.inverseWorld, out vertexComparer.Camera);
            }

            var pS = this.ParticleSystem;

            bool hasForces = false;

            ////if (pS.ApplyForces)
            ////{
            ////    if (this.forcesManager != null)
            ////    {
            ////        this.forcesManager.GetForces(pS.ForcesCategory, ref this.forces);
            ////        hasForces = this.forces.Count > 0;

            ////        if (hasForces)
            ////        {
            ////            for (int i = 0; i < this.forces.Count; i++)
            ////            {
            ////                this.forces[i].Prepare(this);
            ////            }
            ////        }
            ////    }
            ////}

            pS.material.VelocityTrailFactor = (pS.ScreenAlign == NewParticleSystem.ScreenAlignType.Velocity) ? pS.VelocityTrailFactor : 0;

            // The amount of time
            this.timeFactor = (float)gameTime.TotalSeconds * this.ParticleSystem.TimeFactor;

            // Gets the number of new particles in this frame
            var newParticles = this.LaunchNewParticles();

            this.aliveParticles = 0;

            float correctedTime = this.timeFactor * this.ParticleSystem.LifeFactor;

            Timers.BeginAveragedTimer("Particles");

            ////this.ParticleSystem.Shape?.Prepare();

            Parallel.For(0, this.numParticles, (i) =>
            {
                ////for (var i = 0; i < this.numParticles; i++)
                ////{
                ref Particle p = ref this.particles[i];

                // We check the life cycle of the particle
                if (p.Alive)
                {
                    p.LifeLerp += correctedTime / p.LifeTime;

                    if (p.LifeLerp > 1)
                    {
                        p.Alive = false;
                        p.Size  = 0;
                    }
                }
                else
                {
                    // If the particle is not alive we create a new one (if there are new particles to create)
                    if (Interlocked.Decrement(ref newParticles) >= 0)
                    {
                        this.ParticleSystem.ResetParticle(ref p);

                        var startTime = (float)(this.timeFactor * this.random.NextDouble());

                        p.LifeLerp  = startTime * (this.ParticleSystem.LifeFactor) / p.LifeTime;
                        p.Position += startTime * p.Velocity;
                    }
                }

                if (p.Alive)
                {
                    // If the particle is alive after all, we update it
                    p.Forces.X -= this.timeFactor * pS.Gravity.X;
                    p.Forces.Y -= this.timeFactor * pS.Gravity.Y;
                    p.Forces.Z -= this.timeFactor * pS.Gravity.Z;

                    if (hasForces)
                    {
                        for (int fIdx = 0; fIdx < this.forces.Count; fIdx++)
                        {
                            this.forces[fIdx].ApplyForce(this, this.timeFactor, ref p);
                        }
                    }

                    if (pS.ColorAnimated && (pS.ColorOverLife != null))
                    {
                        p.Color = p.InitColor * pS.ColorOverLife.GetValue(p.LifeLerp);

                        if (pS.PremultiplyAlpha)
                        {
                            var alpha = p.Color.A / 255f;
                            p.Color.R = (byte)(p.Color.R * alpha);
                            p.Color.G = (byte)(p.Color.G * alpha);
                            p.Color.B = (byte)(p.Color.B * alpha);
                        }
                    }

                    if (pS.SizeAnimated && (pS.SizeOverLife != null))
                    {
                        p.Size = p.InitSize * pS.SizeOverLife.GetValue(p.LifeLerp);
                    }

                    if ((pS.VelocityAnimated) && (pS.VelocityOverLifeX != null) && (pS.VelocityOverLifeY != null) && (pS.VelocityOverLifeZ != null))
                    {
                        p.Velocity.X = p.InitVelocity.X * pS.VelocityOverLifeX.GetValue(p.LifeLerp);
                        p.Velocity.Y = p.InitVelocity.Y * pS.VelocityOverLifeY.GetValue(p.LifeLerp);
                        p.Velocity.Z = p.InitVelocity.Z * pS.VelocityOverLifeZ.GetValue(p.LifeLerp);
                    }

                    if ((pS.CollideWithFloor) && (p.Position.Y < pS.FloorLevel))
                    {
                        switch (pS.CollisionType)
                        {
                        case NewParticleSystem.ParticleCollisionType.Die:
                            p.Alive = false;
                            p.Size  = 0;
                            break;

                        case NewParticleSystem.ParticleCollisionType.Bounce:

                            p.Position.Y = pS.FloorLevel;

                            p.Velocity.X = p.Velocity.X * pS.FloorBounciness;
                            p.Velocity.Y = (p.Velocity.Y + p.Forces.Y) * -pS.FloorBounciness;
                            p.Velocity.Z = p.Velocity.Z * pS.FloorBounciness;

                            p.Forces.Y = 0;

                            break;

                        case NewParticleSystem.ParticleCollisionType.Stop:
                        default:
                            p.Position.Y = pS.FloorLevel;
                            p.Velocity.X = 0;
                            p.Velocity.Y = 0;
                            p.Velocity.Z = 0;
                            break;
                        }
                    }

                    p.Angle += timeFactor * p.AngularVelocity;

                    p.Position.X += (p.Velocity.X + p.Forces.X) * timeFactor;
                    p.Position.Y += (p.Velocity.Y + p.Forces.Y) * timeFactor;
                    p.Position.Z += (p.Velocity.Z + p.Forces.Z) * timeFactor;

                    int particleIndex = (Interlocked.Increment(ref this.aliveParticles) - 1) * 4;

                    PointSpriteVertexFormat pointVertex = default(PointSpriteVertexFormat);
                    pointVertex.Position = p.Position;
                    pointVertex.Size.X   = p.Size;
                    pointVertex.Size.Y   = p.Size;
                    pointVertex.Color    = p.Color;
                    pointVertex.VelocityAndRotation.X = p.Velocity.X;
                    pointVertex.VelocityAndRotation.Y = p.Velocity.Y;
                    pointVertex.VelocityAndRotation.Z = p.Velocity.Z;
                    pointVertex.VelocityAndRotation.W = p.Angle;

                    // Copy to Vertex Buffer

                    pointVertex.VertexTexCoords = VertexUVs[0];

                    this.vertices[particleIndex++] = pointVertex; // 0

                    pointVertex.VertexTexCoords = VertexUVs[1];

                    this.vertices[particleIndex++] = pointVertex; // 1

                    pointVertex.VertexTexCoords = VertexUVs[2];

                    this.vertices[particleIndex++] = pointVertex; // 2

                    pointVertex.VertexTexCoords = VertexUVs[3];

                    this.vertices[particleIndex++] = pointVertex; // 3
                }
            }