/// <summary> /// Used to update information affecting the SkyMesh /// </summary> public void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime) { // Adjust dome position so the bottom edge is not visible Vector3 ViewerXNAPosition = new Vector3(MSTSSkyViewer.Camera.Location.X, MSTSSkyViewer.Camera.Location.Y - 100, -MSTSSkyViewer.Camera.Location.Z); Matrix XNASkyWorldLocation = Matrix.CreateTranslation(ViewerXNAPosition); if (mstsskyworldLoc == null) { // First time around, initialize the following items: mstsskyworldLoc = new WorldLatLon(); skySteps.OldClockTime = MSTSSkyViewer.Simulator.ClockTime % 86400; while (skySteps.OldClockTime < 0) { skySteps.OldClockTime += 86400; } skySteps.Step1 = skySteps.Step2 = (int)(skySteps.OldClockTime / 1200); skySteps.Step2 = skySteps.Step2 < skySteps.MaxSteps - 1 ? skySteps.Step2 + 1 : 0; // limit to max. steps in case activity starts near midnight // Get the current latitude and longitude coordinates mstsskyworldLoc.ConvertWTC(MSTSSkyViewer.Camera.TileX, MSTSSkyViewer.Camera.TileZ, MSTSSkyViewer.Camera.Location, ref mstsskylatitude, ref mstsskylongitude); if (mstsskyseasonType != (int)MSTSSkyViewer.Simulator.Season) { mstsskyseasonType = (int)MSTSSkyViewer.Simulator.Season; date.ordinalDate = mstsskylatitude >= 0 ? 82 + mstsskyseasonType * 91 : (82 + (mstsskyseasonType + 2) * 91) % 365; // TODO: Set the following three externally from ORTS route files (future) date.month = 1 + date.ordinalDate / 30; date.day = 21; date.year = 2017; } // Fill in the sun- and moon-position lookup tables for (int i = 0; i < skySteps.MaxSteps; i++) { mstsskysolarPosArray[i] = SunMoonPos.SolarAngle(mstsskylatitude, mstsskylongitude, ((float)i / skySteps.MaxSteps), date); mstsskylunarPosArray[i] = SunMoonPos.LunarAngle(mstsskylatitude, mstsskylongitude, ((float)i / skySteps.MaxSteps), date); } // Phase of the moon is generated at random mstsskymoonPhase = Viewer.Random.Next(8); if (mstsskymoonPhase == 6 && date.ordinalDate > 45 && date.ordinalDate < 330) { mstsskymoonPhase = 3; // Moon dog only occurs in winter } // Overcast factor: 0.0=almost no clouds; 0.1=wispy clouds; 1.0=total overcast //mstsskyovercastFactor = MSTSSkyViewer.World.WeatherControl.overcastFactor; mstsskyfogDistance = MSTSSkyViewer.Simulator.Weather.FogDistance; } MPManager manager = MPManager.Instance(); if (MPManager.IsClient() && manager.weatherChanged) { //received message about weather change if (manager.overcastFactor >= 0) { mstsskyovercastFactor = manager.overcastFactor; } //received message about weather change if (manager.fogDistance > 0) { mstsskyfogDistance = manager.fogDistance; } if (manager.overcastFactor >= 0 || manager.fogDistance > 0) { manager.weatherChanged = false; manager.overcastFactor = -1; manager.fogDistance = -1; } } ////////////////////// T E M P O R A R Y /////////////////////////// // The following keyboard commands are used for viewing sky and weather effects in "demo" mode. // Control- and Control+ for overcast, Shift- and Shift+ for fog and - and + for time. // Don't let multiplayer clients adjust the weather. if (!MPManager.IsClient()) { // Overcast ranges from 0 (completely clear) to 1 (completely overcast). if (UserInput.IsDown(UserCommand.DebugOvercastIncrease)) { mstsskyovercastFactor = MathHelper.Clamp(mstsskyovercastFactor + elapsedTime.RealSeconds / 10, 0, 1); } if (UserInput.IsDown(UserCommand.DebugOvercastDecrease)) { mstsskyovercastFactor = MathHelper.Clamp(mstsskyovercastFactor - elapsedTime.RealSeconds / 10, 0, 1); } // Fog ranges from 10m (can't see anything) to 100km (clear arctic conditions). if (UserInput.IsDown(UserCommand.DebugFogIncrease)) { mstsskyfogDistance = MathHelper.Clamp(mstsskyfogDistance - elapsedTime.RealSeconds * mstsskyfogDistance, 10, 100000); } if (UserInput.IsDown(UserCommand.DebugFogDecrease)) { mstsskyfogDistance = MathHelper.Clamp(mstsskyfogDistance + elapsedTime.RealSeconds * mstsskyfogDistance, 10, 100000); } } // Don't let clock shift if multiplayer. if (!MPManager.IsMultiPlayer()) { // Shift the clock forwards or backwards at 1h-per-second. if (UserInput.IsDown(UserCommand.DebugClockForwards)) { MSTSSkyViewer.Simulator.ClockTime += elapsedTime.RealSeconds * 3600; } if (UserInput.IsDown(UserCommand.DebugClockBackwards)) { MSTSSkyViewer.Simulator.ClockTime -= elapsedTime.RealSeconds * 3600; } } // Server needs to notify clients of weather changes. if (MPManager.IsServer()) { if (UserInput.IsReleased(UserCommand.DebugOvercastIncrease) || UserInput.IsReleased(UserCommand.DebugOvercastDecrease) || UserInput.IsReleased(UserCommand.DebugFogIncrease) || UserInput.IsReleased(UserCommand.DebugFogDecrease)) { manager.SetEnvInfo(mstsskyovercastFactor, mstsskyfogDistance); MPManager.Notify(new MSGWeather(-1, mstsskyovercastFactor, -1, mstsskyfogDistance).ToString()); } } skySteps.SetSunAndMoonDirection(ref mstsskysolarDirection, ref mstsskylunarDirection, ref mstsskysolarPosArray, ref mstsskylunarPosArray, MSTSSkyViewer.Simulator.ClockTime); frame.AddPrimitive(MSTSSkyMaterial, MSTSSkyMesh, RenderPrimitiveGroup.Sky, ref XNASkyWorldLocation); }
public static void HandleUserInput() { //In Multiplayer, I maybe the helper, but I can request to be the controller if (UserInput.IsPressed(UserCommands.GameRequestControl)) { MPManager.RequestControl(); } if (UserInput.IsPressed(UserCommands.ControlHorn)) { MPManager.Notify((new MSGEvent(MPManager.GetUserName(), "HORN", 1)).ToString()); } if (UserInput.IsReleased(UserCommands.ControlHorn)) { MPManager.Notify((new MSGEvent(MPManager.GetUserName(), "HORN", 0)).ToString()); } if (UserInput.IsPressed(UserCommands.ControlPantograph2)) { MPManager.Notify((new MSGEvent(MPManager.GetUserName(), "PANTO2", (++PantoSecondCount) % 2)).ToString()); } if (UserInput.IsPressed(UserCommands.ControlPantograph1)) { MPManager.Notify((new MSGEvent(MPManager.GetUserName(), "PANTO1", (++PantoFirstCount) % 2)).ToString()); } if (UserInput.IsPressed(UserCommands.ControlBell)) { MPManager.Notify((new MSGEvent(MPManager.GetUserName(), "BELL", 1)).ToString()); } if (UserInput.IsReleased(UserCommands.ControlBell)) { MPManager.Notify((new MSGEvent(MPManager.GetUserName(), "BELL", 0)).ToString()); } if (UserInput.IsPressed(UserCommands.ControlBellToggle)) { MPManager.Notify((new MSGEvent(MPManager.GetUserName(), "BELL", (++BellCount) % 2)).ToString()); } if (UserInput.IsPressed(UserCommands.ControlWiper)) { MPManager.Notify((new MSGEvent(MPManager.GetUserName(), "WIPER", (++WiperCount) % 2)).ToString()); } if (UserInput.IsPressed(UserCommands.ControlDoorLeft)) { MPManager.Notify((new MSGEvent(MPManager.GetUserName(), "DOORL", (++DoorLeftCount) % 2)).ToString()); } if (UserInput.IsPressed(UserCommands.ControlDoorRight)) { MPManager.Notify((new MSGEvent(MPManager.GetUserName(), "DOORR", (++DoorRightCount) % 2)).ToString()); } if (UserInput.IsPressed(UserCommands.ControlMirror)) { MPManager.Notify((new MSGEvent(MPManager.GetUserName(), "MIRRORS", (++MirrorsCount) % 2)).ToString()); } if (UserInput.IsPressed(UserCommands.ControlHeadlightIncrease)) { HeadLightCount++; if (HeadLightCount >= 3) { HeadLightCount = 2; } MPManager.Notify((new MSGEvent(MPManager.GetUserName(), "HEADLIGHT", HeadLightCount)).ToString()); } if (UserInput.IsPressed(UserCommands.ControlHeadlightDecrease)) { HeadLightCount--; if (HeadLightCount < 0) { HeadLightCount = 0; } MPManager.Notify((new MSGEvent(MPManager.GetUserName(), "HEADLIGHT", HeadLightCount)).ToString()); } }
/// <summary> /// Used to update information affecting the SkyMesh /// </summary> public void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime) { if (mstsskyseasonType != (int)MSTSSkyViewer.Simulator.Season) { mstsskyseasonType = (int)MSTSSkyViewer.Simulator.Season; date.ordinalDate = 82 + mstsskyseasonType * 91; // TODO: Set the following three externally from ORTS route files (future) date.month = 1 + date.ordinalDate / 30; date.day = 21; date.year = 2010; } // Adjust dome position so the bottom edge is not visible Vector3 ViewerXNAPosition = new Vector3(MSTSSkyViewer.Camera.Location.X, MSTSSkyViewer.Camera.Location.Y - 100, -MSTSSkyViewer.Camera.Location.Z); Matrix XNASkyWorldLocation = Matrix.CreateTranslation(ViewerXNAPosition); if (mstsskyworldLoc == null) { // First time around, initialize the following items: mstsskyworldLoc = new WorldLatLon(); mstsskyoldClockTime = MSTSSkyViewer.Simulator.ClockTime % 86400; while (mstsskyoldClockTime < 0) { mstsskyoldClockTime += 86400; } step1 = step2 = (int)(mstsskyoldClockTime / 1200); step2 = step2 < maxSteps - 1 ? step2 + 1 : 0; // limit to max. steps in case activity starts near midnight // Get the current latitude and longitude coordinates mstsskyworldLoc.ConvertWTC(MSTSSkyViewer.Camera.TileX, MSTSSkyViewer.Camera.TileZ, MSTSSkyViewer.Camera.Location, ref mstsskylatitude, ref mstsskylongitude); // Fill in the sun- and moon-position lookup tables for (int i = 0; i < maxSteps; i++) { mstsskysolarPosArray[i] = SunMoonPos.SolarAngle(mstsskylatitude, mstsskylongitude, ((float)i / maxSteps), date); mstsskylunarPosArray[i] = SunMoonPos.LunarAngle(mstsskylatitude, mstsskylongitude, ((float)i / maxSteps), date); } // Phase of the moon is generated at random mstsskymoonPhase = Viewer.Random.Next(8); if (mstsskymoonPhase == 6 && date.ordinalDate > 45 && date.ordinalDate < 330) { mstsskymoonPhase = 3; // Moon dog only occurs in winter } // Overcast factor: 0.0=almost no clouds; 0.1=wispy clouds; 1.0=total overcast //mstsskyovercastFactor = MSTSSkyViewer.World.WeatherControl.overcastFactor; mstsskyfogDistance = MSTSSkyViewer.Simulator.Weather.FogDistance; } if (Orts.MultiPlayer.MPManager.IsClient() && Orts.MultiPlayer.MPManager.Instance().weatherChanged) { //received message about weather change if (Orts.MultiPlayer.MPManager.Instance().overcastFactor >= 0) { mstsskyovercastFactor = Orts.MultiPlayer.MPManager.Instance().overcastFactor; } //received message about weather change if (Orts.MultiPlayer.MPManager.Instance().fogDistance > 0) { mstsskyfogDistance = Orts.MultiPlayer.MPManager.Instance().fogDistance; } try { if (Orts.MultiPlayer.MPManager.Instance().overcastFactor >= 0 || Orts.MultiPlayer.MPManager.Instance().fogDistance > 0) { Orts.MultiPlayer.MPManager.Instance().weatherChanged = false; Orts.MultiPlayer.MPManager.Instance().overcastFactor = -1; Orts.MultiPlayer.MPManager.Instance().fogDistance = -1; } } catch { } } ////////////////////// T E M P O R A R Y /////////////////////////// // The following keyboard commands are used for viewing sky and weather effects in "demo" mode. // Control- and Control+ for overcast, Shift- and Shift+ for fog and - and + for time. // Don't let multiplayer clients adjust the weather. if (!Orts.MultiPlayer.MPManager.IsClient()) { // Overcast ranges from 0 (completely clear) to 1 (completely overcast). if (UserInput.IsDown(UserCommands.DebugOvercastIncrease)) { mstsskyovercastFactor = MathHelper.Clamp(mstsskyovercastFactor + elapsedTime.RealSeconds / 10, 0, 1); } if (UserInput.IsDown(UserCommands.DebugOvercastDecrease)) { mstsskyovercastFactor = MathHelper.Clamp(mstsskyovercastFactor - elapsedTime.RealSeconds / 10, 0, 1); } // Fog ranges from 10m (can't see anything) to 100km (clear arctic conditions). if (UserInput.IsDown(UserCommands.DebugFogIncrease)) { mstsskyfogDistance = MathHelper.Clamp(mstsskyfogDistance - elapsedTime.RealSeconds * mstsskyfogDistance, 10, 100000); } if (UserInput.IsDown(UserCommands.DebugFogDecrease)) { mstsskyfogDistance = MathHelper.Clamp(mstsskyfogDistance + elapsedTime.RealSeconds * mstsskyfogDistance, 10, 100000); } } // Don't let clock shift if multiplayer. if (!Orts.MultiPlayer.MPManager.IsMultiPlayer()) { // Shift the clock forwards or backwards at 1h-per-second. if (UserInput.IsDown(UserCommands.DebugClockForwards)) { MSTSSkyViewer.Simulator.ClockTime += elapsedTime.RealSeconds * 3600; } if (UserInput.IsDown(UserCommands.DebugClockBackwards)) { MSTSSkyViewer.Simulator.ClockTime -= elapsedTime.RealSeconds * 3600; } } // Server needs to notify clients of weather changes. if (Orts.MultiPlayer.MPManager.IsServer()) { if (UserInput.IsReleased(UserCommands.DebugOvercastIncrease) || UserInput.IsReleased(UserCommands.DebugOvercastDecrease) || UserInput.IsReleased(UserCommands.DebugFogIncrease) || UserInput.IsReleased(UserCommands.DebugFogDecrease)) { Orts.MultiPlayer.MPManager.Instance().SetEnvInfo(mstsskyovercastFactor, mstsskyfogDistance); Orts.MultiPlayer.MPManager.Notify((new Orts.MultiPlayer.MSGWeather(-1, mstsskyovercastFactor, -1, mstsskyfogDistance)).ToString()); } } //////////////////////////////////////////////////////////////////// // Current solar and lunar position are calculated by interpolation in the lookup arrays. // Using the Lerp() function, so need to calculate the in-between differential float diff = (float)(MSTSSkyViewer.Simulator.ClockTime - mstsskyoldClockTime) / 1200; // The rest of this increments/decrements the array indices and checks for overshoot/undershoot. if (MSTSSkyViewer.Simulator.ClockTime >= (mstsskyoldClockTime + 1200)) // Plus key, or normal forward in time { step1++; step2++; mstsskyoldClockTime = MSTSSkyViewer.Simulator.ClockTime; diff = 0; if (step2 >= maxSteps) // Midnight. { step2 = 0; } if (step1 >= maxSteps) // Midnight. { step1 = 0; } } if (MSTSSkyViewer.Simulator.ClockTime <= (mstsskyoldClockTime - 1200)) // Minus key { step1--; step2--; mstsskyoldClockTime = MSTSSkyViewer.Simulator.ClockTime; diff = 0; if (step1 < 0) // Midnight. { step1 = maxSteps - 1; } if (step2 < 0) // Midnight. { step2 = maxSteps - 1; } } mstsskysolarDirection.X = MathHelper.Lerp(mstsskysolarPosArray[step1].X, mstsskysolarPosArray[step2].X, diff); mstsskysolarDirection.Y = MathHelper.Lerp(mstsskysolarPosArray[step1].Y, mstsskysolarPosArray[step2].Y, diff); mstsskysolarDirection.Z = MathHelper.Lerp(mstsskysolarPosArray[step1].Z, mstsskysolarPosArray[step2].Z, diff); mstsskylunarDirection.X = MathHelper.Lerp(mstsskylunarPosArray[step1].X, mstsskylunarPosArray[step2].X, diff); mstsskylunarDirection.Y = MathHelper.Lerp(mstsskylunarPosArray[step1].Y, mstsskylunarPosArray[step2].Y, diff); mstsskylunarDirection.Z = MathHelper.Lerp(mstsskylunarPosArray[step1].Z, mstsskylunarPosArray[step2].Z, diff); frame.AddPrimitive(MSTSSkyMaterial, MSTSSkyMesh, RenderPrimitiveGroup.Sky, ref XNASkyWorldLocation); }