示例#1
0
        private void GetFlameInfo()
        {
            // HACK copied from MyThrust's ThrustDamageAsync(), UpdateThrustFlame(), GetDamageCapsuleLine()
            Sandbox.Definitions.MyThrustDefinition thrustDef = thrust.BlockDefinition;
            float thrustLength = /* CurrentStrength * */ 10f * /* MyUtils.GetRandomFloat(0.6f, 1f) * */ thrustDef.FlameLengthScale;

            flames = new List <FlameInfo>();

            Dictionary <string, IMyModelDummy> dummies = ThrustReversersMod.Instance.Dummies;

            dummies.Clear();

            Entity.Model.GetDummies(dummies);

            foreach (IMyModelDummy dummy in dummies.Values)
            {
                if (dummy.Name.StartsWith("thruster_flame", StringComparison.InvariantCultureIgnoreCase))
                {
                    Vector3 startPosition = dummy.Matrix.Translation;
                    Vector3 direction     = Vector3.Normalize(dummy.Matrix.Forward);
                    float   radius        = Math.Max(dummy.Matrix.Scale.X, dummy.Matrix.Scale.Y) * 0.5f;
                    float   length        = thrustLength * radius * thrustDef.FlameDamageLengthScale - radius;
                    Vector3 endPosition   = startPosition + direction * length;

                    flames.Add(new FlameInfo(startPosition, endPosition, radius));
                }
            }

            dummies.Clear();
        }
示例#2
0
        public bool Draw()
        {
            if (thrust.MarkedForClose || thrust.Closed)
            {
                return(false); // remove from list
            }
            MatrixD cm = MyAPIGateway.Session.Camera.WorldMatrix;

            if (thrust.IsWorking && Vector3D.DistanceSquared(cm.Translation, thrust.WorldMatrix.Translation) <= maxViewDistSq)
            {
                if (firstFunctional)
                {
                    firstFunctional = false;
                    GetFlameInfo(); // needed here because it relies on getting dummies from the main model
                }

                float ClosedMultiplier = 1f;

                if (Reverser != null)
                {
                    if (Reverser.MarkedForClose || Reverser.Closed)
                    {
                        Reverser = null;
                    }
                    else
                    {
                        ClosedMultiplier = 1 - Reverser.ReflectedThrust;
                    }
                }

                bool paused = MyParticlesManager.Paused;
                Sandbox.Definitions.MyThrustDefinition def = thrust.BlockDefinition;
                float amount = Math.Min(thrust.CurrentStrength * 2, 1);

                if (!paused)
                {
                    float lengthTarget = Math.Max(amount, 0.25f) * length * 3f * MyUtils.GetRandomFloat(0.9f, 1.1f) * ClosedMultiplier;
                    thrustLerpLength = lengthTarget; // MathHelper.Lerp(thrustLerpLength, lengthTarget, 0.3f);

                    float thickTarget = thickness * MyUtils.GetRandomFloat(0.9f, 1.1f);
                    thrustLerpThick = thickTarget; // MathHelper.Lerp(thrustLerpThick, thickTarget, 0.2f);

                    thurstLerpColor = MathHelper.Lerp(thurstLerpColor, amount, 0.25f);
                }

                //var trailColor = Vector4.Lerp(new Vector4(1f, 0.3f, 0f, 1f) * 0.25f, new Vector4(0.5f, 0.6f, 1f, 1f) * 0.75f, thurstLerpColor);
                Vector4 trailColor  = Vector4.Lerp(new Vector4(0.5f, 0.6f, 1f, 1f) * 0.25f, new Vector4(1f, 0.3f, 0f, 1f), thurstLerpColor);
                Vector4 insideColor = trailColor;  // Vector4.Lerp(new Vector4(1f, 0.3f, 0f, 1f) * 0.5f, new Vector4(1f, 1f, 0.9f, 1f), thurstLerpColor);
                Vector4 lightColor  = insideColor; // Vector4.Lerp(new Vector4(1f, 0.3f, 0f, 1f), new Vector4(1f, 0.5f, 0.25f, 1f), thurstLerpColor);

                MatrixD    m         = thrust.WorldMatrix;
                float      gridScale = thrust.CubeGrid.GridScale;
                MyStringId material  = ThrustReversersMod.Instance.THRUST_MATERIAL;

                for (int i = 0; i < flames.Count; ++i)
                {
                    FlameInfo flame = flames[i];

                    Vector3D direction = Vector3D.TransformNormal((Vector3D)flame.Direction, m);
                    Vector3D position  = Vector3D.Transform((Vector3D)flame.LocalFrom, m);

                    Vector3D trailPos = position + (direction * trailOffset);

                    Vector3 dirToCam = Vector3.Normalize(cm.Translation - position);
                    float   dot      = Vector3.Dot(dirToCam, direction);

                    float trailAlpha  = 0.5f;
                    float pointsAlpha = 2f;

                    const float TRAIL_ANGLE_LIMIT  = 0.95f;
                    const float POINTS_ANGLE_START = 0.9f;
                    const float POINTS_ANGLE_END   = 0.35f;

                    if (dot > TRAIL_ANGLE_LIMIT)
                    {
                        trailAlpha *= 1 - ((dot - TRAIL_ANGLE_LIMIT) / (1 - TRAIL_ANGLE_LIMIT));
                    }

                    if (dot < POINTS_ANGLE_END)
                    {
                        pointsAlpha = 0;
                    }
                    else if (dot < POINTS_ANGLE_START)
                    {
                        pointsAlpha *= (dot - POINTS_ANGLE_END) / (POINTS_ANGLE_START - POINTS_ANGLE_END);
                    }

                    if (trailAlpha > 0)
                    {
                        MyTransparentGeometry.AddLineBillboard(material, trailColor * trailAlpha, trailPos, direction, thrustLerpLength, JET_FLAME_SCALE_MUL * thrustLerpThick, blendType: BLEND_TYPE);
                    }

                    if (pointsAlpha > 0)
                    {
                        MyTransparentGeometry.AddBillboardOriented(ThrustReversersMod.Instance.POINT_MATERIAL, trailColor * pointsAlpha, position + (direction * pointOffset), m.Left, m.Up, (thickness * pointScaleMul), blendType: BLEND_TYPE);
                    }

                    float   coneHeightFinal = coneHeight * (paused ? 1 : MyUtils.GetRandomFloat(0.9f, 1.1f));
                    MatrixD coneMatrix      = MatrixD.CreateWorld(position + (direction * (coneOffset + coneHeightFinal)), -direction, m.Up);
                    Color   coneColor       = new Color(insideColor);

                    DrawTransparentCone(ref coneMatrix, coneRadius, coneHeightFinal, ref coneColor, 16, ThrustReversersMod.Instance.CONE_MATERIAL, blendType: BLEND_TYPE);
                }

                // TODO reflected flames
                //if(ClosedMultiplier < 1 && amount > 0)
                //{
                //    float reflectedTrailOffset = -0.25f;
                //    float reflectedTrailHeight = 1.5f;
                //
                //    var door = (MyAdvancedDoor)Reverser.Entity;
                //
                //    foreach(var part in door.Subparts.Values)
                //    {
                //        var pm = part.WorldMatrix;
                //
                //        MyTransparentGeometry.AddBillboardOriented(ThrustReversersMod.Instance.THRUST_MATERIAL, trailColor * (1 - ClosedMultiplier), pm.Translation + (pm.Forward * reflectedTrailOffset) + pm.Up * (reflectedTrailHeight * 0.5), pm.Left, pm.Down, 0.5f, reflectedTrailHeight);
                //    }
                //}

                light.LightOn   = true;
                light.Position  = m.Translation + (m.Forward * lightOffset);
                light.Color     = lightColor;
                light.Intensity = 100 * Math.Max(trailColor.W * 2, 0.5f);
                light.Falloff   = 3f;
                light.Range     = thrustLerpThick * 2f;
                light.UpdateLight();

                lightJet.LightOn   = true;
                lightJet.Position  = m.Translation + (m.Forward * lightJetOffset);
                lightJet.Color     = trailColor;
                lightJet.Falloff   = 1f;
                lightJet.Range     = thrustLerpLength * 0.75f;
                lightJet.Intensity = 10 * trailColor.W;
                lightJet.UpdateLight();
            }
            else
            {
                if (light.LightOn)
                {
                    light.LightOn = false;
                    light.UpdateLight();
                }

                if (lightJet.LightOn)
                {
                    lightJet.LightOn = false;
                    lightJet.UpdateLight();
                }
            }

            return(true); // keep in list
        }