static private FinishCreatingObjects ( ) : void | ||
Результат | void |
internal static void DragFile(object sender, FileDropEventArgs e) { int n = Files.Length; Array.Resize <string>(ref Files, n + 1); Files[n] = e.FileName; // reset ReducedMode = false; LightingRelative = -1.0; Game.Reset(); Textures.UnloadAllTextures(); //Fonts.Initialize(); Interface.ClearMessages(); for (int i = 0; i < Files.Length; i++) { #if !DEBUG try { #endif if (String.Compare(System.IO.Path.GetFileName(Files[i]), "extensions.cfg", StringComparison.OrdinalIgnoreCase) == 0) { UnifiedObject[] carObjects; UnifiedObject[] bogieObjects; TrainManager.Train train; ExtensionsCfgParser.ParseExtensionsConfig(Files[i], System.Text.Encoding.UTF8, out carObjects, out bogieObjects, out train, true); double z = 0.0; for (int j = 0; j < carObjects.Length; j++) { ObjectManager.CreateObject(carObjects[j], new Vector3(0.0, 0.0, z), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); if (j < train.Cars.Length - 1) { z -= (train.Cars[j].Length + train.Cars[j + 1].Length) / 2; } } } else { UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, false, false, false); ObjectManager.CreateObject(o, Vector3.Zero, new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); } #if !DEBUG } catch (Exception ex) { Interface.AddMessage(MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + "."); } #endif } ObjectManager.InitializeVisibility(); ObjectManager.FinishCreatingObjects(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); }
protected override void OnLoad(EventArgs e) { KeyDown += Program.KeyDown; KeyUp += Program.KeyUp; MouseDown += Program.MouseEvent; MouseUp += Program.MouseEvent; MouseWheel += Program.MouseWheelEvent; FileDrop += Program.DragFile; Program.ResetCamera(); Renderer.Initialize(); Renderer.InitializeLighting(); //SwapBuffers(); Fonts.Initialize(); Program.UpdateViewport(); // command line arguments // if (commandLineArgs != null) // { // for (int i = 0; i < commandLineArgs.Length; i++) // { // if (!Program.SkipArgs[i] && System.IO.File.Exists(commandLineArgs[i])) // { // try // { // ObjectManager.UnifiedObject o = ObjectManager.LoadObject(commandLineArgs[i], // System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false,0,0,0); // ObjectManager.CreateObject(o, new Vector3(0.0, 0.0, 0.0), // new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, // 0.0, 0.0, 25.0, 0.0); // } // catch (Exception ex) // { // Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + commandLineArgs[i] + "."); // } // Array.Resize<string>(ref Program.Files, Program.Files.Length + 1); // Program.Files[Program.Files.Length - 1] = commandLineArgs[i]; // } // } // } ObjectManager.InitializeVisibility(); ObjectManager.FinishCreatingObjects(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); Program.UpdateCaption(); }
internal static void DragFile(object sender, FileDropEventArgs e) { int n = Files.Length; Array.Resize <string>(ref Files, n + 1); Files[n] = e.FileName; // reset ReducedMode = false; LightingRelative = -1.0; Game.Reset(); TextureManager.UnuseAllTextures(); Fonts.Initialize(); Interface.ClearMessages(); for (int i = 0; i < Files.Length; i++) { #if !DEBUG try { #endif ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); ObjectManager.CreateObject(o, new Vector3(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); #if !DEBUG } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + "."); } #endif } ObjectManager.InitializeVisibility(); ObjectManager.FinishCreatingObjects(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); }
private static void LoadEverythingThreaded() { Program.AppendToLogFile("Loading route file: " + CurrentRouteFile); string RailwayFolder = GetRailwayFolder(CurrentRouteFile); string ObjectFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Object"); string SoundFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Sound"); // reset Game.Reset(true); Game.MinimalisticSimulation = true; // screen World.CameraTrackFollower = new TrackManager.TrackFollower { Train = null, CarIndex = -1 }; World.CameraMode = World.CameraViewMode.Interior; //First, check the format of the route file //RW routes were written for BVE1 / 2, and have a different command syntax bool IsRW = CsvRwRouteParser.isRWFile(CurrentRouteFile); Program.AppendToLogFile("Route file format is: " + (IsRW ? "RW" : "CSV")); CsvRwRouteParser.ParseRoute(CurrentRouteFile, IsRW, CurrentRouteEncoding, CurrentTrainFolder, ObjectFolder, SoundFolder, false); Thread createIllustrations = new Thread(Game.RouteInformation.LoadInformation) { IsBackground = true }; createIllustrations.Start(); System.Threading.Thread.Sleep(1); if (Cancel) { return; } Game.CalculateSeaLevelConstants(); if (Game.BogusPretrainInstructions.Length != 0) { double t = Game.BogusPretrainInstructions[0].Time; double p = Game.BogusPretrainInstructions[0].TrackPosition; for (int i = 1; i < Game.BogusPretrainInstructions.Length; i++) { if (Game.BogusPretrainInstructions[i].Time > t) { t = Game.BogusPretrainInstructions[i].Time; } else { t += 1.0; Game.BogusPretrainInstructions[i].Time = t; } if (Game.BogusPretrainInstructions[i].TrackPosition > p) { p = Game.BogusPretrainInstructions[i].TrackPosition; } else { p += 1.0; Game.BogusPretrainInstructions[i].TrackPosition = p; } } } if (Game.Stations.Length == 1) { //Log the fact that only a single station is present, as this is probably not right Program.AppendToLogFile("The processed route file only contains a single station."); } Program.AppendToLogFile("Route file loaded successfully."); RouteProgress = 1.0; // initialize trains System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainManager.Trains = new TrainManager.Train[Game.PrecedingTrainTimeDeltas.Length + 1 + (Game.BogusPretrainInstructions.Length != 0 ? 1 : 0)]; for (int k = 0; k < TrainManager.Trains.Length; k++) { TrainManager.Trains[k] = new TrainManager.Train { TrainIndex = k }; if (k == TrainManager.Trains.Length - 1 & Game.BogusPretrainInstructions.Length != 0) { TrainManager.Trains[k].State = TrainManager.TrainState.Bogus; } else { TrainManager.Trains[k].State = TrainManager.TrainState.Pending; } } TrainManager.PlayerTrain = TrainManager.Trains[Game.PrecedingTrainTimeDeltas.Length]; // load trains double TrainProgressMaximum = 0.7 + 0.3 * (double)TrainManager.Trains.Length; for (int k = 0; k < TrainManager.Trains.Length; k++) { //Sleep for 10ms to allow route loading locks to release Thread.Sleep(20); if (TrainManager.Trains[k].State == TrainManager.TrainState.Bogus) { // bogus train string TrainData = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder("Compatibility", "PreTrain"), "train.dat"); TrainDatParser.ParseTrainData(TrainData, System.Text.Encoding.UTF8, TrainManager.Trains[k]); System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainManager.Trains[k].InitializeCarSounds(); System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainProgressCurrentWeight = 0.3 / TrainProgressMaximum; TrainProgressCurrentSum += TrainProgressCurrentWeight; } else { // real train Program.AppendToLogFile("Loading player train: " + CurrentTrainFolder); TrainProgressCurrentWeight = 0.1 / TrainProgressMaximum; string TrainData = OpenBveApi.Path.CombineFile(CurrentTrainFolder, "train.dat"); TrainDatParser.ParseTrainData(TrainData, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainProgressCurrentWeight = 0.2 / TrainProgressMaximum; SoundCfgParser.ParseSoundConfig(CurrentTrainFolder, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } // door open/close speed for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { if (TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency <= 0.0) { if (TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer != null & TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer); Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer.Duration; double b = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = a + b > 0.0 ? 2.0 / (a + b) : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = a > 0.0 ? 1.0 / a : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer); double b = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = b > 0.0 ? 1.0 / b : 0.8; } else { TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = 0.8; } } if (TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency <= 0.0) { if (TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer != null & TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer); Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer.Duration; double b = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = a + b > 0.0 ? 2.0 / (a + b) : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = a > 0.0 ? 1.0 / a : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer); double b = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = b > 0.0 ? 1.0 / b : 0.8; } else { TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = 0.8; } } const double f = 0.015; const double g = 2.75; TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch = Math.Exp(f * Math.Tan(g * (Program.RandomNumberGenerator.NextDouble() - 0.5))); TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch = Math.Exp(f * Math.Tan(g * (Program.RandomNumberGenerator.NextDouble() - 0.5))); TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency /= TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency /= TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch; /* * Remove the following two lines, then the pitch at which doors play * takes their randomized opening and closing times into account. * */ TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch = 1.0; TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch = 1.0; } } for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { TrainManager.Trains[k].Cars[i].FrontAxle.Follower.Train = TrainManager.Trains[k]; TrainManager.Trains[k].Cars[i].RearAxle.Follower.Train = TrainManager.Trains[k]; TrainManager.Trains[k].Cars[i].BeaconReceiver.Train = TrainManager.Trains[k]; } // add panel section if (k == TrainManager.PlayerTrain.TrainIndex) { TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections = new TrainManager.CarSection[1]; TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections[0].Elements = new ObjectManager.AnimatedObject[] { }; TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections[0].Overlay = true; TrainProgressCurrentWeight = 0.7 / TrainProgressMaximum; TrainManager.ParsePanelConfig(CurrentTrainFolder, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } Program.AppendToLogFile("Train panel loaded sucessfully."); } // add exterior section if (TrainManager.Trains[k].State != TrainManager.TrainState.Bogus) { ObjectManager.UnifiedObject[] CarObjects; ObjectManager.UnifiedObject[] BogieObjects; ExtensionsCfgParser.ParseExtensionsConfig(CurrentTrainFolder, CurrentTrainEncoding, out CarObjects, out BogieObjects, TrainManager.Trains[k]); System.Threading.Thread.Sleep(1); if (Cancel) { return; } //Stores the current array index of the bogie object to add //Required as there are two bogies per car, and we're using a simple linear array.... int currentBogieObject = 0; for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { if (CarObjects[i] == null) { // load default exterior object string file = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder("Compatibility"), "exterior.csv"); ObjectManager.StaticObject so = ObjectManager.LoadStaticObject(file, System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); if (so == null) { CarObjects[i] = null; } else { double sx = TrainManager.Trains[k].Cars[i].Width; double sy = TrainManager.Trains[k].Cars[i].Height; double sz = TrainManager.Trains[k].Cars[i].Length; CsvB3dObjectParser.ApplyScale(so, sx, sy, sz); CarObjects[i] = so; } } if (CarObjects[i] != null) { // add object int j = TrainManager.Trains[k].Cars[i].CarSections.Length; Array.Resize <TrainManager.CarSection>(ref TrainManager.Trains[k].Cars[i].CarSections, j + 1); if (CarObjects[i] is ObjectManager.StaticObject) { ObjectManager.StaticObject s = (ObjectManager.StaticObject)CarObjects[i]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements = new ObjectManager.AnimatedObject[1]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0] = new ObjectManager.AnimatedObject(); TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].States = new ObjectManager.AnimatedObjectState[1]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].States[0].Position = new Vector3(0.0, 0.0, 0.0); TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].States[0].Object = s; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].CurrentState = 0; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].ObjectIndex = ObjectManager.CreateDynamicObject(); } else if (CarObjects[i] is ObjectManager.AnimatedObjectCollection) { ObjectManager.AnimatedObjectCollection a = (ObjectManager.AnimatedObjectCollection)CarObjects[i]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements = new ObjectManager.AnimatedObject[a.Objects.Length]; for (int h = 0; h < a.Objects.Length; h++) { TrainManager.Trains[k].Cars[i].CarSections[j].Elements[h] = a.Objects[h]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[h].ObjectIndex = ObjectManager.CreateDynamicObject(); } } } //Load bogie objects if (BogieObjects[currentBogieObject] != null) { int j = TrainManager.Trains[k].Cars[i].FrontBogie.CarSections.Length; Array.Resize <TrainManager.CarSection>(ref TrainManager.Trains[k].Cars[i].FrontBogie.CarSections, j + 1); if (BogieObjects[currentBogieObject] is ObjectManager.StaticObject) { ObjectManager.StaticObject s = (ObjectManager.StaticObject)BogieObjects[currentBogieObject]; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements = new ObjectManager.AnimatedObject[1]; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[0] = new ObjectManager.AnimatedObject(); TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[0].States = new ObjectManager.AnimatedObjectState[1]; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[0].States[0].Position = new Vector3(0.0, 0.0, 0.0); TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[0].States[0].Object = s; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[0].CurrentState = 0; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[0].ObjectIndex = ObjectManager.CreateDynamicObject(); } else if (BogieObjects[currentBogieObject] is ObjectManager.AnimatedObjectCollection) { ObjectManager.AnimatedObjectCollection a = (ObjectManager.AnimatedObjectCollection)BogieObjects[currentBogieObject]; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements = new ObjectManager.AnimatedObject[a.Objects.Length]; for (int h = 0; h < a.Objects.Length; h++) { TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[h] = a.Objects[h]; TrainManager.Trains[k].Cars[i].FrontBogie.CarSections[j].Elements[h].ObjectIndex = ObjectManager.CreateDynamicObject(); } } } currentBogieObject++; //Can't think of a better way to do this than two functions...... if (BogieObjects[currentBogieObject] != null) { int j = TrainManager.Trains[k].Cars[i].RearBogie.CarSections.Length; Array.Resize <TrainManager.CarSection>(ref TrainManager.Trains[k].Cars[i].RearBogie.CarSections, j + 1); if (BogieObjects[currentBogieObject] is ObjectManager.StaticObject) { ObjectManager.StaticObject s = (ObjectManager.StaticObject)BogieObjects[currentBogieObject]; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements = new ObjectManager.AnimatedObject[1]; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[0] = new ObjectManager.AnimatedObject(); TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[0].States = new ObjectManager.AnimatedObjectState[1]; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[0].States[0].Position = new Vector3(0.0, 0.0, 0.0); TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[0].States[0].Object = s; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[0].CurrentState = 0; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[0].ObjectIndex = ObjectManager.CreateDynamicObject(); } else if (BogieObjects[currentBogieObject] is ObjectManager.AnimatedObjectCollection) { ObjectManager.AnimatedObjectCollection a = (ObjectManager.AnimatedObjectCollection)BogieObjects[currentBogieObject]; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements = new ObjectManager.AnimatedObject[a.Objects.Length]; for (int h = 0; h < a.Objects.Length; h++) { TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[h] = a.Objects[h]; TrainManager.Trains[k].Cars[i].RearBogie.CarSections[j].Elements[h].ObjectIndex = ObjectManager.CreateDynamicObject(); } } } currentBogieObject++; } } // place cars { double z = 0.0; for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { //Front axle track position TrainManager.Trains[k].Cars[i].FrontAxle.Follower.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].FrontAxle.Position; //Bogie for front axle TrainManager.Trains[k].Cars[i].FrontBogie.FrontAxle.Follower.TrackPosition = TrainManager.Trains[k].Cars[i].FrontAxle.Follower.TrackPosition - 0.5 * TrainManager.Trains[k].Cars[i].FrontBogie.Length + TrainManager.Trains[k].Cars[i].FrontBogie.FrontAxle.Position; TrainManager.Trains[k].Cars[i].FrontBogie.RearAxle.Follower.TrackPosition = TrainManager.Trains[k].Cars[i].FrontAxle.Follower.TrackPosition - 0.5 * TrainManager.Trains[k].Cars[i].FrontBogie.Length + TrainManager.Trains[k].Cars[i].FrontBogie.RearAxle.Position; //Rear axle track position TrainManager.Trains[k].Cars[i].RearAxle.Follower.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].RearAxle.Position; //Bogie for rear axle TrainManager.Trains[k].Cars[i].RearBogie.FrontAxle.Follower.TrackPosition = TrainManager.Trains[k].Cars[i].RearAxle.Follower.TrackPosition - 0.5 * TrainManager.Trains[k].Cars[i].RearBogie.Length + TrainManager.Trains[k].Cars[i].RearBogie.FrontAxle.Position; TrainManager.Trains[k].Cars[i].RearBogie.RearAxle.Follower.TrackPosition = TrainManager.Trains[k].Cars[i].RearAxle.Follower.TrackPosition - 0.5 * TrainManager.Trains[k].Cars[i].RearBogie.Length + TrainManager.Trains[k].Cars[i].RearBogie.RearAxle.Position; //Beacon reciever (AWS, ATC etc.) TrainManager.Trains[k].Cars[i].BeaconReceiver.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].BeaconReceiverPosition; z -= TrainManager.Trains[k].Cars[i].Length; if (i < TrainManager.Trains[k].Cars.Length - 1) { z -= 0.5 * (TrainManager.Trains[k].Couplers[i].MinimumDistanceBetweenCars + TrainManager.Trains[k].Couplers[i].MaximumDistanceBetweenCars); } } } // configure ai / timetable if (TrainManager.Trains[k] == TrainManager.PlayerTrain) { TrainManager.Trains[k].TimetableDelta = 0.0; } else if (TrainManager.Trains[k].State != TrainManager.TrainState.Bogus) { TrainManager.Trains[k].AI = new Game.SimpleHumanDriverAI(TrainManager.Trains[k]); TrainManager.Trains[k].TimetableDelta = Game.PrecedingTrainTimeDeltas[k]; TrainManager.Trains[k].Specs.DoorOpenMode = TrainManager.DoorMode.Manual; TrainManager.Trains[k].Specs.DoorCloseMode = TrainManager.DoorMode.Manual; } } TrainProgress = 1.0; // finished created objects System.Threading.Thread.Sleep(1); if (Cancel) { return; } ObjectManager.FinishCreatingObjects(); // update sections if (Game.Sections.Length > 0) { Game.UpdateSection(Game.Sections.Length - 1); } // load plugin for (int i = 0; i < TrainManager.Trains.Length; i++) { if (TrainManager.Trains[i].State != TrainManager.TrainState.Bogus) { if (TrainManager.Trains[i] == TrainManager.PlayerTrain) { if (!PluginManager.LoadCustomPlugin(TrainManager.Trains[i], CurrentTrainFolder, CurrentTrainEncoding)) { PluginManager.LoadDefaultPlugin(TrainManager.Trains[i], CurrentTrainFolder); } } else { PluginManager.LoadDefaultPlugin(TrainManager.Trains[i], CurrentTrainFolder); } } } }
// process events internal static void KeyDown(object sender, KeyboardKeyEventArgs e) { switch (e.Key) { case Key.LShift: case Key.RShift: ShiftPressed = true; break; case Key.F5: // reset ReducedMode = false; LightingRelative = -1.0; Game.Reset(); Textures.UnloadAllTextures(); //Fonts.Initialize(); Interface.ClearMessages(); for (int i = 0; i < Files.Length; i++) { #if !DEBUG try { #endif if (String.Compare(System.IO.Path.GetFileName(Files[i]), "extensions.cfg", StringComparison.OrdinalIgnoreCase) == 0) { UnifiedObject[] carObjects; UnifiedObject[] bogieObjects; double[] axleLocations; TrainManager.Train train; ExtensionsCfgParser.ParseExtensionsConfig(Files[i], System.Text.Encoding.UTF8, out carObjects, out bogieObjects, out axleLocations, out train, true); if (axleLocations.Length == 0) { axleLocations = new double[train.Cars.Length * 2]; for (int j = 0; j < train.Cars.Length; j++) { double ap = train.Cars.Length * 0.4; axleLocations[j] = ap; j++; axleLocations[j] = -ap; } } double z = 0.0; for (int j = 0; j < carObjects.Length; j++) { ObjectManager.CreateObject(carObjects[j], new Vector3(0.0, 0.0, z), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); if (j < train.Cars.Length - 1) { z -= (train.Cars[j].Length + train.Cars[j + 1].Length) / 2; } } z = 0.0; for (int j = 0; j < bogieObjects.Length; j++) { ObjectManager.CreateObject(bogieObjects[j], new Vector3(0.0, 0.0, z + axleLocations[j]), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); j++; ObjectManager.CreateObject(bogieObjects[j], new Vector3(0.0, 0.0, z - axleLocations[j]), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); if (j < train.Cars.Length - 1) { z -= (train.Cars[j].Length + train.Cars[j + 1].Length) / 2; } } } else { UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, false, false, false); ObjectManager.CreateObject(o, Vector3.Zero, new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); } #if !DEBUG } catch (Exception ex) { Interface.AddMessage(MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + "."); } #endif } ObjectManager.InitializeVisibility(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); break; case Key.F7: { OpenFileDialog Dialog = new OpenFileDialog { CheckFileExists = true, Multiselect = true, Filter = @"All supported object files|*.csv;*.b3d;*.x;*.animated;extensions.cfg;*.l3dobj;*.l3dgrp;*.obj;*.s|openBVE Objects|*.csv;*.b3d;*.x;*.animated;extensions.cfg|LokSim 3D Objects|*.l3dobj;*.l3dgrp|Wavefront Objects|*.obj|Microsoft Train Simulator Objects|*.s|All files|*" }; if (Dialog.ShowDialog() == DialogResult.OK) { Application.DoEvents(); string[] f = Dialog.FileNames; int n = Files.Length; Array.Resize <string>(ref Files, n + f.Length); for (int i = 0; i < f.Length; i++) { Files[n + i] = f[i]; } // reset ReducedMode = false; LightingRelative = -1.0; Game.Reset(); Textures.UnloadAllTextures(); Interface.ClearMessages(); for (int i = 0; i < Files.Length; i++) { #if !DEBUG try { #endif if (String.Compare(System.IO.Path.GetFileName(Files[i]), "extensions.cfg", StringComparison.OrdinalIgnoreCase) == 0) { UnifiedObject[] carObjects; UnifiedObject[] bogieObjects; double[] axleLocations; TrainManager.Train train; ExtensionsCfgParser.ParseExtensionsConfig(Files[i], System.Text.Encoding.UTF8, out carObjects, out bogieObjects, out axleLocations, out train, true); if (axleLocations.Length == 0) { axleLocations = new double[train.Cars.Length * 2]; for (int j = 0; j < train.Cars.Length; j++) { double ap = train.Cars.Length * 0.4; axleLocations[j] = ap; j++; axleLocations[j] = -ap; } } double z = 0.0; for (int j = 0; j < carObjects.Length; j++) { ObjectManager.CreateObject(carObjects[j], new Vector3(0.0, 0.0, z), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); if (j < train.Cars.Length - 1) { z -= (train.Cars[j].Length + train.Cars[j + 1].Length) / 2; } } z = 0.0; for (int j = 0; j < bogieObjects.Length; j++) { ObjectManager.CreateObject(bogieObjects[j], new Vector3(0.0, 0.0, z + axleLocations[j]), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); j++; ObjectManager.CreateObject(bogieObjects[j], new Vector3(0.0, 0.0, z - axleLocations[j]), new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); if (j < train.Cars.Length - 1) { z -= (train.Cars[j].Length + train.Cars[j + 1].Length) / 2; } } } else { UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, false, false, false); ObjectManager.CreateObject(o, Vector3.Zero, new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); } #if !DEBUG } catch (Exception ex) { Interface.AddMessage(MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + "."); } #endif } ObjectManager.InitializeVisibility(); ObjectManager.FinishCreatingObjects(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); } else { if (Program.CurrentlyRunOnMono) { //HACK: Dialog doesn't close properly when pressing the ESC key under Mono //Avoid calling Application.DoEvents() unless absolutely necessary though! Application.DoEvents(); } } Dialog.Dispose(); } break; case Key.F9: if (Interface.MessageCount != 0) { formMessages.ShowMessages(); Application.DoEvents(); } break; case Key.Delete: ReducedMode = false; LightingRelative = -1.0; Game.Reset(); Textures.UnloadAllTextures(); //Fonts.Initialize(); Interface.ClearMessages(); Files = new string[] { }; break; case Key.Left: RotateX = -1; ReducedMode = false; break; case Key.Right: RotateX = 1; ReducedMode = false; break; case Key.Up: RotateY = -1; ReducedMode = false; break; case Key.Down: RotateY = 1; ReducedMode = false; break; case Key.A: case Key.Keypad4: MoveX = -1; ReducedMode = false; break; case Key.D: case Key.Keypad6: MoveX = 1; ReducedMode = false; break; case Key.Keypad8: MoveY = 1; ReducedMode = false; break; case Key.Keypad2: MoveY = -1; ReducedMode = false; break; case Key.W: case Key.Keypad9: MoveZ = 1; ReducedMode = false; break; case Key.S: case Key.Keypad3: MoveZ = -1; ReducedMode = false; break; case Key.Keypad5: ResetCamera(); break; case Key.F: case Key.F1: Renderer.OptionWireframe = !Renderer.OptionWireframe; if (Renderer.OptionWireframe) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); } else { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); } break; case Key.N: case Key.F2: Renderer.OptionNormals = !Renderer.OptionNormals; break; case Key.L: case Key.F3: LightingTarget = 1 - LightingTarget; ReducedMode = false; break; case Key.I: case Key.F4: Renderer.OptionInterface = !Renderer.OptionInterface; ReducedMode = false; break; case Key.F8: formOptions.ShowOptions(); Application.DoEvents(); break; case Key.F10: formTrain.ShowTrainSettings(); break; case Key.G: case Key.C: Renderer.OptionCoordinateSystem = !Renderer.OptionCoordinateSystem; ReducedMode = false; break; case Key.B: if (ShiftPressed) { ColorDialog dialog = new ColorDialog(); dialog.FullOpen = true; if (dialog.ShowDialog() == DialogResult.OK) { Renderer.BackgroundColor = -1; Renderer.ApplyBackgroundColor(dialog.Color.R, dialog.Color.G, dialog.Color.B); } } else { Renderer.BackgroundColor++; if (Renderer.BackgroundColor >= Renderer.MaxBackgroundColor) { Renderer.BackgroundColor = 0; } Renderer.ApplyBackgroundColor(); } ReducedMode = false; break; } }
private static void LoadEverythingThreaded() { string RailwayFolder = GetRailwayFolder(CurrentRouteFile); string ObjectFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Object"); string SoundFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Sound"); // string CompatibilityFolder = OpenBveApi.Path.CombineDirectory(Application.StartupPath, "Compatibility"); // reset Game.Reset(); Game.MinimalisticSimulation = true; // screen World.CameraTrackFollower = new TrackManager.TrackFollower(); World.CameraTrackFollower.Train = null; World.CameraTrackFollower.CarIndex = -1; Camera.CurrentMode = CameraViewMode.Track; // load route bool IsRW = string.Equals(System.IO.Path.GetExtension(CurrentRouteFile), ".rw", StringComparison.OrdinalIgnoreCase); CsvRwRouteParser.ParseRoute(CurrentRouteFile, IsRW, CurrentRouteEncoding, Application.StartupPath, ObjectFolder, SoundFolder, false); System.Threading.Thread.Sleep(1); if (Cancel) { return; } Atmosphere.CalculateSeaLevelConstants(); RouteProgress = 1.0; // camera ObjectManager.InitializeVisibility(); TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, 0.0, true, false); TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, 0.1, true, false); TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, -0.1, true, false); World.CameraTrackFollower.TriggerType = EventTriggerType.Camera; // default starting time Game.SecondsSinceMidnight = 0.0; Game.StartupTime = 0.0; // finished created objects System.Threading.Thread.Sleep(1); if (Cancel) { return; } ObjectManager.FinishCreatingObjects(); // signals System.Threading.Thread.Sleep(1); if (Cancel) { return; } if (CurrentRoute.Sections.Length > 0) { Game.UpdateSection(CurrentRoute.Sections.Length - 1); } // starting track position System.Threading.Thread.Sleep(1); if (Cancel) { return; } // int FirstStationIndex = -1; double FirstStationPosition = 0.0; for (int i = 0; i < CurrentRoute.Stations.Length; i++) { if (CurrentRoute.Stations[i].Stops.Length != 0) { // FirstStationIndex = i; FirstStationPosition = CurrentRoute.Stations[i].Stops[CurrentRoute.Stations[i].Stops.Length - 1].TrackPosition; if (CurrentRoute.Stations[i].ArrivalTime < 0.0) { if (CurrentRoute.Stations[i].DepartureTime < 0.0) { Game.SecondsSinceMidnight = 0.0; } else { Game.SecondsSinceMidnight = CurrentRoute.Stations[i].DepartureTime - CurrentRoute.Stations[i].StopTime; } } else { Game.SecondsSinceMidnight = CurrentRoute.Stations[i].ArrivalTime; } Game.StartupTime = Game.SecondsSinceMidnight; break; } } // initialize camera TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, -1.0, true, false); TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, FirstStationPosition, true, false); Camera.CurrentAlignment = new CameraAlignment(new Vector3(0.0, 2.5, 0.0), 0.0, 0.0, 0.0, FirstStationPosition, 1.0); World.UpdateAbsoluteCamera(0.0); ObjectManager.UpdateVisibility(World.CameraTrackFollower.TrackPosition + Camera.CurrentAlignment.Position.Z); }
private static void LoadEverythingThreaded() { string RailwayFolder = GetRailwayFolder(CurrentRouteFile); // if (RailwayFolder == null) { // Interface.AddMessage(Interface.MessageType.Critical, false, "The Railway folder could not be found. Please check your folder structure."); // return; // } string ObjectFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Object"); string SoundFolder = OpenBveApi.Path.CombineDirectory(RailwayFolder, "Sound"); // reset Game.Reset(true); Game.MinimalisticSimulation = true; // screen World.CameraTrackFollower = new TrackManager.TrackFollower(); World.CameraTrackFollower.Train = null; World.CameraTrackFollower.CarIndex = -1; World.CameraMode = World.CameraViewMode.Interior; // load route bool IsRW = string.Equals(System.IO.Path.GetExtension(CurrentRouteFile), ".rw", StringComparison.OrdinalIgnoreCase); CsvRwRouteParser.ParseRoute(CurrentRouteFile, IsRW, CurrentRouteEncoding, CurrentTrainFolder, ObjectFolder, SoundFolder, false); System.Threading.Thread.Sleep(1); if (Cancel) { return; } Game.CalculateSeaLevelConstants(); if (Game.BogusPretrainInstructions.Length != 0) { double t = Game.BogusPretrainInstructions[0].Time; double p = Game.BogusPretrainInstructions[0].TrackPosition; for (int i = 1; i < Game.BogusPretrainInstructions.Length; i++) { if (Game.BogusPretrainInstructions[i].Time > t) { t = Game.BogusPretrainInstructions[i].Time; } else { t += 1.0; Game.BogusPretrainInstructions[i].Time = t; } if (Game.BogusPretrainInstructions[i].TrackPosition > p) { p = Game.BogusPretrainInstructions[i].TrackPosition; } else { p += 1.0; Game.BogusPretrainInstructions[i].TrackPosition = p; } } } RouteProgress = 1.0; // initialize trains System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainManager.Trains = new TrainManager.Train[Game.PrecedingTrainTimeDeltas.Length + 1 + (Game.BogusPretrainInstructions.Length != 0 ? 1 : 0)]; for (int k = 0; k < TrainManager.Trains.Length; k++) { TrainManager.Trains[k] = new TrainManager.Train(); TrainManager.Trains[k].TrainIndex = k; if (k == TrainManager.Trains.Length - 1 & Game.BogusPretrainInstructions.Length != 0) { TrainManager.Trains[k].State = TrainManager.TrainState.Bogus; } else { TrainManager.Trains[k].State = TrainManager.TrainState.Pending; } } TrainManager.PlayerTrain = TrainManager.Trains[Game.PrecedingTrainTimeDeltas.Length]; // load trains double TrainProgressMaximum = 0.7 + 0.3 * (double)TrainManager.Trains.Length; for (int k = 0; k < TrainManager.Trains.Length; k++) { if (TrainManager.Trains[k].State == TrainManager.TrainState.Bogus) { // bogus train string Folder = Program.FileSystem.GetDataFolder("Compatibility", "PreTrain"); TrainDatParser.ParseTrainData(Folder, System.Text.Encoding.UTF8, TrainManager.Trains[k]); System.Threading.Thread.Sleep(1); if (Cancel) { return; } SoundCfgParser.LoadNoSound(TrainManager.Trains[k]); System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainProgressCurrentWeight = 0.3 / TrainProgressMaximum; TrainProgressCurrentSum += TrainProgressCurrentWeight; } else { // real train TrainProgressCurrentWeight = 0.1 / TrainProgressMaximum; TrainDatParser.ParseTrainData(CurrentTrainFolder, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } TrainProgressCurrentWeight = 0.2 / TrainProgressMaximum; SoundCfgParser.ParseSoundConfig(CurrentTrainFolder, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } // door open/close speed for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { if (TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency <= 0.0) { if (TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer != null & TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer); Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer.Duration; double b = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = a + b > 0.0 ? 2.0 / (a + b) : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = a > 0.0 ? 1.0 / a : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorOpenL.Buffer); double b = TrainManager.Trains[k].Cars[i].Sounds.DoorOpenR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = b > 0.0 ? 1.0 / b : 0.8; } else { TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency = 0.8; } } if (TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency <= 0.0) { if (TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer != null & TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer); Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer.Duration; double b = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = a + b > 0.0 ? 2.0 / (a + b) : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer); double a = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = a > 0.0 ? 1.0 / a : 0.8; } else if (TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer != null) { Sounds.LoadBuffer(TrainManager.Trains[k].Cars[i].Sounds.DoorCloseL.Buffer); double b = TrainManager.Trains[k].Cars[i].Sounds.DoorCloseR.Buffer.Duration; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = b > 0.0 ? 1.0 / b : 0.8; } else { TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency = 0.8; } } const double f = 0.015; const double g = 2.75; TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch = Math.Exp(f * Math.Tan(g * (Program.RandomNumberGenerator.NextDouble() - 0.5))); TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch = Math.Exp(f * Math.Tan(g * (Program.RandomNumberGenerator.NextDouble() - 0.5))); TrainManager.Trains[k].Cars[i].Specs.DoorOpenFrequency /= TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch; TrainManager.Trains[k].Cars[i].Specs.DoorCloseFrequency /= TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch; /* * Remove the following two lines, then the pitch at which doors play * takes their randomized opening and closing times into account. * */ TrainManager.Trains[k].Cars[i].Specs.DoorOpenPitch = 1.0; TrainManager.Trains[k].Cars[i].Specs.DoorClosePitch = 1.0; } } for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { TrainManager.Trains[k].Cars[i].FrontAxle.Follower.Train = TrainManager.Trains[k]; TrainManager.Trains[k].Cars[i].RearAxle.Follower.Train = TrainManager.Trains[k]; TrainManager.Trains[k].Cars[i].BeaconReceiver.Train = TrainManager.Trains[k]; } // add panel section if (k == TrainManager.PlayerTrain.TrainIndex) { TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections = new TrainManager.CarSection[1]; TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections[0].Elements = new ObjectManager.AnimatedObject[] { }; TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections[0].Overlay = true; TrainProgressCurrentWeight = 0.7 / TrainProgressMaximum; TrainManager.ParsePanelConfig(CurrentTrainFolder, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; System.Threading.Thread.Sleep(1); if (Cancel) { return; } } // add exterior section if (TrainManager.Trains[k].State != TrainManager.TrainState.Bogus) { ObjectManager.UnifiedObject[] CarObjects; ExtensionsCfgParser.ParseExtensionsConfig(CurrentTrainFolder, CurrentTrainEncoding, out CarObjects, TrainManager.Trains[k]); System.Threading.Thread.Sleep(1); if (Cancel) { return; } for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { if (CarObjects[i] == null) { // load default exterior object string file = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder("Compatibility"), "exterior.csv"); ObjectManager.StaticObject so = ObjectManager.LoadStaticObject(file, System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); if (so == null) { CarObjects[i] = null; } else { double sx = TrainManager.Trains[k].Cars[i].Width; double sy = TrainManager.Trains[k].Cars[i].Height; double sz = TrainManager.Trains[k].Cars[i].Length; CsvB3dObjectParser.ApplyScale(so, sx, sy, sz); CarObjects[i] = so; } } if (CarObjects[i] != null) { // add object int j = TrainManager.Trains[k].Cars[i].CarSections.Length; Array.Resize <TrainManager.CarSection>(ref TrainManager.Trains[k].Cars[i].CarSections, j + 1); if (CarObjects[i] is ObjectManager.StaticObject) { ObjectManager.StaticObject s = (ObjectManager.StaticObject)CarObjects[i]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements = new ObjectManager.AnimatedObject[1]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0] = new ObjectManager.AnimatedObject(); TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].States = new ObjectManager.AnimatedObjectState[1]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].States[0].Position = new Vector3(0.0, 0.0, 0.0); TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].States[0].Object = s; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].CurrentState = 0; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[0].ObjectIndex = ObjectManager.CreateDynamicObject(); } else if (CarObjects[i] is ObjectManager.AnimatedObjectCollection) { ObjectManager.AnimatedObjectCollection a = (ObjectManager.AnimatedObjectCollection)CarObjects[i]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements = new ObjectManager.AnimatedObject[a.Objects.Length]; for (int h = 0; h < a.Objects.Length; h++) { TrainManager.Trains[k].Cars[i].CarSections[j].Elements[h] = a.Objects[h]; TrainManager.Trains[k].Cars[i].CarSections[j].Elements[h].ObjectIndex = ObjectManager.CreateDynamicObject(); } } } } } // place cars { double z = 0.0; for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { TrainManager.Trains[k].Cars[i].FrontAxle.Follower.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].FrontAxlePosition; TrainManager.Trains[k].Cars[i].RearAxle.Follower.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].RearAxlePosition; TrainManager.Trains[k].Cars[i].BeaconReceiver.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].BeaconReceiverPosition; z -= TrainManager.Trains[k].Cars[i].Length; if (i < TrainManager.Trains[k].Cars.Length - 1) { z -= 0.5 * (TrainManager.Trains[k].Couplers[i].MinimumDistanceBetweenCars + TrainManager.Trains[k].Couplers[i].MaximumDistanceBetweenCars); } } } // configure ai / timetable if (TrainManager.Trains[k] == TrainManager.PlayerTrain) { TrainManager.Trains[k].TimetableDelta = 0.0; } else if (TrainManager.Trains[k].State != TrainManager.TrainState.Bogus) { TrainManager.Trains[k].AI = new Game.SimpleHumanDriverAI(TrainManager.Trains[k]); TrainManager.Trains[k].TimetableDelta = Game.PrecedingTrainTimeDeltas[k]; TrainManager.Trains[k].Specs.DoorOpenMode = TrainManager.DoorMode.Manual; TrainManager.Trains[k].Specs.DoorCloseMode = TrainManager.DoorMode.Manual; } } TrainProgress = 1.0; // finished created objects System.Threading.Thread.Sleep(1); if (Cancel) { return; } ObjectManager.FinishCreatingObjects(); // update sections if (Game.Sections.Length > 0) { Game.UpdateSection(Game.Sections.Length - 1); } // load plugin for (int i = 0; i < TrainManager.Trains.Length; i++) { if (TrainManager.Trains[i].State != TrainManager.TrainState.Bogus) { if (TrainManager.Trains[i] == TrainManager.PlayerTrain) { if (!PluginManager.LoadCustomPlugin(TrainManager.Trains[i], CurrentTrainFolder, CurrentTrainEncoding)) { PluginManager.LoadDefaultPlugin(TrainManager.Trains[i], CurrentTrainFolder); } } else { PluginManager.LoadDefaultPlugin(TrainManager.Trains[i], CurrentTrainFolder); } } } }
// process events internal static void KeyDown(object sender, KeyboardKeyEventArgs e) { switch (e.Key) { case Key.LShift: case Key.RShift: ShiftPressed = true; break; case Key.F5: // reset ReducedMode = false; LightingRelative = -1.0; Game.Reset(); TextureManager.UnuseAllTextures(); Fonts.Initialize(); Interface.ClearMessages(); for (int i = 0; i < Files.Length; i++) { #if !DEBUG try { #endif ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); ObjectManager.CreateObject(o, new Vector3(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); #if !DEBUG } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + "."); } #endif } ObjectManager.InitializeVisibility(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); break; case Key.F7: { OpenFileDialog Dialog = new OpenFileDialog(); Dialog.CheckFileExists = true; Dialog.Multiselect = true; Dialog.Filter = "CSV/B3D/X/ANIMATED files|*.csv;*.b3d;*.x;*.animated;*.l3dobj;*.l3dgrp|All files|*"; if (Dialog.ShowDialog() == DialogResult.OK) { Application.DoEvents(); string[] f = Dialog.FileNames; int n = Files.Length; Array.Resize <string>(ref Files, n + f.Length); for (int i = 0; i < f.Length; i++) { Files[n + i] = f[i]; } // reset ReducedMode = false; LightingRelative = -1.0; Game.Reset(); TextureManager.UnuseAllTextures(); Fonts.Initialize(); Interface.ClearMessages(); for (int i = 0; i < Files.Length; i++) { #if !DEBUG try { #endif ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); ObjectManager.CreateObject(o, new Vector3(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); #if !DEBUG } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + "."); } #endif } ObjectManager.InitializeVisibility(); ObjectManager.FinishCreatingObjects(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); } else { if (Program.CurrentlyRunOnMono) { //HACK: Dialog doesn't close properly when pressing the ESC key under Mono //Avoid calling Application.DoEvents() unless absolutely necessary though! Application.DoEvents(); } } Dialog.Dispose(); } break; case Key.F9: if (Interface.MessageCount != 0) { formMessages.ShowMessages(); Application.DoEvents(); } break; case Key.Delete: ReducedMode = false; LightingRelative = -1.0; Game.Reset(); TextureManager.UnuseAllTextures(); Fonts.Initialize(); Interface.ClearMessages(); Files = new string[] {}; break; case Key.Left: RotateX = -1; ReducedMode = false; break; case Key.Right: RotateX = 1; ReducedMode = false; break; case Key.Up: RotateY = -1; ReducedMode = false; break; case Key.Down: RotateY = 1; ReducedMode = false; break; case Key.A: case Key.Keypad4: MoveX = -1; ReducedMode = false; break; case Key.D: case Key.Keypad6: MoveX = 1; ReducedMode = false; break; case Key.Keypad8: MoveY = 1; ReducedMode = false; break; case Key.Keypad2: MoveY = -1; ReducedMode = false; break; case Key.W: case Key.Keypad9: MoveZ = 1; ReducedMode = false; break; case Key.S: case Key.Keypad3: MoveZ = -1; ReducedMode = false; break; case Key.Keypad5: ResetCamera(); break; case Key.F: case Key.F1: Renderer.OptionWireframe = !Renderer.OptionWireframe; if (Renderer.OptionWireframe) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); } else { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); } break; case Key.N: case Key.F2: Renderer.OptionNormals = !Renderer.OptionNormals; break; case Key.L: case Key.F3: LightingTarget = 1 - LightingTarget; ReducedMode = false; break; case Key.I: case Key.F4: Renderer.OptionInterface = !Renderer.OptionInterface; ReducedMode = false; break; case Key.F8: formOptions.ShowOptions(); Application.DoEvents(); break; case Key.G: case Key.C: Renderer.OptionCoordinateSystem = !Renderer.OptionCoordinateSystem; ReducedMode = false; break; case Key.B: if (ShiftPressed) { ColorDialog dialog = new ColorDialog(); dialog.FullOpen = true; if (dialog.ShowDialog() == DialogResult.OK) { Renderer.BackgroundColor = -1; Renderer.ApplyBackgroundColor(dialog.Color.R, dialog.Color.G, dialog.Color.B); } } else { Renderer.BackgroundColor++; if (Renderer.BackgroundColor >= Renderer.MaxBackgroundColor) { Renderer.BackgroundColor = 0; } Renderer.ApplyBackgroundColor(); } ReducedMode = false; break; } }
internal static void Main(string[] args) { // platform and mono int p = (int)Environment.OSVersion.Platform; if (p == 4 | p == 128) { // general Unix CurrentPlatform = Platform.Linux; } else if (p == 6) { // Mac CurrentPlatform = Platform.Mac; } else { // non-Unix CurrentPlatform = Platform.Windows; } CurrentlyRunOnMono = Type.GetType("Mono.Runtime") != null; // file system FileSystem = FileSystem.FromCommandLineArgs(args); FileSystem.CreateFileSystem(); SetPackageLookupDirectories(); // command line arguments bool[] SkipArgs = new bool[args.Length]; if (args.Length != 0) { string File = System.IO.Path.Combine(Application.StartupPath, "RouteViewer.exe"); if (System.IO.File.Exists(File)) { int Skips = 0; System.Text.StringBuilder NewArgs = new System.Text.StringBuilder(); for (int i = 0; i < args.Length; i++) { if (System.IO.File.Exists(args[i])) { if (System.IO.Path.GetExtension(args[i]).Equals(".csv", StringComparison.OrdinalIgnoreCase)) { string Text = System.IO.File.ReadAllText(args[i], System.Text.Encoding.UTF8); if (Text.Length != -1 && Text.IndexOf("CreateMeshBuilder", StringComparison.OrdinalIgnoreCase) == -1) { if (NewArgs.Length != 0) { NewArgs.Append(" "); } NewArgs.Append("\"" + args[i] + "\""); SkipArgs[i] = true; Skips++; } } } else { SkipArgs[i] = true; Skips++; } } if (NewArgs.Length != 0) { System.Diagnostics.Process.Start(File, NewArgs.ToString()); } if (Skips == args.Length) { return; } } } // application Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO) != 0) { MessageBox.Show("SDL failed to initialize the video subsystem.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } Interface.CurrentOptions.ObjectOptimizationBasicThreshold = 1000; Interface.CurrentOptions.ObjectOptimizationFullThreshold = 250; // initialize sdl window SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DOUBLEBUFFER, 1); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DEPTH_SIZE, 16); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_RED_SIZE, 8); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_GREEN_SIZE, 8); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_BLUE_SIZE, 8); SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_ALPHA_SIZE, 8); SDL.SDL_ShowCursor(1); // initialize camera ResetCamera(); // create window Renderer.ScreenWidth = 960; Renderer.ScreenHeight = 600; // int Bits = 32; //Sdl.SDL_SetVideoMode(Renderer.ScreenWidth, Renderer.ScreenHeight, Bits, Sdl.SDL_OPENGL | Sdl.SDL_DOUBLEBUF); SDLWindow = SDL.SDL_CreateWindow(Application.ProductName, SDL.SDL_WINDOWPOS_UNDEFINED, SDL.SDL_WINDOWPOS_UNDEFINED, Renderer.ScreenWidth, Renderer.ScreenHeight, SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE); if (SDLWindow != IntPtr.Zero) { // create window string File = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder(), "icon.png"); if (System.IO.File.Exists(File)) { // set up icon iconBmp = new Bitmap(File); // load file iconData = iconBmp.LockBits(new Rectangle(0, 0, iconBmp.Width, iconBmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); // lock data iconSurface = SDL.SDL_CreateRGBSurfaceFrom(iconData.Scan0, iconBmp.Width, iconBmp.Height, 32, iconData.Stride, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); // upload to sdl SDL.SDL_SetWindowIcon(SDLWindow, iconSurface); // use icon // free is on the end of the program /* * IntPtr bitmap = SDL.SDL_LoadBMP(File); * if (bitmap != IntPtr.Zero) { * SDL.SDL_Surface Surface = (SDL.SDL_Surface)System.Runtime.InteropServices.Marshal.PtrToStructure(bitmap, typeof(SDL.SDL_Surface)); * uint ColorKey = SDL.SDL_MapRGB(Surface.format, 0, 0, 255); * SDL.SDL_SetColorKey(bitmap, 1, ColorKey); * SDL.SDL_SetWindowIcon(SDLWindow,bitmap); * } */ } GLContext = SDL.SDL_GL_CreateContext(SDLWindow); tkContext = new GraphicsContext(new ContextHandle(GLContext), SDL.SDL_GL_GetProcAddress, () => new ContextHandle(SDL.SDL_GL_GetCurrentContext())); // anisotropic filtering string[] extensions = GL.GetString(StringName.Extensions).Split(new [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); Interface.CurrentOptions.AnisotropicFilteringMaximum = 0; for (int i = 0; i < extensions.Length; i++) { if (extensions[i] == "GL_EXT_texture_filter_anisotropic") { float n; GL.GetFloat((GetPName)ExtTextureFilterAnisotropic.MaxTextureMaxAnisotropyExt, out n); Interface.CurrentOptions.AnisotropicFilteringMaximum = (int)Math.Round((double)n); break; } } if (Interface.CurrentOptions.AnisotropicFilteringMaximum <= 0) { Interface.CurrentOptions.AnisotropicFilteringMaximum = 0; Interface.CurrentOptions.AnisotropicFilteringLevel = 0; Interface.CurrentOptions.Interpolation = TextureManager.InterpolationMode.AnisotropicFiltering; } else { Interface.CurrentOptions.AnisotropicFilteringLevel = Interface.CurrentOptions.AnisotropicFilteringMaximum; Interface.CurrentOptions.Interpolation = TextureManager.InterpolationMode.TrilinearMipmapped; } // module initialization Renderer.Initialize(); Renderer.InitializeLighting(); SDL.SDL_GL_SwapWindow(SDLWindow); Fonts.Initialize(); UpdateViewport(); // command line arguments for (int i = 0; i < args.Length; i++) { if (!SkipArgs[i] && System.IO.File.Exists(args[i])) { try { ObjectManager.UnifiedObject o = ObjectManager.LoadObject(args[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); ObjectManager.CreateObject(o, new World.Vector3D(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + args[i] + "."); } Array.Resize <string>(ref Files, Files.Length + 1); Files[Files.Length - 1] = args[i]; } } ObjectManager.InitializeVisibility(); ObjectManager.FinishCreatingObjects(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); UpdateCaption(); Stopwatch timer = new Stopwatch(); timer.Start(); LastTicks = timer.ElapsedMilliseconds; // loop while (!Quit) { long ticks = timer.ElapsedMilliseconds; double timeElapsed = 0.001 * (double)(ticks - LastTicks); if (timeElapsed < 0.0001) { timeElapsed = 0.0001; } LastTicks = ticks; DateTime time = DateTime.Now; Game.SecondsSinceMidnight = (double)(3600 * time.Hour + 60 * time.Minute + time.Second) + 0.001 * (double)time.Millisecond; ObjectManager.UpdateAnimatedWorldObjects(timeElapsed, false); ProcessEvents(); if (ReducedMode) { System.Threading.Thread.Sleep(125); } else { System.Threading.Thread.Sleep(1); } bool updatelight = false; bool keep = false; // rotate x if (RotateX == 0) { double d = (1.0 + Math.Abs(RotateXSpeed)) * timeElapsed; if (RotateXSpeed >= -d & RotateXSpeed <= d) { RotateXSpeed = 0.0; } else { RotateXSpeed -= (double)Math.Sign(RotateXSpeed) * d; } } else { double d = (1.0 + 1.0 - 1.0 / (1.0 + RotateXSpeed * RotateXSpeed)) * timeElapsed; double m = 1.0; RotateXSpeed += (double)RotateX * d; if (RotateXSpeed < -m) { RotateXSpeed = -m; } else if (RotateXSpeed > m) { RotateXSpeed = m; } } if (RotateXSpeed != 0.0) { double cosa = Math.Cos(RotateXSpeed * timeElapsed); double sina = Math.Sin(RotateXSpeed * timeElapsed); World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, 0.0, 1.0, 0.0, cosa, sina); World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, 0.0, 1.0, 0.0, cosa, sina); World.Rotate(ref World.AbsoluteCameraSide.X, ref World.AbsoluteCameraSide.Y, ref World.AbsoluteCameraSide.Z, 0.0, 1.0, 0.0, cosa, sina); keep = true; } // rotate y if (RotateY == 0) { double d = (1.0 + Math.Abs(RotateYSpeed)) * timeElapsed; if (RotateYSpeed >= -d & RotateYSpeed <= d) { RotateYSpeed = 0.0; } else { RotateYSpeed -= (double)Math.Sign(RotateYSpeed) * d; } } else { double d = (1.0 + 1.0 - 1.0 / (1.0 + RotateYSpeed * RotateYSpeed)) * timeElapsed; double m = 1.0; RotateYSpeed += (double)RotateY * d; if (RotateYSpeed < -m) { RotateYSpeed = -m; } else if (RotateYSpeed > m) { RotateYSpeed = m; } } if (RotateYSpeed != 0.0) { double cosa = Math.Cos(RotateYSpeed * timeElapsed); double sina = Math.Sin(RotateYSpeed * timeElapsed); World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina); World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina); keep = true; } // move x if (MoveX == 0) { double d = (2.5 + Math.Abs(MoveXSpeed)) * timeElapsed; if (MoveXSpeed >= -d & MoveXSpeed <= d) { MoveXSpeed = 0.0; } else { MoveXSpeed -= (double)Math.Sign(MoveXSpeed) * d; } } else { double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveXSpeed * MoveXSpeed)) * timeElapsed; double m = 25.0; MoveXSpeed += (double)MoveX * d; if (MoveXSpeed < -m) { MoveXSpeed = -m; } else if (MoveXSpeed > m) { MoveXSpeed = m; } } if (MoveXSpeed != 0.0) { World.AbsoluteCameraPosition.X += MoveXSpeed * timeElapsed * World.AbsoluteCameraSide.X; World.AbsoluteCameraPosition.Y += MoveXSpeed * timeElapsed * World.AbsoluteCameraSide.Y; World.AbsoluteCameraPosition.Z += MoveXSpeed * timeElapsed * World.AbsoluteCameraSide.Z; keep = true; } // move y if (MoveY == 0) { double d = (2.5 + Math.Abs(MoveYSpeed)) * timeElapsed; if (MoveYSpeed >= -d & MoveYSpeed <= d) { MoveYSpeed = 0.0; } else { MoveYSpeed -= (double)Math.Sign(MoveYSpeed) * d; } } else { double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveYSpeed * MoveYSpeed)) * timeElapsed; double m = 25.0; MoveYSpeed += (double)MoveY * d; if (MoveYSpeed < -m) { MoveYSpeed = -m; } else if (MoveYSpeed > m) { MoveYSpeed = m; } } if (MoveYSpeed != 0.0) { World.AbsoluteCameraPosition.X += MoveYSpeed * timeElapsed * World.AbsoluteCameraUp.X; World.AbsoluteCameraPosition.Y += MoveYSpeed * timeElapsed * World.AbsoluteCameraUp.Y; World.AbsoluteCameraPosition.Z += MoveYSpeed * timeElapsed * World.AbsoluteCameraUp.Z; keep = true; } // move z if (MoveZ == 0) { double d = (2.5 + Math.Abs(MoveZSpeed)) * timeElapsed; if (MoveZSpeed >= -d & MoveZSpeed <= d) { MoveZSpeed = 0.0; } else { MoveZSpeed -= (double)Math.Sign(MoveZSpeed) * d; } } else { double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveZSpeed * MoveZSpeed)) * timeElapsed; double m = 25.0; MoveZSpeed += (double)MoveZ * d; if (MoveZSpeed < -m) { MoveZSpeed = -m; } else if (MoveZSpeed > m) { MoveZSpeed = m; } } if (MoveZSpeed != 0.0) { World.AbsoluteCameraPosition.X += MoveZSpeed * timeElapsed * World.AbsoluteCameraDirection.X; World.AbsoluteCameraPosition.Y += MoveZSpeed * timeElapsed * World.AbsoluteCameraDirection.Y; World.AbsoluteCameraPosition.Z += MoveZSpeed * timeElapsed * World.AbsoluteCameraDirection.Z; keep = true; } // lighting if (LightingRelative == -1) { LightingRelative = (double)LightingTarget; updatelight = true; } if (LightingTarget == 0) { if (LightingRelative != 0.0) { LightingRelative -= 0.5 * timeElapsed; if (LightingRelative < 0.0) { LightingRelative = 0.0; } updatelight = true; keep = true; } } else { if (LightingRelative != 1.0) { LightingRelative += 0.5 * timeElapsed; if (LightingRelative > 1.0) { LightingRelative = 1.0; } updatelight = true; keep = true; } } // continue if (ReducedMode) { ReducedModeEnteringTime = (int)(ticks + 3000); } else { if (keep) { ReducedModeEnteringTime = (int)(ticks + 3000); } else if (ticks > ReducedModeEnteringTime) { ReducedMode = true; World.AbsoluteCameraSide.Y = 0.0; World.Normalize(ref World.AbsoluteCameraSide.X, ref World.AbsoluteCameraSide.Y, ref World.AbsoluteCameraSide.Z); World.Normalize(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z); World.AbsoluteCameraUp = World.Cross(World.AbsoluteCameraDirection, World.AbsoluteCameraSide); } } if (updatelight) { Renderer.OptionAmbientColor.R = (byte)Math.Round(32.0 + 128.0 * LightingRelative * (2.0 - LightingRelative)); Renderer.OptionAmbientColor.G = (byte)Math.Round(32.0 + 128.0 * 0.5 * (LightingRelative + LightingRelative * (2.0 - LightingRelative))); Renderer.OptionAmbientColor.B = (byte)Math.Round(32.0 + 128.0 * LightingRelative); Renderer.OptionDiffuseColor.R = (byte)Math.Round(32.0 + 128.0 * LightingRelative); Renderer.OptionDiffuseColor.G = (byte)Math.Round(32.0 + 128.0 * LightingRelative); Renderer.OptionDiffuseColor.B = (byte)Math.Round(32.0 + 128.0 * Math.Sqrt(LightingRelative)); Renderer.InitializeLighting(); } Renderer.RenderScene(); SDL.SDL_GL_SwapWindow(SDLWindow); } // quit TextureManager.UnuseAllTextures(); if (iconSurface != IntPtr.Zero) { SDL.SDL_FreeSurface(iconSurface); // free surface } if (iconBmp != null && iconData != null) { iconBmp.UnlockBits(iconData); // free pixels iconBmp.Dispose(); } SDL.SDL_GL_DeleteContext(GLContext); SDL.SDL_DestroyWindow(SDLWindow); SDL.SDL_Quit(); } else { MessageBox.Show("SDL failed to create the window.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); } }
// process events private static void ProcessEvents() { SDL.SDL_Event Event; while (SDL.SDL_PollEvent(out Event) != 0) { switch (Event.type) { // quit case SDL.SDL_EventType.SDL_QUIT: Quit = true; return; // resize case SDL.SDL_EventType.SDL_WINDOWEVENT: if (Event.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED) { Renderer.ScreenWidth = Event.window.data1; Renderer.ScreenHeight = Event.window.data2; UpdateViewport(); } break; // mouse case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN: MouseCenterX = (short)Event.button.x; MouseCenterY = (short)Event.button.y; MouseCameraPosition = World.AbsoluteCameraPosition; MouseCameraDirection = World.AbsoluteCameraDirection; MouseCameraUp = World.AbsoluteCameraUp; MouseCameraSide = World.AbsoluteCameraSide; MouseButton = Event.button.button; break; case SDL.SDL_EventType.SDL_MOUSEBUTTONUP: MouseButton = 0; break; case SDL.SDL_EventType.SDL_MOUSEMOTION: if (MouseButton == SDL.SDL_BUTTON_LEFT) { World.AbsoluteCameraDirection = MouseCameraDirection; World.AbsoluteCameraUp = MouseCameraUp; World.AbsoluteCameraSide = MouseCameraSide; { double dx = 0.0025 * (double)(MouseCenterX - Event.motion.x); double cosa = Math.Cos(dx); double sina = Math.Sin(dx); World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, 0.0, 1.0, 0.0, cosa, sina); World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, 0.0, 1.0, 0.0, cosa, sina); World.Rotate(ref World.AbsoluteCameraSide.X, ref World.AbsoluteCameraSide.Y, ref World.AbsoluteCameraSide.Z, 0.0, 1.0, 0.0, cosa, sina); } { double dy = 0.0025 * (double)(MouseCenterY - Event.motion.y); double cosa = Math.Cos(dy); double sina = Math.Sin(dy); World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina); World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina); } ReducedMode = false; } else if (MouseButton == SDL.SDL_BUTTON_RIGHT) { World.AbsoluteCameraPosition = MouseCameraPosition; double dx = -0.025 * (double)(Event.motion.x - MouseCenterX); World.AbsoluteCameraPosition.X += dx * World.AbsoluteCameraSide.X; World.AbsoluteCameraPosition.Y += dx * World.AbsoluteCameraSide.Y; World.AbsoluteCameraPosition.Z += dx * World.AbsoluteCameraSide.Z; double dy = 0.025 * (double)(Event.motion.y - MouseCenterY); World.AbsoluteCameraPosition.X += dy * World.AbsoluteCameraUp.X; World.AbsoluteCameraPosition.Y += dy * World.AbsoluteCameraUp.Y; World.AbsoluteCameraPosition.Z += dy * World.AbsoluteCameraUp.Z; ReducedMode = false; } else if (MouseButton == SDL.SDL_BUTTON_MIDDLE) { World.AbsoluteCameraPosition = MouseCameraPosition; double dx = -0.025 * (double)(Event.motion.x - MouseCenterX); World.AbsoluteCameraPosition.X += dx * World.AbsoluteCameraSide.X; World.AbsoluteCameraPosition.Y += dx * World.AbsoluteCameraSide.Y; World.AbsoluteCameraPosition.Z += dx * World.AbsoluteCameraSide.Z; double dz = -0.025 * (double)(Event.motion.y - MouseCenterY); World.AbsoluteCameraPosition.X += dz * World.AbsoluteCameraDirection.X; World.AbsoluteCameraPosition.Y += dz * World.AbsoluteCameraDirection.Y; World.AbsoluteCameraPosition.Z += dz * World.AbsoluteCameraDirection.Z; ReducedMode = false; } break; // key down case SDL.SDL_EventType.SDL_KEYDOWN: switch (Event.key.keysym.sym) { case SDL.SDL_Keycode.SDLK_LSHIFT: case SDL.SDL_Keycode.SDLK_RSHIFT: ShiftPressed = true; break; case SDL.SDL_Keycode.SDLK_F5: // reset ReducedMode = false; LightingRelative = -1.0; Game.Reset(); TextureManager.UnuseAllTextures(); Fonts.Initialize(); Interface.ClearMessages(); for (int i = 0; i < Files.Length; i++) { #if !DEBUG try { #endif ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); ObjectManager.CreateObject(o, new World.Vector3D(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); #if !DEBUG } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + "."); } #endif } ObjectManager.InitializeVisibility(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); break; case SDL.SDL_Keycode.SDLK_F7: { OpenFileDialog Dialog = new OpenFileDialog(); Dialog.CheckFileExists = true; Dialog.Multiselect = true; Dialog.Filter = "CSV/B3D/X/ANIMATED files|*.csv;*.b3d;*.x;*.animated|All files|*"; if (Dialog.ShowDialog() == DialogResult.OK) { string[] f = Dialog.FileNames; int n = Files.Length; Array.Resize <string>(ref Files, n + f.Length); for (int i = 0; i < f.Length; i++) { Files[n + i] = f[i]; } // reset ReducedMode = false; LightingRelative = -1.0; Game.Reset(); TextureManager.UnuseAllTextures(); Fonts.Initialize(); Interface.ClearMessages(); for (int i = 0; i < Files.Length; i++) { #if !DEBUG try { #endif ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); ObjectManager.CreateObject(o, new World.Vector3D(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); #if !DEBUG } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + "."); } #endif } ObjectManager.InitializeVisibility(); ObjectManager.FinishCreatingObjects(); ObjectManager.UpdateVisibility(0.0, true); ObjectManager.UpdateAnimatedWorldObjects(0.01, true); } } break; case SDL.SDL_Keycode.SDLK_F9: if (Interface.MessageCount != 0) { formMessages.ShowMessages(); } break; case SDL.SDL_Keycode.SDLK_DELETE: ReducedMode = false; LightingRelative = -1.0; Game.Reset(); TextureManager.UnuseAllTextures(); Fonts.Initialize(); Interface.ClearMessages(); Files = new string[] { }; UpdateCaption(); break; case SDL.SDL_Keycode.SDLK_LEFT: RotateX = -1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_RIGHT: RotateX = 1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_UP: RotateY = -1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_DOWN: RotateY = 1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_a: case SDL.SDL_Keycode.SDLK_KP_4: MoveX = -1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_d: case SDL.SDL_Keycode.SDLK_KP_6: MoveX = 1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_KP_8: MoveY = 1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_KP_2: MoveY = -1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_w: case SDL.SDL_Keycode.SDLK_KP_9: MoveZ = 1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_s: case SDL.SDL_Keycode.SDLK_KP_3: MoveZ = -1; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_KP_5: ResetCamera(); break; case SDL.SDL_Keycode.SDLK_f: case SDL.SDL_Keycode.SDLK_F1: Renderer.OptionWireframe = !Renderer.OptionWireframe; if (Renderer.OptionWireframe) { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); } else { GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); } break; case SDL.SDL_Keycode.SDLK_n: case SDL.SDL_Keycode.SDLK_F2: Renderer.OptionNormals = !Renderer.OptionNormals; break; case SDL.SDL_Keycode.SDLK_l: case SDL.SDL_Keycode.SDLK_F3: LightingTarget = 1 - LightingTarget; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_i: case SDL.SDL_Keycode.SDLK_F4: Renderer.OptionInterface = !Renderer.OptionInterface; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_g: case SDL.SDL_Keycode.SDLK_c: Renderer.OptionCoordinateSystem = !Renderer.OptionCoordinateSystem; ReducedMode = false; break; case SDL.SDL_Keycode.SDLK_b: if (ShiftPressed) { ColorDialog dialog = new ColorDialog(); dialog.FullOpen = true; if (dialog.ShowDialog() == DialogResult.OK) { Renderer.BackgroundColor = -1; Renderer.ApplyBackgroundColor(dialog.Color.R, dialog.Color.G, dialog.Color.B); } } else { Renderer.BackgroundColor++; if (Renderer.BackgroundColor >= Renderer.MaxBackgroundColor) { Renderer.BackgroundColor = 0; } Renderer.ApplyBackgroundColor(); } ReducedMode = false; break; } break; // key up case SDL.SDL_EventType.SDL_KEYUP: switch (Event.key.keysym.sym) { case SDL.SDL_Keycode.SDLK_LSHIFT: case SDL.SDL_Keycode.SDLK_RSHIFT: ShiftPressed = false; break; case SDL.SDL_Keycode.SDLK_LEFT: case SDL.SDL_Keycode.SDLK_RIGHT: RotateX = 0; break; case SDL.SDL_Keycode.SDLK_UP: case SDL.SDL_Keycode.SDLK_DOWN: RotateY = 0; break; case SDL.SDL_Keycode.SDLK_a: case SDL.SDL_Keycode.SDLK_d: case SDL.SDL_Keycode.SDLK_KP_4: case SDL.SDL_Keycode.SDLK_KP_6: MoveX = 0; break; case SDL.SDL_Keycode.SDLK_KP_8: case SDL.SDL_Keycode.SDLK_KP_2: MoveY = 0; break; case SDL.SDL_Keycode.SDLK_w: case SDL.SDL_Keycode.SDLK_s: case SDL.SDL_Keycode.SDLK_KP_9: case SDL.SDL_Keycode.SDLK_KP_3: MoveZ = 0; break; } break; } } }