예제 #1
0
            public void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime, Matrix xnaTileTranslation)
            {
                var initialise = DisplayState == -1;

                if (DisplayState != SignalHead.draw_state)
                {
#if DEBUG_SIGNAL_SHAPES
                    Console.WriteLine("{5} {0} signal {1} unit {2} state: {3} --> {4}",
                                      SignalShape.Location, SignalShape.UID, Index, DisplayState,
                                      SignalHead.draw_state, InfoDisplay.FormattedTime(Viewer.Simulator.ClockTime));
#endif
                    DisplayState = SignalHead.draw_state;
                    if (SignalTypeData.DrawAspects.ContainsKey(DisplayState))
                    {
                        SemaphoreTarget = SignalTypeData.DrawAspects[DisplayState].SemaphorePos;
                        SemaphoreSpeed  = SignalTypeData.SemaphoreAnimationTime <= 0 ? 0 : (SemaphoreTarget > SemaphorePos ? +1 : -1) / SignalTypeData.SemaphoreAnimationTime;
                        if (Sound != null)
                        {
                            Sound.HandleEvent(Event.SemaphoreArm);
                        }
                    }
                }

                CumulativeTime += elapsedTime.ClockSeconds;
                while (CumulativeTime > SignalTypeData.FlashTimeTotal)
                {
                    CumulativeTime -= SignalTypeData.FlashTimeTotal;
                }

                if (DisplayState < 0 || !SignalTypeData.DrawAspects.ContainsKey(DisplayState))
                {
                    return;
                }

                if (SignalTypeData.Semaphore)
                {
                    // We reset the animation matrix before preparing the lights, because they need to be positioned
                    // based on the original matrix only.
                    foreach (AnimatedPart SemaphorePart in SemaphoreParts)
                    {
                        SemaphorePart.SetFrameWrap(0);
                    }
                }

                for (var i = 0; i < SignalTypeData.Lights.Count; i++)
                {
                    SignalLightState state         = lightStates[i];
                    bool             semaphoreDark = SemaphorePos != SemaphoreTarget && SignalTypeData.LightsSemaphoreChange[i];
                    bool             constantDark  = !SignalTypeData.DrawAspects[DisplayState].DrawLights[i];
                    bool             flashingDark  = SignalTypeData.DrawAspects[DisplayState].FlashLights[i] && (CumulativeTime > SignalTypeData.FlashTimeOn);
                    state.UpdateIntensity(semaphoreDark || constantDark || flashingDark ? 0 : 1, elapsedTime);
                    if (!state.IsIlluminated())
                    {
                        continue;
                    }

                    bool isDay;
                    if (Viewer.Settings.UseMSTSEnv == false)
                    {
                        isDay = Viewer.World.Sky.solarDirection.Y > 0;
                    }
                    else
                    {
                        isDay = Viewer.World.MSTSSky.mstsskysolarDirection.Y > 0;
                    }
                    bool isPoorVisibility = Viewer.Simulator.Weather.FogDistance < 200;
                    if (!SignalTypeData.DayLight && isDay && !isPoorVisibility)
                    {
                        continue;
                    }

                    var slp       = SignalTypeData.Lights[i];
                    var xnaMatrix = Matrix.CreateTranslation(slp.Position);

                    foreach (int MatrixIndex in MatrixIndices)
                    {
                        Matrix.Multiply(ref xnaMatrix, ref SignalShape.XNAMatrices[MatrixIndex], out xnaMatrix);
                    }
                    Matrix.Multiply(ref xnaMatrix, ref xnaTileTranslation, out xnaMatrix);

                    void renderEffect(Material material)
                    {
                        frame.AddPrimitive(material, slp, RenderPrimitiveGroup.Lights, ref xnaMatrix, ShapeFlags.None, state);
                    }

                    renderEffect(SignalTypeData.Material);
                    if (Viewer.Settings.SignalLightGlow)
                    {
                        renderEffect(SignalTypeData.GlowMaterial);
                    }
                }

                if (SignalTypeData.Semaphore)
                {
                    // Now we update and re-animate the semaphore arm.
                    if (SignalTypeData.SemaphoreAnimationTime <= 0 || initialise)
                    {
                        // No timing (so instant switch) or we're initialising.
                        SemaphorePos   = SemaphoreTarget;
                        SemaphoreSpeed = 0;
                    }
                    else
                    {
                        // Animate slowly to target position.
                        SemaphorePos += SemaphoreSpeed * elapsedTime.ClockSeconds;
                        if (SemaphorePos * Math.Sign(SemaphoreSpeed) > SemaphoreTarget * Math.Sign(SemaphoreSpeed))
                        {
                            SemaphorePos   = SemaphoreTarget;
                            SemaphoreSpeed = 0;
                        }
                    }
                    foreach (AnimatedPart SemaphorePart in SemaphoreParts)
                    {
                        SemaphorePart.SetFrameCycle(SemaphorePos);
                    }
                }
            }
예제 #2
0
            public void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime, Matrix xnaTileTranslation)
            {
                var initialise = DisplayState == -1;
                if (DisplayState != SignalHead.draw_state)
                {
#if DEBUG_SIGNAL_SHAPES
                    Console.WriteLine("{5} {0} signal {1} unit {2} state: {3} --> {4}",
                        SignalShape.Location, SignalShape.UID, Index, DisplayState,
                        SignalHead.draw_state, InfoDisplay.FormattedTime(Viewer.Simulator.ClockTime));
#endif
                    DisplayState = SignalHead.draw_state;
                    if (SignalTypeData.DrawAspects.ContainsKey(DisplayState))
                    {
                        SemaphoreTarget = SignalTypeData.DrawAspects[DisplayState].SemaphorePos;
                        SemaphoreSpeed = SignalTypeData.SemaphoreAnimationTime <= 0 ? 0 : (SemaphoreTarget > SemaphorePos ? +1 : -1) / SignalTypeData.SemaphoreAnimationTime;
                        if (Sound != null) Sound.HandleEvent(Event.SemaphoreArm);
                    }
                }

                CumulativeTime += elapsedTime.ClockSeconds;
                while (CumulativeTime > SignalTypeData.FlashTimeTotal)
                    CumulativeTime -= SignalTypeData.FlashTimeTotal;

                if (DisplayState < 0 || !SignalTypeData.DrawAspects.ContainsKey(DisplayState))
                    return;

                if (SignalTypeData.Semaphore)
                {
                    // We reset the animation matrix before preparing the lights, because they need to be positioned
                    // based on the original matrix only.
                    foreach (AnimatedPart SemaphorePart in SemaphoreParts)
                    {
                        SemaphorePart.SetFrameWrap(0);
                    }
                }

                for (var i = 0; i < SignalTypeData.Lights.Count; i++)
                {
                    if (SemaphorePos != SemaphoreTarget && SignalTypeData.LightsSemaphoreChange[i])
                        continue;
                    if (!SignalTypeData.DrawAspects[DisplayState].DrawLights[i])
                        continue;
                    if (SignalTypeData.DrawAspects[DisplayState].FlashLights[i] && (CumulativeTime > SignalTypeData.FlashTimeOn))
                        continue;

                    var xnaMatrix = Matrix.CreateTranslation(SignalTypeData.Lights[i].Position);

                    foreach (int MatrixIndex in MatrixIndices)
                    {
                        Matrix.Multiply(ref xnaMatrix, ref SignalShape.XNAMatrices[MatrixIndex], out xnaMatrix);
                    }
                    Matrix.Multiply(ref xnaMatrix, ref xnaTileTranslation, out xnaMatrix);

                    frame.AddPrimitive(SignalTypeData.Material, SignalTypeData.Lights[i], RenderPrimitiveGroup.Lights, ref xnaMatrix);
                    if (Viewer.Settings.SignalLightGlow)
                        frame.AddPrimitive(SignalTypeData.GlowMaterial, SignalTypeData.Lights[i], RenderPrimitiveGroup.Lights, ref xnaMatrix);
                }

                if (SignalTypeData.Semaphore)
                {
                    // Now we update and re-animate the semaphore arm.
                    if (SignalTypeData.SemaphoreAnimationTime <= 0 || initialise)
                    {
                        // No timing (so instant switch) or we're initialising.
                        SemaphorePos = SemaphoreTarget;
                        SemaphoreSpeed = 0;
                    }
                    else
                    {
                        // Animate slowly to target position.
                        SemaphorePos += SemaphoreSpeed * elapsedTime.ClockSeconds;
                        if (SemaphorePos * Math.Sign(SemaphoreSpeed) > SemaphoreTarget * Math.Sign(SemaphoreSpeed))
                        {
                            SemaphorePos = SemaphoreTarget;
                            SemaphoreSpeed = 0;
                        }
                    }
                    foreach (AnimatedPart SemaphorePart in SemaphoreParts)
                    {
                        SemaphorePart.SetFrameCycle(SemaphorePos);
                    }
                }
            }