Пример #1
0
        //  Update position, check collisions, etc. and draw if particle still lives.
        //  Return false if particle dies/timeouts in this tick.
        public bool Draw(MyBillboard billboard)
        {
            //  Check for timeout
            int elapsedMiliseconds = MyMinerGame.TotalGamePlayTimeInMilliseconds - m_timeStarted;

            if (elapsedMiliseconds >= m_lifespanInMiliseconds)
            {
                return(false);
            }

            //  This time is scaled according to planned lifespan of the particle
            float normalizedTimeElapsed = (float)elapsedMiliseconds / (float)m_lifespanInMiliseconds;

            MyQuad  quad = new MyQuad();
            Vector3 actualPosition;

            if (m_type == MyParticleType.LINE_PARTICLE)
            {
                actualPosition  = m_startPosition;
                actualPosition += m_velocity * ((float)elapsedMiliseconds / 1000.0f);
            }
            else if (m_type == MyParticleType.LINE_PARTICLE_RELATIVE_TO_PHYS_OBJECT)
            {
                Matrix worldMatrix = m_physObject.WorldMatrix;
                actualPosition  = MyUtils.GetTransform(ref m_startPosition, ref worldMatrix);
                actualPosition += m_velocity * ((float)elapsedMiliseconds / 1000.0f);
            }
            else if (m_type == MyParticleType.LINE_PARTICLE_RELATIVE_TO_PHYS_OBJECT_COCKPIT_GLASS)
            {
                actualPosition  = MyUtils.GetTransform(ref m_startPosition, ref ((MySmallShip)m_physObject).PlayerHeadForCockpitInteriorWorldMatrix);
                actualPosition += m_velocity * ((float)elapsedMiliseconds / 1000.0f);
            }
            else if (m_type == MyParticleType.POINT_PARTICLE)
            {
                actualPosition = m_startPosition + m_velocity * ((float)elapsedMiliseconds / 1000.0f);
            }
            else if (m_type == MyParticleType.POINT_PARTICLE_RELATIVE_TO_PHYS_OBJECT)
            {
                Matrix worldMatrix = m_physObject.WorldMatrix;
                actualPosition  = MyUtils.GetTransform(ref m_startPosition, ref worldMatrix);
                actualPosition += m_velocity * ((float)elapsedMiliseconds / 1000.0f);
            }
            else
            {
                throw new MyMwcExceptionApplicationShouldNotGetHere();
            }

            // Distance for sorting
            Vector3 campos = MyCamera.Position;

            Vector3.DistanceSquared(ref campos, ref actualPosition, out billboard.DistanceSquared);

            // If distance to camera is really small don't draw it.
            if (billboard.DistanceSquared <= MyMwcMathConstants.EPSILON)
            {
                return(true);
            }

            if ((m_type == MyParticleType.LINE_PARTICLE) ||
                (m_type == MyParticleType.LINE_PARTICLE_RELATIVE_TO_PHYS_OBJECT) ||
                (m_type == MyParticleType.LINE_PARTICLE_RELATIVE_TO_PHYS_OBJECT_COCKPIT_GLASS))
            {
                float actualLength = MathHelper.Lerp(m_lineSpecific_startLength, m_lineSpecific_endLength, normalizedTimeElapsed);

                MyPolyLine polyLine;
                polyLine.LineDirectionNormalized = m_lineSpecific_directionNormalized;
                polyLine.Point0    = actualPosition;
                polyLine.Point1    = actualPosition + polyLine.LineDirectionNormalized * actualLength;
                polyLine.Thickness = m_lineSpecific_thickness;

                //  Billboard vertexes
                MyUtils.GetPolyLineQuad(out quad, ref polyLine);
            }
            else if ((m_type == MyParticleType.POINT_PARTICLE) || (m_type == MyParticleType.POINT_PARTICLE_RELATIVE_TO_PHYS_OBJECT))
            {
                //  Billboard vertexes
                float actualRadius = MathHelper.Lerp(m_pointSpecific_startRadius, m_pointSpecific_endRadius, normalizedTimeElapsed);
                float angle        = m_pointSpecific_startAngle + normalizedTimeElapsed * m_pointSpecific_rotationSpeed;
                MyUtils.GetBillboardQuadRotated(billboard, ref actualPosition, actualRadius, angle);
            }
            else
            {
                throw new MyMwcExceptionApplicationShouldNotGetHere();
            }

            //  Color and alpha depend on time
            Vector4 color;

            color.X = MathHelper.Lerp(m_startColor.X, m_endColor.X, normalizedTimeElapsed);
            color.Y = MathHelper.Lerp(m_startColor.Y, m_endColor.Y, normalizedTimeElapsed);
            color.Z = MathHelper.Lerp(m_startColor.Z, m_endColor.Z, normalizedTimeElapsed);
            color.W = MathHelper.Lerp(m_startColor.W, m_endColor.W, normalizedTimeElapsed);
            //billboard.Color.W *= 1.0f - normalizedTimeElapsed;
            //billboard.Color.W *= 1 - (float)Math.Pow(normalizedTimeElapsed, 2);
            //billboard.Color.W *= normalizedTimeElapsed * (1 - normalizedTimeElapsed) * (1 - normalizedTimeElapsed) * 6.7f;

            billboard.Start(ref quad, m_materialEnum, ref color, ref m_startPosition);

            //  Yes, draw this particle
            return(true);
        }
Пример #2
0
        //  Update position, check collisions, etc. and draw if particle still lives.
        //  Return false if particle dies/timeouts in this tick.
        public bool Draw(MyBillboard billboard)
        {
            //  Check for timeout
            int elapsedMiliseconds = MyMinerGame.TotalGamePlayTimeInMilliseconds - m_timeStarted;
            if (elapsedMiliseconds >= m_lifespanInMiliseconds) return false;

            //  This time is scaled according to planned lifespan of the particle
            float normalizedTimeElapsed = (float)elapsedMiliseconds / (float)m_lifespanInMiliseconds;

            MyQuad quad = new MyQuad();
            Vector3 actualPosition;

            if (m_type == MyParticleType.LINE_PARTICLE)
            {
                actualPosition = m_startPosition;
                actualPosition += m_velocity * ((float)elapsedMiliseconds / 1000.0f);
            }
            else if (m_type == MyParticleType.LINE_PARTICLE_RELATIVE_TO_PHYS_OBJECT)
            {
                Matrix worldMatrix = m_physObject.WorldMatrix;
                actualPosition = MyUtils.GetTransform(ref m_startPosition, ref worldMatrix);
                actualPosition += m_velocity * ((float)elapsedMiliseconds / 1000.0f);
            }
            else if (m_type == MyParticleType.LINE_PARTICLE_RELATIVE_TO_PHYS_OBJECT_COCKPIT_GLASS)
            {
                actualPosition = MyUtils.GetTransform(ref m_startPosition, ref ((MySmallShip)m_physObject).PlayerHeadForCockpitInteriorWorldMatrix);
                actualPosition += m_velocity * ((float)elapsedMiliseconds / 1000.0f);
            }            
            else if (m_type == MyParticleType.POINT_PARTICLE)
            {
                actualPosition = m_startPosition + m_velocity * ((float)elapsedMiliseconds / 1000.0f);
            }
            else if (m_type == MyParticleType.POINT_PARTICLE_RELATIVE_TO_PHYS_OBJECT)
            {
                Matrix worldMatrix = m_physObject.WorldMatrix;
                actualPosition = MyUtils.GetTransform(ref m_startPosition, ref worldMatrix);
                actualPosition += m_velocity * ((float)elapsedMiliseconds / 1000.0f);
            }
            else
            {
                throw new MyMwcExceptionApplicationShouldNotGetHere();
            }

            // Distance for sorting
            Vector3 campos = MyCamera.Position;
            Vector3.DistanceSquared(ref campos, ref actualPosition, out billboard.DistanceSquared);

            // If distance to camera is really small don't draw it.
            if (billboard.DistanceSquared <= MyMwcMathConstants.EPSILON)
            {
                return true;
            }

            if ((m_type == MyParticleType.LINE_PARTICLE) ||
                (m_type == MyParticleType.LINE_PARTICLE_RELATIVE_TO_PHYS_OBJECT) ||
                (m_type == MyParticleType.LINE_PARTICLE_RELATIVE_TO_PHYS_OBJECT_COCKPIT_GLASS))
            {
                float actualLength = MathHelper.Lerp(m_lineSpecific_startLength, m_lineSpecific_endLength, normalizedTimeElapsed);

                MyPolyLine polyLine;
                polyLine.LineDirectionNormalized = m_lineSpecific_directionNormalized;
                polyLine.Point0 = actualPosition;
                polyLine.Point1 = actualPosition + polyLine.LineDirectionNormalized * actualLength;
                polyLine.Thickness = m_lineSpecific_thickness;

                //  Billboard vertexes
                MyUtils.GetPolyLineQuad(out quad, ref polyLine);
            }
            else if ((m_type == MyParticleType.POINT_PARTICLE) || (m_type == MyParticleType.POINT_PARTICLE_RELATIVE_TO_PHYS_OBJECT))
            {
                //  Billboard vertexes
                float actualRadius = MathHelper.Lerp(m_pointSpecific_startRadius, m_pointSpecific_endRadius, normalizedTimeElapsed);
                float angle = m_pointSpecific_startAngle + normalizedTimeElapsed * m_pointSpecific_rotationSpeed;
                MyUtils.GetBillboardQuadRotated(billboard, ref actualPosition, actualRadius, angle);
            }
            else
            {
                throw new MyMwcExceptionApplicationShouldNotGetHere();
            }

            //  Color and alpha depend on time
            Vector4 color;
            color.X = MathHelper.Lerp(m_startColor.X, m_endColor.X, normalizedTimeElapsed);
            color.Y = MathHelper.Lerp(m_startColor.Y, m_endColor.Y, normalizedTimeElapsed);
            color.Z = MathHelper.Lerp(m_startColor.Z, m_endColor.Z, normalizedTimeElapsed);
            color.W = MathHelper.Lerp(m_startColor.W, m_endColor.W, normalizedTimeElapsed);
            //billboard.Color.W *= 1.0f - normalizedTimeElapsed;
            //billboard.Color.W *= 1 - (float)Math.Pow(normalizedTimeElapsed, 2);            
            //billboard.Color.W *= normalizedTimeElapsed * (1 - normalizedTimeElapsed) * (1 - normalizedTimeElapsed) * 6.7f;

            billboard.Start(ref quad, m_materialEnum, ref color, ref m_startPosition);

            //  Yes, draw this particle
            return true;
        }