// 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); }
// 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; }