コード例 #1
0
ファイル: ObjectManager.cs プロジェクト: sladen/openbve
 internal static void CreateObject(UnifiedObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials)
 {
     if (Prototype is StaticObject) {
         StaticObject s = (StaticObject)Prototype;
         CreateStaticObject(s, Position, BaseTransformation, AuxTransformation, AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, BlockLength, TrackPosition, Brightness, DuplicateMaterials);
     } else if (Prototype is AnimatedObjectCollection) {
         AnimatedObjectCollection a = (AnimatedObjectCollection)Prototype;
         CreateAnimatedWorldObjects(a.Objects, Position, BaseTransformation, AuxTransformation, SectionIndex, AccurateObjectDisposal, StartingDistance, EndingDistance, BlockLength, TrackPosition, Brightness, DuplicateMaterials);
     }
 }
コード例 #2
0
ファイル: ObjectManager.cs プロジェクト: sladen/openbve
 internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials)
 {
     int a = ObjectsUsed;
     if (a >= Objects.Length) {
         Array.Resize<StaticObject>(ref Objects, Objects.Length << 1);
     }
     ApplyStaticObjectData(ref Objects[a], Prototype, Position, BaseTransformation, AuxTransformation, AccurateObjectDisposal, AccurateObjectDisposalZOffset, StartingDistance, EndingDistance, BlockLength, TrackPosition, Brightness, DuplicateMaterials);
     for (int i = 0; i < Prototype.Mesh.Faces.Length; i++) {
         switch (Prototype.Mesh.Faces[i].Flags & World.MeshFace.FaceTypeMask) {
             case World.MeshFace.FaceTypeTriangles:
                 Game.InfoTotalTriangles++;
                 break;
             case World.MeshFace.FaceTypeTriangleStrip:
                 Game.InfoTotalTriangleStrip++;
                 break;
             case World.MeshFace.FaceTypeQuads:
                 Game.InfoTotalQuads++;
                 break;
             case World.MeshFace.FaceTypeQuadStrip:
                 Game.InfoTotalQuadStrip++;
                 break;
             case World.MeshFace.FaceTypePolygon:
                 Game.InfoTotalPolygon++;
                 break;
         }
     }
     ObjectsUsed++;
     return a;
 }
コード例 #3
0
ファイル: TextureManager.cs プロジェクト: leezer3/OpenBVE
		// load texture rgba
		private static void LoadTextureRGBAforData(Bitmap Bitmap, World.ColorRGB TransparentColor, byte TransparentColorUsed, int TextureIndex)
		{
			try
			{
				// load bytes
				int Width, Height, Stride; byte[] Data;
				{
					if (Textures[TextureIndex].ClipWidth == 0) Textures[TextureIndex].ClipWidth = Bitmap.Width;
					if (Textures[TextureIndex].ClipHeight == 0) Textures[TextureIndex].ClipHeight = Bitmap.Height;
					Width = Textures[TextureIndex].ClipWidth;
					Height = Textures[TextureIndex].ClipHeight;
					Bitmap c = new Bitmap(Width, Height, GDIPixelFormat.Format32bppArgb);
					Graphics g = Graphics.FromImage(c);
					Rectangle dst = new Rectangle(0, 0, Width, Height);
					Rectangle src = new Rectangle(Textures[TextureIndex].ClipLeft, Textures[TextureIndex].ClipTop, Textures[TextureIndex].ClipWidth, Textures[TextureIndex].ClipHeight);
					g.DrawImage(Bitmap, dst, src, GraphicsUnit.Pixel);
					g.Dispose();
					BitmapData d = c.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, c.PixelFormat);
					Stride = d.Stride;
					Data = new byte[Stride * Height];
					System.Runtime.InteropServices.Marshal.Copy(d.Scan0, Data, 0, Stride * Height);
					c.UnlockBits(d);
					c.Dispose();
				}
				// load mode
				if (Textures[TextureIndex].LoadMode == TextureLoadMode.Bve4SignalGlow)
				{
					// bve 4 signal glow
					int p = 0, pn = Stride - 4 * Width;
					byte tr, tg, tb;
					if (TransparentColorUsed != 0)
					{
						tr = TransparentColor.R;
						tg = TransparentColor.G;
						tb = TransparentColor.B;
					}
					else
					{
						tr = 0; tg = 0; tb = 0;
					}
					// invert lightness
					byte[] Temp = new byte[Stride * Height];
					for (int y = 0; y < Height; y++)
					{
						for (int x = 0; x < Width; x++)
						{
							if (Data[p] == tb & Data[p + 1] == tg & Data[p + 2] == tr)
							{
								Temp[p] = 0;
								Temp[p + 1] = 0;
								Temp[p + 2] = 0;
							}
							else if (Data[p] != 255 | Data[p + 1] != 255 | Data[p + 2] != 255)
							{
								int b = Data[p], g = Data[p + 1], r = Data[p + 2];
								InvertLightness(ref r, ref g, ref b);
								int l = r >= g & r >= b ? r : g >= b ? g : b;
								Temp[p] = (byte)(l * b / 255);
								Temp[p + 1] = (byte)(l * g / 255);
								Temp[p + 2] = (byte)(l * r / 255);
							}
							else
							{
								Temp[p] = Data[p];
								Temp[p + 1] = Data[p + 1];
								Temp[p + 2] = Data[p + 2];
							}
							p += 4;
						} p += pn;
					} p = 0;
					// blur the image and multiply by lightness
					int s = 4;
					int n = Stride - (2 * s + 1 << 2);
					for (int y = 0; y < Height; y++)
					{
						for (int x = 0; x < Width; x++)
						{
							int q = p - s * (Stride + 4);
							int r = 0, g = 0, b = 0, c = 0;
							for (int yr = y - s; yr <= y + s; yr++)
							{
								if (yr >= 0 & yr < Height)
								{
									for (int xr = x - s; xr <= x + s; xr++)
									{
										if (xr >= 0 & xr < Width)
										{
											b += (int)Temp[q];
											g += (int)Temp[q + 1];
											r += (int)Temp[q + 2];
											c++;
										} q += 4;
									} q += n;
								}
								else q += Stride;
							} if (c == 0)
							{
								Data[p] = 0;
								Data[p + 1] = 0;
								Data[p + 2] = 0;
								Data[p + 3] = 255;
							}
							else
							{
								r /= c; g /= c; b /= c;
								int l = r >= g & r >= b ? r : g >= b ? g : b;
								Data[p] = (byte)(l * b / 255);
								Data[p + 1] = (byte)(l * g / 255);
								Data[p + 2] = (byte)(l * r / 255);
								Data[p + 3] = 255;
							}
							p += 4;
						} p += pn;
					}
					Textures[TextureIndex].Transparency = TextureTransparencyMode.None;
					Textures[TextureIndex].DontAllowUnload = true;
				}
				else if (TransparentColorUsed != 0)
				{
					// transparent color
					int p = 0, pn = Stride - 4 * Width;
					byte tr = TransparentColor.R;
					byte tg = TransparentColor.G;
					byte tb = TransparentColor.B;
					bool used = false;
					// check if alpha is actually used
					int y;
					for (y = 0; y < Height; y++)
					{
						int x; for (x = 0; x < Width; x++)
						{
							if (Data[p + 3] != 255)
							{
								break;
							} p += 4;
						} if (x < Width) break;
						p += pn;
					}
					if (y == Height)
					{
						Textures[TextureIndex].Transparency = TextureTransparencyMode.TransparentColor;
					}
					// duplicate color data from adjacent pixels
					p = 0; pn = Stride - 4 * Width;
					for (y = 0; y < Height; y++)
					{
						for (int x = 0; x < Width; x++)
						{
							if (Data[p] == tb & Data[p + 1] == tg & Data[p + 2] == tr)
							{
								used = true;
								if (x == 0)
								{
									int q = p;
									int v; for (v = y; v < Height; v++)
									{
										int u; for (u = v == y ? x + 1 : 0; u < Width; u++)
										{
											if (Data[q] != tb | Data[q + 1] != tg | Data[q + 2] != tr)
											{
												Data[p] = Data[q];
												Data[p + 1] = Data[q + 1];
												Data[p + 2] = Data[q + 2];
												Data[p + 3] = 0;
												break;
											} q += 4;
										} if (u < Width)
										{
											break;
										}
										else q += pn;
									} if (v == Height)
									{
										if (y == 0)
										{
											Data[p] = 128;
											Data[p + 1] = 128;
											Data[p + 2] = 128;
											Data[p + 3] = 0;
										}
										else
										{
											Data[p] = Data[p - Stride];
											Data[p + 1] = Data[p - Stride + 1];
											Data[p + 2] = Data[p - Stride + 2];
											Data[p + 3] = 0;
										}
									}
								}
								else
								{
									Data[p] = Data[p - 4];
									Data[p + 1] = Data[p - 3];
									Data[p + 2] = Data[p - 2];
									Data[p + 3] = 0;
								}
							} p += 4;
						} p += pn;
					}
					// transparent color is not actually used
					if (!used & Textures[TextureIndex].Transparency == TextureTransparencyMode.TransparentColor)
					{
						Textures[TextureIndex].Transparency = TextureTransparencyMode.None;
					}
				}
				else if (Textures[TextureIndex].Transparency == TextureTransparencyMode.Alpha)
				{
					// check if alpha is actually used
					int p = 0, pn = Stride - 4 * Width;
					int y; for (y = 0; y < Height; y++)
					{
						int x; for (x = 0; x < Width; x++)
						{
							if (Data[p + 3] != 255)
							{
								break;
							} p += 4;
						} if (x < Width) break;
						p += pn;
					}
					if (y == Height)
					{
						Textures[TextureIndex].Transparency = TextureTransparencyMode.None;
					}
				}
				// non-power of two
				int TargetWidth = Interface.RoundToPowerOfTwo(Width);
				int TargetHeight = Interface.RoundToPowerOfTwo(Height);
				if (TargetWidth != Width | TargetHeight != Height)
				{
					Bitmap b = new Bitmap(Width, Height, GDIPixelFormat.Format32bppArgb);
					BitmapData d = b.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, b.PixelFormat);
					System.Runtime.InteropServices.Marshal.Copy(Data, 0, d.Scan0, d.Stride * d.Height);
					b.UnlockBits(d);
					Bitmap c = new Bitmap(TargetWidth, TargetHeight, GDIPixelFormat.Format32bppArgb);
					Graphics g = Graphics.FromImage(c);
					g.DrawImage(b, 0, 0, TargetWidth, TargetHeight);
					g.Dispose();
					b.Dispose();
					d = c.LockBits(new Rectangle(0, 0, TargetWidth, TargetHeight), ImageLockMode.ReadOnly, c.PixelFormat);
					Stride = d.Stride;
					Data = new byte[Stride * TargetHeight];
					System.Runtime.InteropServices.Marshal.Copy(d.Scan0, Data, 0, Stride * TargetHeight);
					c.UnlockBits(d);
					c.Dispose();
				}
				Textures[TextureIndex].Width = TargetWidth;
				Textures[TextureIndex].Height = TargetHeight;
				Textures[TextureIndex].Data = Data;
			}
			catch (Exception ex)
			{
				Interface.AddMessage(Interface.MessageType.Error, false, "Internal error in TextureManager.cs::LoadTextureRGBAForData: " + ex.Message);
				throw;
			}
		}
コード例 #4
0
ファイル: ObjectManager.cs プロジェクト: sladen/openbve
 internal static void CreateAnimatedWorldObjects(AnimatedObject[] Prototypes, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials)
 {
     bool[] free = new bool[Prototypes.Length];
     bool anyfree = false;
     for (int i = 0; i < Prototypes.Length; i++) {
         free[i] = Prototypes[i].IsFreeOfFunctions();
         if (free[i]) anyfree = true;
     }
     if (anyfree) {
         for (int i = 0; i < Prototypes.Length; i++) {
             if (Prototypes[i].States.Length != 0) {
                 if (free[i]) {
                     Vector3 p = Position;
                     World.Transformation t = new OpenBve.World.Transformation(BaseTransformation, AuxTransformation);
                     Vector3 s = t.X;
                     Vector3 u = t.Y;
                     Vector3 d = t.Z;
                     p.X += Prototypes[i].States[0].Position.X * s.X + Prototypes[i].States[0].Position.Y * u.X + Prototypes[i].States[0].Position.Z * d.X;
                     p.Y += Prototypes[i].States[0].Position.X * s.Y + Prototypes[i].States[0].Position.Y * u.Y + Prototypes[i].States[0].Position.Z * d.Y;
                     p.Z += Prototypes[i].States[0].Position.X * s.Z + Prototypes[i].States[0].Position.Y * u.Z + Prototypes[i].States[0].Position.Z * d.Z;
                     double zOffset = Prototypes[i].States[0].Position.Z;
                     CreateStaticObject(Prototypes[i].States[0].Object, p, BaseTransformation, AuxTransformation, AccurateObjectDisposal, zOffset, StartingDistance, EndingDistance, BlockLength, TrackPosition, Brightness, DuplicateMaterials);
                 } else {
                     CreateAnimatedWorldObject(Prototypes[i], Position, BaseTransformation, AuxTransformation, SectionIndex, TrackPosition, Brightness);
                 }
             }
         }
     } else {
         for (int i = 0; i < Prototypes.Length; i++) {
             if (Prototypes[i].States.Length != 0) {
                 CreateAnimatedWorldObject(Prototypes[i], Position, BaseTransformation, AuxTransformation, SectionIndex, TrackPosition, Brightness);
             }
         }
     }
 }
コード例 #5
0
ファイル: TextureManager.cs プロジェクト: leezer3/OpenBVE
		internal static int RegisterTexture(string FileName, World.ColorRGB TransparentColor, byte TransparentColorUsed, TextureWrapMode WrapModeX, TextureWrapMode WrapModeY, bool DontAllowUnload)
		{
			return RegisterTexture(FileName, TransparentColor, TransparentColorUsed, TextureLoadMode.Normal, WrapModeX, WrapModeY, DontAllowUnload, 0, 0, 0, 0);
		}
コード例 #6
0
ファイル: TextureManager.cs プロジェクト: leezer3/OpenBVE
		internal static int RegisterTexture(Bitmap Bitmap, World.ColorRGB TransparentColor)
		{
			int i = GetFreeTexture();
			int[] a = new int[1];
			GL.GenTextures(1, a);
			Textures[i] = new Texture
			{
				Queried = false,
				OpenGlTextureIndex = a[0],
				Transparency = TextureTransparencyMode.TransparentColor,
				TransparentColor = TransparentColor,
				TransparentColorUsed = 1,
				FileName = null,
				Loaded = true,
				Width =  Bitmap.Width,
				Height = Bitmap.Height,
				DontAllowUnload = true
			};
			LoadTextureRGBAforData(Bitmap, Textures[i].TransparentColor, Textures[i].TransparentColorUsed, i);
			LoadTextureRGBAforOpenGl(i);
			return i;
		}
コード例 #7
0
ファイル: InterfaceR.cs プロジェクト: JakubVanek/openBVE-1
		internal static bool TryParseHexColor(string Expression, out World.ColorRGBA Color) {
			if (Expression.StartsWith("#")) {
				string a = Expression.Substring(1).TrimStart();
				int x; if (int.TryParse(a, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out x)) {
					int r = (x >> 16) & 0xFF;
					int g = (x >> 8) & 0xFF;
					int b = x & 0xFF;
					if (r >= 0 & r <= 255 & g >= 0 & g <= 255 & b >= 0 & b <= 255) {
						Color = new World.ColorRGBA((byte)r, (byte)g, (byte)b, 255);
						return true;
					} else {
						Color = new World.ColorRGBA(0, 0, 255, 255);
						return false;
					}
				} else {
					Color = new World.ColorRGBA(0, 0, 255, 255);
					return false;
				}
			} else {
				Color = new World.ColorRGBA(0, 0, 255, 255);
				return false;
			}
		}
コード例 #8
0
 internal static void UpdateAnimatedObject(ref AnimatedObject Object, TrainManager.Train Train, int SectionIndex, double TrackPosition, World.Vector3D Position, World.Vector3D Direction, World.Vector3D Up, World.Vector3D Side, bool Overlay, bool UpdateFunctions, bool Show, double TimeElapsed)
 {
     int s = Object.CurrentState;
     int i = Object.ObjectIndex;
     // state change
     if (Object.StateFunction != null & UpdateFunctions) {
         double sd = Object.StateFunction.Perform(Train, Position, TrackPosition, SectionIndex, TimeElapsed);
         int si = (int)Math.Round(sd);
         int sn = Object.States.Length;
         if (si < 0 | si >= sn) si = -1;
         if (s != si) {
             InitializeAnimatedObject(ref Object, si, Overlay, Show);
             s = si;
         }
     }
     if (s == -1) return;
     // translation
     if (Object.TranslateXFunction != null) {
         double x;
         if (UpdateFunctions) {
             x = Object.TranslateXFunction.Perform(Train, Position, TrackPosition, SectionIndex, TimeElapsed);
         } else  {
             x = Object.TranslateXFunction.LastResult;
         }
         double rx = Object.TranslateXDirection.X, ry = Object.TranslateXDirection.Y, rz = Object.TranslateXDirection.Z;
         World.Rotate(ref rx, ref ry, ref rz, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z);
         Position.X += x * rx;
         Position.Y += x * ry;
         Position.Z += x * rz;
     }
     if (Object.TranslateYFunction != null) {
         double y;
         if (UpdateFunctions) {
             y = Object.TranslateYFunction.Perform(Train, Position, TrackPosition, SectionIndex, TimeElapsed);
         } else {
             y = Object.TranslateYFunction.LastResult;
         }
         double rx = Object.TranslateYDirection.X, ry = Object.TranslateYDirection.Y, rz = Object.TranslateYDirection.Z;
         World.Rotate(ref rx, ref ry, ref rz, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z);
         Position.X += y * rx;
         Position.Y += y * ry;
         Position.Z += y * rz;
     }
     if (Object.TranslateZFunction != null) {
         double z;
         if (UpdateFunctions) {
             z = Object.TranslateZFunction.Perform(Train, Position, TrackPosition, SectionIndex, TimeElapsed);
         } else {
             z = Object.TranslateZFunction.LastResult;
         }
         double rx = Object.TranslateZDirection.X, ry = Object.TranslateZDirection.Y, rz = Object.TranslateZDirection.Z;
         World.Rotate(ref rx, ref ry, ref rz, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z);
         Position.X += z * rx;
         Position.Y += z * ry;
         Position.Z += z * rz;
     }
     // rotation
     bool rotateX = Object.RotateXFunction != null;
     bool rotateY = Object.RotateYFunction != null;
     bool rotateZ = Object.RotateZFunction != null;
     double cosX, sinX;
     if (rotateX) {
         double a;
         if (UpdateFunctions) {
             a = Object.RotateXFunction.Perform(Train, Position, TrackPosition, SectionIndex, TimeElapsed);
         } else {
             a = Object.RotateXFunction.LastResult;
         }
         ObjectManager.UpdateDamping(ref Object.RotateXDamping, TimeElapsed, ref a);
         cosX = Math.Cos(a);
         sinX = Math.Sin(a);
     } else {
         cosX = 0.0; sinX = 0.0;
     }
     double cosY, sinY;
     if (rotateY) {
         double a;
         if (UpdateFunctions) {
             a = Object.RotateYFunction.Perform(Train, Position, TrackPosition, SectionIndex, TimeElapsed);
         } else {
             a = Object.RotateYFunction.LastResult;
         }
         ObjectManager.UpdateDamping(ref Object.RotateYDamping, TimeElapsed, ref a);
         cosY = Math.Cos(a);
         sinY = Math.Sin(a);
     } else {
         cosY = 0.0; sinY = 0.0;
     }
     double cosZ, sinZ;
     if (rotateZ) {
         double a;
         if (UpdateFunctions) {
             a = Object.RotateZFunction.Perform(Train, Position, TrackPosition, SectionIndex, TimeElapsed);
         } else {
             a = Object.RotateZFunction.LastResult;
         }
         ObjectManager.UpdateDamping(ref Object.RotateZDamping, TimeElapsed, ref a);
         cosZ = Math.Cos(a);
         sinZ = Math.Sin(a);
     } else {
         cosZ = 0.0; sinZ = 0.0;
     }
     // texture shift
     bool shiftx = Object.TextureShiftXFunction != null;
     bool shifty = Object.TextureShiftYFunction != null;
     if ((shiftx | shifty) & UpdateFunctions) {
         for (int k = 0; k < ObjectManager.Objects[i].Mesh.Vertices.Length; k++) {
             ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates = Object.States[s].Object.Mesh.Vertices[k].TextureCoordinates;
         }
         if (shiftx) {
             double x = Object.TextureShiftXFunction.Perform(Train, Position, TrackPosition, SectionIndex, TimeElapsed);
             x -= Math.Floor(x);
             for (int k = 0; k < ObjectManager.Objects[i].Mesh.Vertices.Length; k++) {
                 ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates.X += (float)(x * Object.TextureShiftXDirection.X);
                 ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates.Y += (float)(x * Object.TextureShiftXDirection.Y);
             }
         }
         if (shifty) {
             double y = Object.TextureShiftYFunction.Perform(Train, Position, TrackPosition, SectionIndex, TimeElapsed);
             y -= Math.Floor(y);
             for (int k = 0; k < ObjectManager.Objects[i].Mesh.Vertices.Length; k++) {
                 ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates.X += (float)(y * Object.TextureShiftYDirection.X);
                 ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates.Y += (float)(y * Object.TextureShiftYDirection.Y);
             }
         }
     }
     // led
     bool led = Object.LEDFunction != null;
     double ledangle;
     if (led) {
         if (UpdateFunctions) {
             ledangle = Object.LEDFunction.Perform(Train, Position, TrackPosition, SectionIndex, TimeElapsed);
         } else {
             ledangle = Object.LEDFunction.LastResult;
         }
     } else {
         ledangle = 0.0;
     }
     // null object
     if (Object.States[s].Object == null) {
         return;
     }
     // initialize vertices
     for (int k = 0; k < Object.States[s].Object.Mesh.Vertices.Length; k++) {
         ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates = Object.States[s].Object.Mesh.Vertices[k].Coordinates;
     }
     // led
     if (led) {
         double max = Object.LEDMaximumAngle;
         for (int j = 0; j < 5; j++) {
             double pos1 = 0.0;
             double pos2 = 1.0;
             switch (j) {
                 case 0:
                     if (ledangle <= -0.5 * Math.PI) {
                         pos1 = 0.5;
                     } else if (ledangle >= 0.5 * Math.PI) {
                         pos1 = 1.0;
                     } else {
                         pos1 = 0.5 * Math.Tan(ledangle - 2.0 * Math.PI) + 0.5;
                         if (pos1 < 0.5) pos1 = 0.5;
                         else if (pos1 > 1.0) pos1 = 1.0;
                     }
                     if (max <= -0.5 * Math.PI) {
                         pos2 = 0.5;
                     } else if (max >= 0.5 * Math.PI) {
                         pos2 = 1.0;
                     } else {
                         pos2 = 0.5 * Math.Tan(max - 2.0 * Math.PI) + 0.5;
                         if (pos2 < 0.5) pos2 = 0.5;
                         else if (pos2 > 1.0) pos2 = 1.0;
                     }
                     break;
                 case 1:
                     if (ledangle <= 0.0) {
                         pos1 = 0.0;
                     } else if (ledangle >= Math.PI) {
                         pos1 = 1.0;
                     } else {
                         pos1 = 0.5 * Math.Tan(ledangle - 0.5 * Math.PI) + 0.5;
                         if (pos1 < 0.0) pos1 = 0.0;
                         else if (pos1 > 1.0) pos1 = 1.0;
                     }
                     if (max <= 0.0) {
                         pos2 = 0.0;
                     } else if (max >= Math.PI) {
                         pos2 = 1.0;
                     } else {
                         pos2 = 0.5 * Math.Tan(max - 0.5 * Math.PI) + 0.5;
                         if (pos2 < 0.0) pos2 = 0.0;
                         else if (pos2 > 1.0) pos2 = 1.0;
                     }
                     break;
                 case 2:
                     if (ledangle <= 0.5 * Math.PI) {
                         pos1 = 0.0;
                     } else if (ledangle >= 1.5 * Math.PI) {
                         pos1 = 1.0;
                     } else {
                         pos1 = 0.5 * Math.Tan(ledangle - Math.PI) + 0.5;
                         if (pos1 < 0.0) pos1 = 0.0;
                         else if (pos1 > 1.0) pos1 = 1.0;
                     }
                     if (max <= 0.5 * Math.PI) {
                         pos2 = 0.0;
                     } else if (max >= 1.5 * Math.PI) {
                         pos2 = 1.0;
                     } else {
                         pos2 = 0.5 * Math.Tan(max - Math.PI) + 0.5;
                         if (pos2 < 0.0) pos2 = 0.0;
                         else if (pos2 > 1.0) pos2 = 1.0;
                     }
                     break;
                 case 3:
                     if (ledangle <= Math.PI) {
                         pos1 = 0.0;
                     } else if (ledangle >= 2.0 * Math.PI) {
                         pos1 = 1.0;
                     } else {
                         pos1 = 0.5 * Math.Tan(ledangle - 1.5 * Math.PI) + 0.5;
                         if (pos1 < 0.0) pos1 = 0.0;
                         else if (pos1 > 1.0) pos1 = 1.0;
                     }
                     if (max <= Math.PI) {
                         pos2 = 0.0;
                     } else if (max >= 2.0 * Math.PI) {
                         pos2 = 1.0;
                     } else {
                         pos2 = 0.5 * Math.Tan(max - 1.5 * Math.PI) + 0.5;
                         if (pos2 < 0.0) pos2 = 0.0;
                         else if (pos2 > 1.0) pos2 = 1.0;
                     }
                     break;
                 case 4:
                     if (ledangle <= 1.5 * Math.PI) {
                         pos1 = 0.0;
                     } else if (ledangle >= 2.5 * Math.PI) {
                         pos1 = 0.5;
                     } else {
                         pos1 = 0.5 * Math.Tan(ledangle - 2.0 * Math.PI) + 0.5;
                         if (pos1 < 0.0) pos1 = 0.0;
                         else if (pos1 > 0.5) pos1 = 0.5;
                     }
                     if (max <= 1.5 * Math.PI) {
                         pos2 = 0.0;
                     } else if (max >= 2.5 * Math.PI) {
                         pos2 = 0.5;
                     } else {
                         pos2 = 0.5 * Math.Tan(max - 2.0 * Math.PI) + 0.5;
                         if (pos2 < 0.0) pos2 = 0.0;
                         else if (pos2 > 0.5) pos2 = 0.5;
                     }
                     break;
             }
             int k = 2 * j + 1;
             double cpos1 = 1.0 - pos1;
             double cpos2 = 1.0 - pos2;
             double x0 = Object.States[s].Object.Mesh.Vertices[k].Coordinates.X;
             double y0 = Object.States[s].Object.Mesh.Vertices[k].Coordinates.Y;
             double z0 = Object.States[s].Object.Mesh.Vertices[k].Coordinates.Z;
             double x1 = Object.States[s].Object.Mesh.Vertices[k + 1].Coordinates.X;
             double y1 = Object.States[s].Object.Mesh.Vertices[k + 1].Coordinates.Y;
             double z1 = Object.States[s].Object.Mesh.Vertices[k + 1].Coordinates.Z;
             if (Object.LEDClockwiseWinding) {
                 ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X = x0 * cpos1 + x1 * pos1;
                 ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y = y0 * cpos1 + y1 * pos1;
                 ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z = z0 * cpos1 + z1 * pos1;
                 ObjectManager.Objects[i].Mesh.Vertices[k + 1].Coordinates.X = x0 * cpos2 + x1 * pos2;
                 ObjectManager.Objects[i].Mesh.Vertices[k + 1].Coordinates.Y = y0 * cpos2 + y1 * pos2;
                 ObjectManager.Objects[i].Mesh.Vertices[k + 1].Coordinates.Z = z0 * cpos2 + z1 * pos2;
             } else {
                 ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X = x0 * cpos2 + x1 * pos2;
                 ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y = y0 * cpos2 + y1 * pos2;
                 ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z = z0 * cpos2 + z1 * pos2;
                 ObjectManager.Objects[i].Mesh.Vertices[k + 1].Coordinates.X = x0 * cpos1 + x1 * pos1;
                 ObjectManager.Objects[i].Mesh.Vertices[k + 1].Coordinates.Y = y0 * cpos1 + y1 * pos1;
                 ObjectManager.Objects[i].Mesh.Vertices[k + 1].Coordinates.Z = z0 * cpos1 + z1 * pos1;
             }
         }
     }
     // update vertices
     for (int k = 0; k < Object.States[s].Object.Mesh.Vertices.Length; k++) {
         // rotate
         if (rotateX) {
             World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z, Object.RotateXDirection.X, Object.RotateXDirection.Y, Object.RotateXDirection.Z, cosX, sinX);
         }
         if (rotateY) {
             World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z, Object.RotateYDirection.X, Object.RotateYDirection.Y, Object.RotateYDirection.Z, cosY, sinY);
         }
         if (rotateZ) {
             World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z, Object.RotateZDirection.X, Object.RotateZDirection.Y, Object.RotateZDirection.Z, cosZ, sinZ);
         }
         // translate
         if (Overlay & World.CameraRestriction != World.CameraRestrictionMode.NotAvailable) {
             ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X += Object.States[s].Position.X - Position.X;
             ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y += Object.States[s].Position.Y - Position.Y;
             ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z += Object.States[s].Position.Z - Position.Z;
             World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z, World.AbsoluteCameraDirection.X, World.AbsoluteCameraDirection.Y, World.AbsoluteCameraDirection.Z, World.AbsoluteCameraUp.X, World.AbsoluteCameraUp.Y, World.AbsoluteCameraUp.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z);
             double dx = -Math.Tan(World.CameraCurrentAlignment.Yaw) - World.CameraCurrentAlignment.Position.X;
             double dy = -Math.Tan(World.CameraCurrentAlignment.Pitch) - World.CameraCurrentAlignment.Position.Y;
             double dz = -World.CameraCurrentAlignment.Position.Z;
             ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X += World.AbsoluteCameraPosition.X + dx * World.AbsoluteCameraSide.X + dy * World.AbsoluteCameraUp.X + dz * World.AbsoluteCameraDirection.X;
             ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y += World.AbsoluteCameraPosition.Y + dx * World.AbsoluteCameraSide.Y + dy * World.AbsoluteCameraUp.Y + dz * World.AbsoluteCameraDirection.Y;
             ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z += World.AbsoluteCameraPosition.Z + dx * World.AbsoluteCameraSide.Z + dy * World.AbsoluteCameraUp.Z + dz * World.AbsoluteCameraDirection.Z;
         } else {
             ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X += Object.States[s].Position.X;
             ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y += Object.States[s].Position.Y;
             ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z += Object.States[s].Position.Z;
             World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z);
             ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X += Position.X;
             ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y += Position.Y;
             ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z += Position.Z;
         }
     }
     // update normals
     for (int k = 0; k < Object.States[s].Object.Mesh.Faces.Length; k++) {
         for (int h = 0; h < Object.States[s].Object.Mesh.Faces[k].Vertices.Length; h++) {
             ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal = Object.States[s].Object.Mesh.Faces[k].Vertices[h].Normal;
         }
         for (int h = 0; h < Object.States[s].Object.Mesh.Faces[k].Vertices.Length; h++) {
             if (!Object.States[s].Object.Mesh.Faces[k].Vertices[h].Normal.IsZero()) {
                 if (rotateX) {
                     World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.X, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Y, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Z, Object.RotateXDirection.X, Object.RotateXDirection.Y, Object.RotateXDirection.Z, cosX, sinX);
                 }
                 if (rotateY) {
                     World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.X, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Y, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Z, Object.RotateYDirection.X, Object.RotateYDirection.Y, Object.RotateYDirection.Z, cosY, sinY);
                 }
                 if (rotateZ) {
                     World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.X, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Y, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Z, Object.RotateZDirection.X, Object.RotateZDirection.Y, Object.RotateZDirection.Z, cosZ, sinZ);
                 }
                 World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.X, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Y, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Z, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z);
             }
         }
         // visibility changed
         if (Show) {
             Renderer.ShowObject(i, Overlay);
         } else {
             Renderer.HideObject(i);
         }
     }
 }
コード例 #9
0
ファイル: RendererS.cs プロジェクト: leezer3/OpenBVE
 // render cube
 private static void RenderBox(World.Vector3D Position, World.Vector3D Direction, World.Vector3D Up, World.Vector3D Side, World.Vector3D Size, double CameraX, double CameraY, double CameraZ)
 {
     if (TexturingEnabled)
     {
         GL.Disable(EnableCap.Texture2D);
         TexturingEnabled = false;
     }
     World.Vector3D[] v = new World.Vector3D[8];
     v[0] = new World.Vector3D(Size.X, Size.Y, -Size.Z);
     v[1] = new World.Vector3D(Size.X, -Size.Y, -Size.Z);
     v[2] = new World.Vector3D(-Size.X, -Size.Y, -Size.Z);
     v[3] = new World.Vector3D(-Size.X, Size.Y, -Size.Z);
     v[4] = new World.Vector3D(Size.X, Size.Y, Size.Z);
     v[5] = new World.Vector3D(Size.X, -Size.Y, Size.Z);
     v[6] = new World.Vector3D(-Size.X, -Size.Y, Size.Z);
     v[7] = new World.Vector3D(-Size.X, Size.Y, Size.Z);
     for (int i = 0; i < 8; i++)
     {
         World.Rotate(ref v[i].X, ref v[i].Y, ref v[i].Z, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z);
         v[i].X += Position.X - CameraX;
         v[i].Y += Position.Y - CameraY;
         v[i].Z += Position.Z - CameraZ;
     }
     int[][] Faces = new int[6][];
     Faces[0] = new int[] { 0, 1, 2, 3 };
     Faces[1] = new int[] { 0, 4, 5, 1 };
     Faces[2] = new int[] { 0, 3, 7, 4 };
     Faces[3] = new int[] { 6, 5, 4, 7 };
     Faces[4] = new int[] { 6, 7, 3, 2 };
     Faces[5] = new int[] { 6, 2, 1, 5 };
     for (int i = 0; i < 6; i++)
     {
         GL.Begin(PrimitiveType.Quads);
         for (int j = 0; j < 4; j++)
         {
             GL.Vertex3(v[Faces[i][j]].X, v[Faces[i][j]].Y, v[Faces[i][j]].Z);
         }
         GL.End();
     }
 }
コード例 #10
0
		// load all textures
		private static int[] LoadAllTextures(string BaseFile, World.ColorRGB TransparentColor, byte TransparentColorUsed, TextureManager.TextureLoadMode LoadMode) {
			string Folder = System.IO.Path.GetDirectoryName(BaseFile);
			if (!System.IO.Directory.Exists(Folder)) return new int[] { };
			string Name = System.IO.Path.GetFileNameWithoutExtension(BaseFile);
			int[] Textures = new int[] { };
			string[] Files = System.IO.Directory.GetFiles(Folder);
			for (int i = 0; i < Files.Length; i++) {
				string a = System.IO.Path.GetFileNameWithoutExtension(Files[i]);
				if (a.StartsWith(Name, StringComparison.OrdinalIgnoreCase)) {
					if (a.Length > Name.Length) {
						string b = a.Substring(Name.Length).TrimStart();
						int j; if (int.TryParse(b, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out j)) {
							if (j >= 0) {
								string c = System.IO.Path.GetExtension(Files[i]);
								switch (c.ToLowerInvariant()) {
									case ".bmp":
									case ".gif":
									case ".jpg":
									case ".jpeg":
									case ".png":
									case ".tif":
									case ".tiff":
										if (j >= Textures.Length) {
											int n = Textures.Length;
											Array.Resize<int>(ref Textures, j + 1);
											for (int k = n; k < j; k++) {
												Textures[k] = -1;
											}
										}
										Textures[j] = TextureManager.RegisterTexture(Files[i], TransparentColor, TransparentColorUsed, LoadMode, TextureManager.TextureWrapMode.Repeat, TextureManager.TextureWrapMode.Repeat, true, 0, 0, 0, 0);
										TextureManager.UseTexture(Textures[j], TextureManager.UseMode.Normal);
										break;
								}
							}
						}
					}
				}
			} return Textures;
		}
コード例 #11
0
ファイル: RendererS.cs プロジェクト: leezer3/OpenBVE
 private static void RenderFace(ref World.MeshMaterial Material, World.Vertex[] Vertices, ref World.MeshFace Face, double CameraX, double CameraY, double CameraZ)
 {
     // texture
     int OpenGlNighttimeTextureIndex = Material.NighttimeTextureIndex >= 0 ? TextureManager.UseTexture(Material.NighttimeTextureIndex, TextureManager.UseMode.Normal) : 0;
     int OpenGlDaytimeTextureIndex = Material.DaytimeTextureIndex >= 0 ? TextureManager.UseTexture(Material.DaytimeTextureIndex, TextureManager.UseMode.Normal) : 0;
     if (OpenGlDaytimeTextureIndex != 0)
     {
         if (!TexturingEnabled)
         {
             GL.Enable(EnableCap.Texture2D);
             TexturingEnabled = true;
         }
         if (OpenGlDaytimeTextureIndex != LastBoundTexture)
         {
             GL.BindTexture(TextureTarget.Texture2D, OpenGlDaytimeTextureIndex);
             LastBoundTexture = OpenGlDaytimeTextureIndex;
         }
         if (TextureManager.Textures[Material.DaytimeTextureIndex].Transparency != TextureManager.TextureTransparencyMode.None)
         {
             if (!AlphaTestEnabled)
             {
                 GL.Enable(EnableCap.AlphaTest);
                 AlphaTestEnabled = true;
             }
         }
         else if (AlphaTestEnabled)
         {
             GL.Disable(EnableCap.AlphaTest);
             AlphaTestEnabled = false;
         }
     }
     else
     {
         if (TexturingEnabled)
         {
             GL.Disable(EnableCap.Texture2D);
             TexturingEnabled = false;
             LastBoundTexture = 0;
         }
         if (AlphaTestEnabled)
         {
             GL.Disable(EnableCap.AlphaTest);
             AlphaTestEnabled = false;
         }
     }
     // blend mode
     float factor;
     if (Material.BlendMode == World.MeshMaterialBlendMode.Additive)
     {
         factor = 1.0f;
         if (!BlendEnabled) GL.Enable(EnableCap.Blend);
         GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One);
         if (FogEnabled)
         {
             GL.Disable(EnableCap.Fog);
         }
     }
     else if (OpenGlNighttimeTextureIndex == 0)
     {
         float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
         if (blend > 1.0f) blend = 1.0f;
         factor = 1.0f - 0.8f * blend;
     }
     else
     {
         factor = 1.0f;
     }
     if (OpenGlNighttimeTextureIndex != 0)
     {
         if (LightingEnabled)
         {
             GL.Disable(EnableCap.Lighting);
             LightingEnabled = false;
         }
     }
     else
     {
         if (OptionLighting & !LightingEnabled)
         {
             GL.Enable(EnableCap.Lighting);
             LightingEnabled = true;
         }
     }
     // render daytime polygon
     int FaceType = Face.Flags & World.MeshFace.FaceTypeMask;
     switch (FaceType)
     {
         case World.MeshFace.FaceTypeTriangles:
             GL.Begin(PrimitiveType.Triangles);
             break;
         case World.MeshFace.FaceTypeTriangleStrip:
             GL.Begin(PrimitiveType.TriangleStrip);
             break;
         case World.MeshFace.FaceTypeQuads:
             GL.Begin(PrimitiveType.Quads);
             break;
         case World.MeshFace.FaceTypeQuadStrip:
             GL.Begin(PrimitiveType.QuadStrip);
             break;
         default:
             GL.Begin(PrimitiveType.Polygon);
             break;
     }
     if (Material.GlowAttenuationData != 0)
     {
         float alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
         GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
     }
     else
     {
         GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A);
     }
     if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0)
     {
         GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 * (float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
         EmissiveEnabled = true;
     }
     else if (EmissiveEnabled)
     {
         GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
         EmissiveEnabled = false;
     }
     if (OpenGlDaytimeTextureIndex != 0)
     {
         if (LightingEnabled)
         {
             for (int j = 0; j < Face.Vertices.Length; j++)
             {
                 GL.Normal3(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                 GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                 GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
         else
         {
             for (int j = 0; j < Face.Vertices.Length; j++)
             {
                 GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                 GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
     }
     else
     {
         if (LightingEnabled)
         {
             for (int j = 0; j < Face.Vertices.Length; j++)
             {
                 GL.Normal3(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                 GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
         else
         {
             for (int j = 0; j < Face.Vertices.Length; j++)
             {
                 GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
     }
     GL.End();
     // render nighttime polygon
     if (OpenGlNighttimeTextureIndex != 0)
     {
         if (!TexturingEnabled)
         {
             GL.Enable(EnableCap.Texture2D);
             TexturingEnabled = true;
         }
         if (!BlendEnabled)
         {
             GL.Enable(EnableCap.Blend);
         }
         GL.BindTexture(TextureTarget.Texture2D, OpenGlNighttimeTextureIndex);
         LastBoundTexture = 0;
         SetAlphaFunc(AlphaFunction.Greater, 0.0f);
         switch (FaceType)
         {
             case World.MeshFace.FaceTypeTriangles:
                 GL.Begin(PrimitiveType.Triangles);
                 break;
             case World.MeshFace.FaceTypeTriangleStrip:
                 GL.Begin(PrimitiveType.TriangleStrip);
                 break;
             case World.MeshFace.FaceTypeQuads:
                 GL.Begin(PrimitiveType.Quads);
                 break;
             case World.MeshFace.FaceTypeQuadStrip:
                 GL.Begin(PrimitiveType.QuadStrip);
                 break;
             default:
                 GL.Begin(PrimitiveType.Polygon);
                 break;
         }
         float alphafactor;
         if (Material.GlowAttenuationData != 0)
         {
             alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
             float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
             if (blend > 1.0f) blend = 1.0f;
             alphafactor *= blend;
         }
         else
         {
             alphafactor = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
             if (alphafactor > 1.0f) alphafactor = 1.0f;
         }
         GL.Color4(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
         if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0)
         {
             GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { inv255 * (float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
             EmissiveEnabled = true;
         }
         else if (EmissiveEnabled)
         {
             GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Emission, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
             EmissiveEnabled = false;
         }
         for (int j = 0; j < Face.Vertices.Length; j++)
         {
             GL.TexCoord2(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
             GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
         }
         GL.End();
         if (AlphaFuncValue != 0.0)
         {
             GL.AlphaFunc(AlphaFuncComparison, AlphaFuncValue);
         }
         if (!BlendEnabled)
         {
             GL.Disable(EnableCap.Blend);
         }
     }
     // normals
     if (OptionNormals)
     {
         if (TexturingEnabled)
         {
             GL.Disable(EnableCap.Texture2D);
             TexturingEnabled = false;
         }
         if (AlphaTestEnabled)
         {
             GL.Disable(EnableCap.AlphaTest);
             AlphaTestEnabled = false;
         }
         for (int j = 0; j < Face.Vertices.Length; j++)
         {
             GL.Begin(PrimitiveType.Lines);
             GL.Color4(inv255 * (float)Material.Color.R, inv255 * (float)Material.Color.G, inv255 * (float)Material.Color.B, 1.0f);
             GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             GL.Vertex3((float)(Vertices[Face.Vertices[j].Index].Coordinates.X + Face.Vertices[j].Normal.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y + Face.Vertices[j].Normal.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z + Face.Vertices[j].Normal.Z - CameraZ));
             GL.End();
         }
     }
     // finalize
     if (Material.BlendMode == World.MeshMaterialBlendMode.Additive)
     {
         GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
         if (!BlendEnabled) GL.Disable(EnableCap.Blend);
         if (FogEnabled)
         {
             GL.Enable(EnableCap.Fog);
         }
     }
 }
コード例 #12
0
ファイル: TextureManager.cs プロジェクト: leezer3/OpenBVE
		internal static int RegisterTexture(Bitmap Bitmap, World.ColorRGB TransparentColor)
		{
			int i = GetFreeTexture();
			int[] a = new int[1];
			GL.GenTextures(1, a);
			Textures[i] = new Texture();
			Textures[i].Queried = false;
			Textures[i].OpenGlTextureIndex = a[0];
			Textures[i].Transparency = TextureTransparencyMode.TransparentColor;
			Textures[i].TransparentColor = TransparentColor;
			Textures[i].TransparentColorUsed = 1;
			Textures[i].FileName = null;
			Textures[i].Loaded = true;
			Textures[i].DontAllowUnload = true;
			LoadTextureRGBAforData(Bitmap, Textures[i].TransparentColor, Textures[i].TransparentColorUsed, i);
			LoadTextureRGBAforOpenGl(i);
			return i;
		}
コード例 #13
0
ファイル: WorldS.cs プロジェクト: AlteredCarrot71/OpenBVExp
        // update absolute camera
        internal static void UpdateAbsoluteCamera(double TimeElapsed)
        {
            // zoom
            double zm = World.CameraCurrentAlignment.Zoom;

            AdjustAlignment(ref World.CameraCurrentAlignment.Zoom, World.CameraAlignmentDirection.Zoom, ref World.CameraAlignmentSpeed.Zoom, TimeElapsed, World.CameraAlignmentSpeed.Zoom != 0.0);
            if (zm != World.CameraCurrentAlignment.Zoom)
            {
                ApplyZoom();
            }
            // current alignment
            AdjustAlignment(ref World.CameraCurrentAlignment.Position.X, World.CameraAlignmentDirection.Position.X, ref World.CameraAlignmentSpeed.Position.X, TimeElapsed);
            AdjustAlignment(ref World.CameraCurrentAlignment.Position.Y, World.CameraAlignmentDirection.Position.Y, ref World.CameraAlignmentSpeed.Position.Y, TimeElapsed);
            bool q = World.CameraAlignmentSpeed.Yaw != 0.0 | World.CameraAlignmentSpeed.Pitch != 0.0 | World.CameraAlignmentSpeed.Roll != 0.0;

            AdjustAlignment(ref World.CameraCurrentAlignment.Yaw, World.CameraAlignmentDirection.Yaw, ref World.CameraAlignmentSpeed.Yaw, TimeElapsed);
            AdjustAlignment(ref World.CameraCurrentAlignment.Pitch, World.CameraAlignmentDirection.Pitch, ref World.CameraAlignmentSpeed.Pitch, TimeElapsed);
            AdjustAlignment(ref World.CameraCurrentAlignment.Roll, World.CameraAlignmentDirection.Roll, ref World.CameraAlignmentSpeed.Roll, TimeElapsed);
            double tr = World.CameraCurrentAlignment.TrackPosition;

            AdjustAlignment(ref World.CameraCurrentAlignment.TrackPosition, World.CameraAlignmentDirection.TrackPosition, ref World.CameraAlignmentSpeed.TrackPosition, TimeElapsed);
            if (tr != World.CameraCurrentAlignment.TrackPosition)
            {
                TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, World.CameraCurrentAlignment.TrackPosition, true, false);
                q = true;
            }
            if (q)
            {
                UpdateViewingDistances();
            }
            double dx = World.CameraTrackFollower.WorldDirection.X;
            double dy = World.CameraTrackFollower.WorldDirection.Y;
            double dz = World.CameraTrackFollower.WorldDirection.Z;
            double ux = World.CameraTrackFollower.WorldUp.X;
            double uy = World.CameraTrackFollower.WorldUp.Y;
            double uz = World.CameraTrackFollower.WorldUp.Z;
            double sx = World.CameraTrackFollower.WorldSide.X;
            double sy = World.CameraTrackFollower.WorldSide.Y;
            double sz = World.CameraTrackFollower.WorldSide.Z;
            double tx = World.CameraCurrentAlignment.Position.X;
            double ty = World.CameraCurrentAlignment.Position.Y;
            double tz = World.CameraCurrentAlignment.Position.Z;
            double dx2 = dx, dy2 = dy, dz2 = dz;
            double ux2 = ux, uy2 = uy, uz2 = uz;
            double cx = World.CameraTrackFollower.WorldPosition.X + sx * tx + ux2 * ty + dx2 * tz;
            double cy = World.CameraTrackFollower.WorldPosition.Y + sy * tx + uy2 * ty + dy2 * tz;
            double cz = World.CameraTrackFollower.WorldPosition.Z + sz * tx + uz2 * ty + dz2 * tz;

            if (World.CameraCurrentAlignment.Yaw != 0.0)
            {
                double cosa = Math.Cos(World.CameraCurrentAlignment.Yaw);
                double sina = Math.Sin(World.CameraCurrentAlignment.Yaw);
                World.Rotate(ref dx, ref dy, ref dz, ux, uy, uz, cosa, sina);
                World.Rotate(ref sx, ref sy, ref sz, ux, uy, uz, cosa, sina);
            }
            double p = World.CameraCurrentAlignment.Pitch;

            if (p != 0.0)
            {
                double cosa = Math.Cos(-p);
                double sina = Math.Sin(-p);
                World.Rotate(ref dx, ref dy, ref dz, sx, sy, sz, cosa, sina);
                World.Rotate(ref ux, ref uy, ref uz, sx, sy, sz, cosa, sina);
            }
            if (World.CameraCurrentAlignment.Roll != 0.0)
            {
                double cosa = Math.Cos(-World.CameraCurrentAlignment.Roll);
                double sina = Math.Sin(-World.CameraCurrentAlignment.Roll);
                World.Rotate(ref ux, ref uy, ref uz, dx, dy, dz, cosa, sina);
                World.Rotate(ref sx, ref sy, ref sz, dx, dy, dz, cosa, sina);
            }
            AbsoluteCameraPosition  = new Vector3D(cx, cy, cz);
            AbsoluteCameraDirection = new Vector3D(dx, dy, dz);
            AbsoluteCameraUp        = new Vector3D(ux, uy, uz);
            AbsoluteCameraSide      = new Vector3D(sx, sy, sz);
        }
コード例 #14
0
			internal double Perform(TrainManager.Train Train, int CarIndex, World.Vector3D Position, double TrackPosition, int SectionIndex, bool IsPartOfTrain, double TimeElapsed) {
				ExecuteFunctionScript(this, Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed);
				return this.LastResult;
			}
コード例 #15
0
ファイル: Renderer.cs プロジェクト: openbve/OpenBVE
 private static void RenderBackground(World.Background Data, double dx, double dy, double dz, float Alpha, float scale)
 {
     if (Data.Texture != null && Textures.LoadTexture(Data.Texture, Textures.OpenGlTextureWrapMode.RepeatClamp)) {
         if (LightingEnabled) {
             Gl.glDisable(Gl.GL_LIGHTING);
             LightingEnabled = false;
         }
         if (!TexturingEnabled) {
             Gl.glEnable(Gl.GL_TEXTURE_2D);
             TexturingEnabled = true;
         }
         if (Alpha == 1.0f) {
             if (BlendEnabled) {
                 Gl.glDisable(Gl.GL_BLEND);
                 BlendEnabled = false;
             }
         } else if (!BlendEnabled) {
             Gl.glEnable(Gl.GL_BLEND);
             BlendEnabled = true;
         }
         Gl.glBindTexture(Gl.GL_TEXTURE_2D, Data.Texture.OpenGlTextures[(int)Textures.OpenGlTextureWrapMode.RepeatClamp].Name);
         Gl.glColor4f(1.0f, 1.0f, 1.0f, Alpha);
         float y0, y1;
         if (Data.KeepAspectRatio) {
             int tw = Data.Texture.Width;
             int th = Data.Texture.Height;
             double hh = Math.PI * World.BackgroundImageDistance * (double)th / ((double)tw * (double)Data.Repetition);
             y0 = (float)(-0.5 * hh);
             y1 = (float)(1.5 * hh);
         } else {
             y0 = (float)(-0.125 * World.BackgroundImageDistance);
             y1 = (float)(0.375 * World.BackgroundImageDistance);
         }
         const int n = 32;
         World.Vector3Df[] bottom = new World.Vector3Df[n];
         World.Vector3Df[] top = new World.Vector3Df[n];
         double angleValue = 2.61799387799149 - 3.14159265358979 / (double)n;
         double angleIncrement = 6.28318530717958 / (double)n;
         /*
          * To ensure that the whole background cylinder is rendered inside the viewing frustum,
          * the background is rendered before the scene with z-buffer writes disabled. Then,
          * the actual distance from the camera is irrelevant as long as it is inside the frustum.
          * */
         for (int i = 0; i < n; i++) {
             float x = (float)(World.BackgroundImageDistance * Math.Cos(angleValue));
             float z = (float)(World.BackgroundImageDistance * Math.Sin(angleValue));
             bottom[i] = new World.Vector3Df(scale * x, scale * y0, scale * z);
             top[i] = new World.Vector3Df(scale * x, scale * y1, scale * z);
             angleValue += angleIncrement;
         }
         float textureStart = 0.5f * (float)Data.Repetition / (float)n;
         float textureIncrement = -(float)Data.Repetition / (float)n;
         double textureX = textureStart;
         for (int i = 0; i < n; i++) {
             int j = (i + 1) % n;
             // side wall
             Gl.glBegin(Gl.GL_QUADS);
             Gl.glTexCoord2d(textureX, 0.005f);
             Gl.glVertex3f(top[i].X, top[i].Y, top[i].Z);
             Gl.glTexCoord2d(textureX, 0.995f);
             Gl.glVertex3f(bottom[i].X, bottom[i].Y, bottom[i].Z);
             Gl.glTexCoord2d(textureX + textureIncrement, 0.995f);
             Gl.glVertex3f(bottom[j].X, bottom[j].Y, bottom[j].Z);
             Gl.glTexCoord2d(textureX + textureIncrement, 0.005f);
             Gl.glVertex3f(top[j].X, top[j].Y, top[j].Z);
             Gl.glEnd();
             // top cap
             Gl.glBegin(Gl.GL_TRIANGLES);
             Gl.glTexCoord2d(textureX, 0.005f);
             Gl.glVertex3f(top[i].X, top[i].Y, top[i].Z);
             Gl.glTexCoord2d(textureX + textureIncrement, 0.005f);
             Gl.glVertex3f(top[j].X, top[j].Y, top[j].Z);
             Gl.glTexCoord2d(textureX + 0.5 * textureIncrement, 0.1f);
             Gl.glVertex3f(0.0f, top[i].Y, 0.0f);
             // bottom cap
             Gl.glTexCoord2d(textureX + 0.5 * textureIncrement, 0.9f);
             Gl.glVertex3f(0.0f, bottom[i].Y, 0.0f);
             Gl.glTexCoord2d(textureX + textureIncrement, 0.995f);
             Gl.glVertex3f(bottom[j].X, bottom[j].Y, bottom[j].Z);
             Gl.glTexCoord2d(textureX, 0.995f);
             Gl.glVertex3f(bottom[i].X, bottom[i].Y, bottom[i].Z);
             Gl.glEnd();
             // finish
             textureX += textureIncrement;
         }
         Gl.glDisable(Gl.GL_TEXTURE_2D);
         TexturingEnabled = false;
         if (!BlendEnabled) {
             Gl.glEnable(Gl.GL_BLEND);
             BlendEnabled = true;
         }
     }
 }
コード例 #16
0
ファイル: PointsOfInterest.cs プロジェクト: ian2009/OpenBVE
        /// <summary>Moves the camera to a point of interest</summary>
        /// <param name="Value">The value of the jump to perform:
        /// -1= Previous POI
        ///  0= Return to currently selected POI (From cab etc.)
        ///  1= Next POI</param>
        /// <param name="Relative">Whether the relative camera position should be retained</param>
        /// <returns>False if the previous / next POI would be outside those defined, true otherwise</returns>
        internal static bool ApplyPointOfInterest(int Value, bool Relative)
        {
            double t = 0.0;
            int    j = -1;

            if (Relative)
            {
                // relative
                if (Value < 0)
                {
                    // previous poi
                    t = double.NegativeInfinity;
                    for (int i = 0; i < Program.CurrentRoute.PointsOfInterest.Length; i++)
                    {
                        if (Program.CurrentRoute.PointsOfInterest[i].TrackPosition < World.CameraTrackFollower.TrackPosition)
                        {
                            if (Program.CurrentRoute.PointsOfInterest[i].TrackPosition > t)
                            {
                                t = Program.CurrentRoute.PointsOfInterest[i].TrackPosition;
                                j = i;
                            }
                        }
                    }
                }
                else if (Value > 0)
                {
                    // next poi
                    t = double.PositiveInfinity;
                    for (int i = 0; i < Program.CurrentRoute.PointsOfInterest.Length; i++)
                    {
                        if (Program.CurrentRoute.PointsOfInterest[i].TrackPosition > World.CameraTrackFollower.TrackPosition)
                        {
                            if (Program.CurrentRoute.PointsOfInterest[i].TrackPosition < t)
                            {
                                t = Program.CurrentRoute.PointsOfInterest[i].TrackPosition;
                                j = i;
                            }
                        }
                    }
                }
            }
            else
            {
                // absolute
                j = Value >= 0 & Value < Program.CurrentRoute.PointsOfInterest.Length ? Value : -1;
            }
            // process poi
            if (j < 0)
            {
                return(false);
            }
            World.CameraTrackFollower.UpdateAbsolute(t, true, false);
            Program.Renderer.Camera.Alignment.Position      = Program.CurrentRoute.PointsOfInterest[j].TrackOffset;
            Program.Renderer.Camera.Alignment.Yaw           = Program.CurrentRoute.PointsOfInterest[j].TrackYaw;
            Program.Renderer.Camera.Alignment.Pitch         = Program.CurrentRoute.PointsOfInterest[j].TrackPitch;
            Program.Renderer.Camera.Alignment.Roll          = Program.CurrentRoute.PointsOfInterest[j].TrackRoll;
            Program.Renderer.Camera.Alignment.TrackPosition = t;
            World.UpdateAbsoluteCamera(0.0);
            if (Program.CurrentRoute.PointsOfInterest[j].Text != null)
            {
                double n = 3.0 + 0.5 * Math.Sqrt((double)Program.CurrentRoute.PointsOfInterest[j].Text.Length);
                Game.AddMessage(Program.CurrentRoute.PointsOfInterest[j].Text, MessageDependency.PointOfInterest, GameMode.Expert, MessageColor.White, Program.CurrentRoute.SecondsSinceMidnight + n, null);
            }
            return(true);
        }
コード例 #17
0
ファイル: Renderer.cs プロジェクト: openbve/OpenBVE
 private static void RenderFace(ref World.MeshMaterial Material, World.Vertex[] Vertices, Textures.OpenGlTextureWrapMode wrap, ref World.MeshFace Face, double CameraX, double CameraY, double CameraZ)
 {
     // texture
     if (Material.DaytimeTexture != null) {
         if (Textures.LoadTexture(Material.DaytimeTexture, wrap)) {
             if (!TexturingEnabled) {
                 Gl.glEnable(Gl.GL_TEXTURE_2D);
                 TexturingEnabled = true;
             }
             if (Material.DaytimeTexture.OpenGlTextures[(int)wrap] != LastBoundTexture) {
                 Gl.glBindTexture(Gl.GL_TEXTURE_2D, Material.DaytimeTexture.OpenGlTextures[(int)wrap].Name);
                 LastBoundTexture = Material.DaytimeTexture.OpenGlTextures[(int)wrap];
             }
         } else {
             if (TexturingEnabled) {
                 Gl.glDisable(Gl.GL_TEXTURE_2D);
                 TexturingEnabled = false;
                 LastBoundTexture = null;
             }
         }
     } else {
         if (TexturingEnabled) {
             Gl.glDisable(Gl.GL_TEXTURE_2D);
             TexturingEnabled = false;
             LastBoundTexture = null;
         }
     }
     // blend mode
     float factor;
     if (Material.BlendMode == World.MeshMaterialBlendMode.Additive) {
         factor = 1.0f;
         if (!BlendEnabled) Gl.glEnable(Gl.GL_BLEND);
         Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE);
         if (FogEnabled) {
             Gl.glDisable(Gl.GL_FOG);
         }
     } else if (Material.NighttimeTexture == null) {
         float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
         if (blend > 1.0f) blend = 1.0f;
         factor = 1.0f - 0.7f * blend;
     } else {
         factor = 1.0f;
     }
     if (Material.NighttimeTexture != null) {
         if (LightingEnabled) {
             Gl.glDisable(Gl.GL_LIGHTING);
             LightingEnabled = false;
         }
     } else {
         if (OptionLighting & !LightingEnabled) {
             Gl.glEnable(Gl.GL_LIGHTING);
             LightingEnabled = true;
         }
     }
     // render daytime polygon
     int FaceType = Face.Flags & World.MeshFace.FaceTypeMask;
     switch (FaceType) {
         case World.MeshFace.FaceTypeTriangles:
             Gl.glBegin(Gl.GL_TRIANGLES);
             break;
         case World.MeshFace.FaceTypeTriangleStrip:
             Gl.glBegin(Gl.GL_TRIANGLE_STRIP);
             break;
         case World.MeshFace.FaceTypeQuads:
             Gl.glBegin(Gl.GL_QUADS);
             break;
         case World.MeshFace.FaceTypeQuadStrip:
             Gl.glBegin(Gl.GL_QUAD_STRIP);
             break;
         default:
             Gl.glBegin(Gl.GL_POLYGON);
             break;
     }
     if (Material.GlowAttenuationData != 0) {
         float alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
         Gl.glColor4f(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
     } else {
         Gl.glColor4f(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A);
     }
     if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0) {
         Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { inv255 * (float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
         EmissiveEnabled = true;
     } else if (EmissiveEnabled) {
         Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
         EmissiveEnabled = false;
     }
     if (Material.DaytimeTexture != null) {
         if (LightingEnabled) {
             for (int j = 0; j < Face.Vertices.Length; j++) {
                 Gl.glNormal3f(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                 Gl.glTexCoord2f(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                 Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         } else {
             for (int j = 0; j < Face.Vertices.Length; j++) {
                 Gl.glTexCoord2f(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
                 Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
     } else {
         if (LightingEnabled) {
             for (int j = 0; j < Face.Vertices.Length; j++) {
                 Gl.glNormal3f(Face.Vertices[j].Normal.X, Face.Vertices[j].Normal.Y, Face.Vertices[j].Normal.Z);
                 Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         } else {
             for (int j = 0; j < Face.Vertices.Length; j++) {
                 Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             }
         }
     }
     Gl.glEnd();
     // render nighttime polygon
     if (Material.NighttimeTexture != null && Textures.LoadTexture(Material.NighttimeTexture, wrap)) {
         if (!TexturingEnabled) {
             Gl.glEnable(Gl.GL_TEXTURE_2D);
             TexturingEnabled = true;
         }
         if (!BlendEnabled) {
             Gl.glEnable(Gl.GL_BLEND);
         }
         Gl.glBindTexture(Gl.GL_TEXTURE_2D, Material.NighttimeTexture.OpenGlTextures[(int)wrap].Name);
         LastBoundTexture = null;
         Gl.glAlphaFunc(Gl.GL_GREATER, 0.0f);
         Gl.glEnable(Gl.GL_ALPHA_TEST);
         switch (FaceType) {
             case World.MeshFace.FaceTypeTriangles:
                 Gl.glBegin(Gl.GL_TRIANGLES);
                 break;
             case World.MeshFace.FaceTypeTriangleStrip:
                 Gl.glBegin(Gl.GL_TRIANGLE_STRIP);
                 break;
             case World.MeshFace.FaceTypeQuads:
                 Gl.glBegin(Gl.GL_QUADS);
                 break;
             case World.MeshFace.FaceTypeQuadStrip:
                 Gl.glBegin(Gl.GL_QUAD_STRIP);
                 break;
             default:
                 Gl.glBegin(Gl.GL_POLYGON);
                 break;
         }
         float alphafactor;
         if (Material.GlowAttenuationData != 0) {
             alphafactor = (float)GetDistanceFactor(Vertices, ref Face, Material.GlowAttenuationData, CameraX, CameraY, CameraZ);
             float blend = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
             if (blend > 1.0f) blend = 1.0f;
             alphafactor *= blend;
         } else {
             alphafactor = inv255 * (float)Material.DaytimeNighttimeBlend + 1.0f - OptionLightingResultingAmount;
             if (alphafactor > 1.0f) alphafactor = 1.0f;
         }
         Gl.glColor4f(inv255 * (float)Material.Color.R * factor, inv255 * Material.Color.G * factor, inv255 * (float)Material.Color.B * factor, inv255 * (float)Material.Color.A * alphafactor);
         if ((Material.Flags & World.MeshMaterial.EmissiveColorMask) != 0) {
             Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { inv255 * (float)Material.EmissiveColor.R, inv255 * (float)Material.EmissiveColor.G, inv255 * (float)Material.EmissiveColor.B, 1.0f });
             EmissiveEnabled = true;
         } else if (EmissiveEnabled) {
             Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_EMISSION, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });
             EmissiveEnabled = false;
         }
         for (int j = 0; j < Face.Vertices.Length; j++) {
             Gl.glTexCoord2f(Vertices[Face.Vertices[j].Index].TextureCoordinates.X, Vertices[Face.Vertices[j].Index].TextureCoordinates.Y);
             Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
         }
         Gl.glEnd();
         RestoreAlphaFunc();
         if (!BlendEnabled) {
             Gl.glDisable(Gl.GL_BLEND);
         }
     }
     // normals
     if (OptionNormals) {
         if (TexturingEnabled) {
             Gl.glDisable(Gl.GL_TEXTURE_2D);
             TexturingEnabled = false;
         }
         for (int j = 0; j < Face.Vertices.Length; j++) {
             Gl.glBegin(Gl.GL_LINES);
             Gl.glColor4f(inv255 * (float)Material.Color.R, inv255 * (float)Material.Color.G, inv255 * (float)Material.Color.B, 1.0f);
             Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z - CameraZ));
             Gl.glVertex3f((float)(Vertices[Face.Vertices[j].Index].Coordinates.X + Face.Vertices[j].Normal.X - CameraX), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Y + Face.Vertices[j].Normal.Y - CameraY), (float)(Vertices[Face.Vertices[j].Index].Coordinates.Z + Face.Vertices[j].Normal.Z - CameraZ));
             Gl.glEnd();
         }
     }
     // finalize
     if (Material.BlendMode == World.MeshMaterialBlendMode.Additive) {
         Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
         if (!BlendEnabled) Gl.glDisable(Gl.GL_BLEND);
         if (FogEnabled) {
             Gl.glEnable(Gl.GL_FOG);
         }
     }
 }
コード例 #18
0
ファイル: ObjectManager.cs プロジェクト: JakubVanek/openBVE-1
		internal static void UpdateAnimatedObject(ref AnimatedObject Object, bool IsPartOfTrain, TrainManager.Train Train, int CarIndex, int SectionIndex, double TrackPosition, World.Vector3D Position, World.Vector3D Direction, World.Vector3D Up, World.Vector3D Side, bool Overlay, bool UpdateFunctions, bool Show, double TimeElapsed) {
			int s = Object.CurrentState;
			int i = Object.ObjectIndex;
			// state change
			if (Object.StateFunction != null & UpdateFunctions) {
				double sd = Object.StateFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed);
				int si = (int)Math.Round(sd);
				int sn = Object.States.Length;
				if (si < 0 | si >= sn) si = -1;
				if (s != si) {
					InitializeAnimatedObject(ref Object, si, Overlay, Show);
					s = si;
				}
			}
			if (s == -1) return;
			// translation
			if (Object.TranslateXFunction != null) {
				double x;
				if (UpdateFunctions) {
					x = Object.TranslateXFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed);
				} else  {
					x = Object.TranslateXFunction.LastResult;
				}
				double rx = Object.TranslateXDirection.X, ry = Object.TranslateXDirection.Y, rz = Object.TranslateXDirection.Z;
				World.Rotate(ref rx, ref ry, ref rz, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z);
				Position.X += x * rx;
				Position.Y += x * ry;
				Position.Z += x * rz;
			}
			if (Object.TranslateYFunction != null) {
				double y;
				if (UpdateFunctions) {
					y = Object.TranslateYFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed);
				} else {
					y = Object.TranslateYFunction.LastResult;
				}
				double rx = Object.TranslateYDirection.X, ry = Object.TranslateYDirection.Y, rz = Object.TranslateYDirection.Z;
				World.Rotate(ref rx, ref ry, ref rz, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z);
				Position.X += y * rx;
				Position.Y += y * ry;
				Position.Z += y * rz;
			}
			if (Object.TranslateZFunction != null) {
				double z;
				if (UpdateFunctions) {
					z = Object.TranslateZFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed);
				} else {
					z = Object.TranslateZFunction.LastResult;
				}
				double rx = Object.TranslateZDirection.X, ry = Object.TranslateZDirection.Y, rz = Object.TranslateZDirection.Z;
				World.Rotate(ref rx, ref ry, ref rz, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z);
				Position.X += z * rx;
				Position.Y += z * ry;
				Position.Z += z * rz;
			}
			// rotation
			bool rotateX = Object.RotateXFunction != null;
			bool rotateY = Object.RotateYFunction != null;
			bool rotateZ = Object.RotateZFunction != null;
			double cosX, sinX;
			if (rotateX) {
				double a;
				if (UpdateFunctions) {
					a = Object.RotateXFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed);
				} else {
					a = Object.RotateXFunction.LastResult;
				}
				ObjectManager.UpdateDamping(ref Object.RotateXDamping, TimeElapsed, ref a);
				cosX = Math.Cos(a);
				sinX = Math.Sin(a);
			} else {
				cosX = 0.0; sinX = 0.0;
			}
			double cosY, sinY;
			if (rotateY) {
				double a;
				if (UpdateFunctions) {
					a = Object.RotateYFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed);
				} else {
					a = Object.RotateYFunction.LastResult;
				}
				ObjectManager.UpdateDamping(ref Object.RotateYDamping, TimeElapsed, ref a);
				cosY = Math.Cos(a);
				sinY = Math.Sin(a);
			} else {
				cosY = 0.0; sinY = 0.0;
			}
			double cosZ, sinZ;
			if (rotateZ) {
				double a;
				if (UpdateFunctions) {
					a = Object.RotateZFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed);
				} else {
					a = Object.RotateZFunction.LastResult;
				}
				ObjectManager.UpdateDamping(ref Object.RotateZDamping, TimeElapsed, ref a);
				cosZ = Math.Cos(a);
				sinZ = Math.Sin(a);
			} else {
				cosZ = 0.0; sinZ = 0.0;
			}
			// texture shift
			bool shiftx = Object.TextureShiftXFunction != null;
			bool shifty = Object.TextureShiftYFunction != null;
			if ((shiftx | shifty) & UpdateFunctions) {
				for (int k = 0; k < ObjectManager.Objects[i].Mesh.Vertices.Length; k++) {
					ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates = Object.States[s].Object.Mesh.Vertices[k].TextureCoordinates;
				}
				if (shiftx) {
					double x = Object.TextureShiftXFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed);
					x -= Math.Floor(x);
					for (int k = 0; k < ObjectManager.Objects[i].Mesh.Vertices.Length; k++) {
						ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates.X += (float)(x * Object.TextureShiftXDirection.X);
						ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates.Y += (float)(x * Object.TextureShiftXDirection.Y);
					}
				}
				if (shifty) {
					double y = Object.TextureShiftYFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed);
					y -= Math.Floor(y);
					for (int k = 0; k < ObjectManager.Objects[i].Mesh.Vertices.Length; k++) {
						ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates.X += (float)(y * Object.TextureShiftYDirection.X);
						ObjectManager.Objects[i].Mesh.Vertices[k].TextureCoordinates.Y += (float)(y * Object.TextureShiftYDirection.Y);
					}
				}
			}
			// led
			bool led = Object.LEDFunction != null;
			double ledangle;
			if (led) {
				if (UpdateFunctions) {
					double lastangle = Object.LEDFunction.LastResult;
					ledangle = Object.LEDFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed);
				} else {
					ledangle = Object.LEDFunction.LastResult;
				}
			} else {
				ledangle = 0.0;
			}
			// null object
			if (Object.States[s].Object == null) {
				return;
			}
			// initialize vertices
			for (int k = 0; k < Object.States[s].Object.Mesh.Vertices.Length; k++) {
				ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates = Object.States[s].Object.Mesh.Vertices[k].Coordinates;
			}
			// led
			if (led) {
				/*
				 * Edges:         Vertices:
				 * 0 - bottom     0 - bottom-left
				 * 1 - left       1 - top-left
				 * 2 - top        2 - top-right
				 * 3 - right      3 - bottom-right
				 *                4 - center
				 * */
				int v = 1;
				if (Object.LEDClockwiseWinding) {
					/* winding is clockwise*/
					if (ledangle < Object.LEDInitialAngle) {
						ledangle = Object.LEDInitialAngle;
					}
					if (ledangle < Object.LEDLastAngle) {
						double currentEdgeFloat = Math.Floor(0.636619772367582 * (ledangle + 0.785398163397449));
						int currentEdge = ((int)currentEdgeFloat % 4 + 4) % 4;
						double lastEdgeFloat = Math.Floor(0.636619772367582 * (Object.LEDLastAngle + 0.785398163397449));
						int lastEdge = ((int)lastEdgeFloat % 4 + 4) % 4;
						if (lastEdge < currentEdge | lastEdge == currentEdge & Math.Abs(currentEdgeFloat - lastEdgeFloat) > 2.0) {
							lastEdge += 4;
						}
						if (currentEdge == lastEdge) {
							/* current angle to last angle */
							{
								double t = 0.5 + (0.636619772367582 * ledangle) - currentEdgeFloat;
								if (t < 0.0) {
									t = 0.0;
								} else if (t > 1.0) {
									t = 1.0;
								}
								t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
								double cx = (1.0 - t) * Object.LEDVectors[(currentEdge + 3) % 4].X + t * Object.LEDVectors[currentEdge].X;
								double cy = (1.0 - t) * Object.LEDVectors[(currentEdge + 3) % 4].Y + t * Object.LEDVectors[currentEdge].Y;
								double cz = (1.0 - t) * Object.LEDVectors[(currentEdge + 3) % 4].Z + t * Object.LEDVectors[currentEdge].Z;
								Object.States[s].Object.Mesh.Vertices[v].Coordinates = new World.Vector3D(cx, cy, cz);
								v++;
							}
							{
								double t = 0.5 + (0.636619772367582 * Object.LEDLastAngle) - lastEdgeFloat;
								if (t < 0.0) {
									t = 0.0;
								} else if (t > 1.0) {
									t = 1.0;
								}
								t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
								double lx = (1.0 - t) * Object.LEDVectors[(lastEdge + 3) % 4].X + t * Object.LEDVectors[lastEdge].X;
								double ly = (1.0 - t) * Object.LEDVectors[(lastEdge + 3) % 4].Y + t * Object.LEDVectors[lastEdge].Y;
								double lz = (1.0 - t) * Object.LEDVectors[(lastEdge + 3) % 4].Z + t * Object.LEDVectors[lastEdge].Z;
								Object.States[s].Object.Mesh.Vertices[v].Coordinates = new World.Vector3D(lx, ly, lz);
								v++;
							}
						} else {
							{
								/* current angle to square vertex */
								double t = 0.5 + (0.636619772367582 * ledangle) - currentEdgeFloat;
								if (t < 0.0) {
									t = 0.0;
								} else if (t > 1.0) {
									t = 1.0;
								}
								t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
								double cx = (1.0 - t) * Object.LEDVectors[(currentEdge + 3) % 4].X + t * Object.LEDVectors[currentEdge].X;
								double cy = (1.0 - t) * Object.LEDVectors[(currentEdge + 3) % 4].Y + t * Object.LEDVectors[currentEdge].Y;
								double cz = (1.0 - t) * Object.LEDVectors[(currentEdge + 3) % 4].Z + t * Object.LEDVectors[currentEdge].Z;
								Object.States[s].Object.Mesh.Vertices[v + 0].Coordinates = new World.Vector3D(cx, cy, cz);
								Object.States[s].Object.Mesh.Vertices[v + 1].Coordinates = Object.LEDVectors[currentEdge];
								v += 2;
							}
							for (int j = currentEdge + 1; j < lastEdge; j++) {
								/* square-vertex to square-vertex */
								Object.States[s].Object.Mesh.Vertices[v + 0].Coordinates = Object.LEDVectors[(j + 3) % 4];
								Object.States[s].Object.Mesh.Vertices[v + 1].Coordinates = Object.LEDVectors[j % 4];
								v += 2;
							}
							{
								/* square vertex to last angle */
								double t = 0.5 + (0.636619772367582 * Object.LEDLastAngle) - lastEdgeFloat;
								if (t < 0.0) {
									t = 0.0;
								} else if (t > 1.0) {
									t = 1.0;
								}
								t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
								double lx = (1.0 - t) * Object.LEDVectors[(lastEdge + 3) % 4].X + t * Object.LEDVectors[lastEdge % 4].X;
								double ly = (1.0 - t) * Object.LEDVectors[(lastEdge + 3) % 4].Y + t * Object.LEDVectors[lastEdge % 4].Y;
								double lz = (1.0 - t) * Object.LEDVectors[(lastEdge + 3) % 4].Z + t * Object.LEDVectors[lastEdge % 4].Z;
								Object.States[s].Object.Mesh.Vertices[v + 0].Coordinates = Object.LEDVectors[(lastEdge + 3) % 4];
								Object.States[s].Object.Mesh.Vertices[v + 1].Coordinates = new World.Vector3D(lx, ly, lz);
								v += 2;
							}
						}
					}
				} else {
					/* winding is counter-clockwise*/
					if (ledangle > Object.LEDInitialAngle) {
						ledangle = Object.LEDInitialAngle;
					}
					if (ledangle > Object.LEDLastAngle) {
						double currentEdgeFloat = Math.Floor(0.636619772367582 * (ledangle + 0.785398163397449));
						int currentEdge = ((int)currentEdgeFloat % 4 + 4) % 4;
						double lastEdgeFloat = Math.Floor(0.636619772367582 * (Object.LEDLastAngle + 0.785398163397449));
						int lastEdge = ((int)lastEdgeFloat % 4 + 4) % 4;
						if (currentEdge < lastEdge | lastEdge == currentEdge & Math.Abs(currentEdgeFloat - lastEdgeFloat) > 2.0) {
							currentEdge += 4;
						}
						if (currentEdge == lastEdge) {
							/* current angle to last angle */
							{
								double t = 0.5 + (0.636619772367582 * Object.LEDLastAngle) - lastEdgeFloat;
								if (t < 0.0) {
									t = 0.0;
								} else if (t > 1.0) {
									t = 1.0;
								}
								t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
								double lx = (1.0 - t) * Object.LEDVectors[(lastEdge + 3) % 4].X + t * Object.LEDVectors[lastEdge].X;
								double ly = (1.0 - t) * Object.LEDVectors[(lastEdge + 3) % 4].Y + t * Object.LEDVectors[lastEdge].Y;
								double lz = (1.0 - t) * Object.LEDVectors[(lastEdge + 3) % 4].Z + t * Object.LEDVectors[lastEdge].Z;
								Object.States[s].Object.Mesh.Vertices[v].Coordinates = new World.Vector3D(lx, ly, lz);
								v++;
							}
							{
								double t = 0.5 + (0.636619772367582 * ledangle) - currentEdgeFloat;
								if (t < 0.0) {
									t = 0.0;
								} else if (t > 1.0) {
									t = 1.0;
								}
								t = t - Math.Floor(t);
								t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
								double cx = (1.0 - t) * Object.LEDVectors[(currentEdge + 3) % 4].X + t * Object.LEDVectors[currentEdge].X;
								double cy = (1.0 - t) * Object.LEDVectors[(currentEdge + 3) % 4].Y + t * Object.LEDVectors[currentEdge].Y;
								double cz = (1.0 - t) * Object.LEDVectors[(currentEdge + 3) % 4].Z + t * Object.LEDVectors[currentEdge].Z;
								Object.States[s].Object.Mesh.Vertices[v].Coordinates = new World.Vector3D(cx, cy, cz);
								v++;
							}
						} else {
							{
								/* current angle to square vertex */
								double t = 0.5 + (0.636619772367582 * ledangle) - currentEdgeFloat;
								if (t < 0.0) {
									t = 0.0;
								} else if (t > 1.0) {
									t = 1.0;
								}
								t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
								double cx = (1.0 - t) * Object.LEDVectors[(currentEdge + 3) % 4].X + t * Object.LEDVectors[currentEdge % 4].X;
								double cy = (1.0 - t) * Object.LEDVectors[(currentEdge + 3) % 4].Y + t * Object.LEDVectors[currentEdge % 4].Y;
								double cz = (1.0 - t) * Object.LEDVectors[(currentEdge + 3) % 4].Z + t * Object.LEDVectors[currentEdge % 4].Z;
								Object.States[s].Object.Mesh.Vertices[v + 0].Coordinates = Object.LEDVectors[(currentEdge + 3) % 4];
								Object.States[s].Object.Mesh.Vertices[v + 1].Coordinates = new World.Vector3D(cx, cy, cz);
								v += 2;
							}
							for (int j = currentEdge - 1; j > lastEdge; j--) {
								/* square-vertex to square-vertex */
								Object.States[s].Object.Mesh.Vertices[v + 0].Coordinates = Object.LEDVectors[(j + 3) % 4];
								Object.States[s].Object.Mesh.Vertices[v + 1].Coordinates = Object.LEDVectors[j % 4];
								v += 2;
							}
							{
								/* square vertex to last angle */
								double t = 0.5 + (0.636619772367582 * Object.LEDLastAngle) - lastEdgeFloat;
								if (t < 0.0) {
									t = 0.0;
								} else if (t > 1.0) {
									t = 1.0;
								}
								t = 0.5 * (1.0 - Math.Tan(0.25 * (Math.PI - 2.0 * Math.PI * t)));
								double lx = (1.0 - t) * Object.LEDVectors[(lastEdge + 3) % 4].X + t * Object.LEDVectors[lastEdge].X;
								double ly = (1.0 - t) * Object.LEDVectors[(lastEdge + 3) % 4].Y + t * Object.LEDVectors[lastEdge].Y;
								double lz = (1.0 - t) * Object.LEDVectors[(lastEdge + 3) % 4].Z + t * Object.LEDVectors[lastEdge].Z;
								Object.States[s].Object.Mesh.Vertices[v + 0].Coordinates = new World.Vector3D(lx, ly, lz);
								Object.States[s].Object.Mesh.Vertices[v + 1].Coordinates = Object.LEDVectors[lastEdge % 4];
								v += 2;
							}
						}
					}
				}
				for (int j = v; v < 11; v++) {
					Object.States[s].Object.Mesh.Vertices[j].Coordinates = Object.LEDVectors[4];
				}
			}
			// update vertices
			for (int k = 0; k < Object.States[s].Object.Mesh.Vertices.Length; k++) {
				// rotate
				if (rotateX) {
					World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z, Object.RotateXDirection.X, Object.RotateXDirection.Y, Object.RotateXDirection.Z, cosX, sinX);
				}
				if (rotateY) {
					World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z, Object.RotateYDirection.X, Object.RotateYDirection.Y, Object.RotateYDirection.Z, cosY, sinY);
				}
				if (rotateZ) {
					World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z, Object.RotateZDirection.X, Object.RotateZDirection.Y, Object.RotateZDirection.Z, cosZ, sinZ);
				}
				// translate
				if (Overlay & World.CameraRestriction != World.CameraRestrictionMode.NotAvailable) {
					ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X += Object.States[s].Position.X - Position.X;
					ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y += Object.States[s].Position.Y - Position.Y;
					ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z += Object.States[s].Position.Z - Position.Z;
					World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z, World.AbsoluteCameraDirection.X, World.AbsoluteCameraDirection.Y, World.AbsoluteCameraDirection.Z, World.AbsoluteCameraUp.X, World.AbsoluteCameraUp.Y, World.AbsoluteCameraUp.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z);
					double dx = -Math.Tan(World.CameraCurrentAlignment.Yaw) - World.CameraCurrentAlignment.Position.X;
					double dy = -Math.Tan(World.CameraCurrentAlignment.Pitch) - World.CameraCurrentAlignment.Position.Y;
					double dz = -World.CameraCurrentAlignment.Position.Z;
					ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X += World.AbsoluteCameraPosition.X + dx * World.AbsoluteCameraSide.X + dy * World.AbsoluteCameraUp.X + dz * World.AbsoluteCameraDirection.X;
					ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y += World.AbsoluteCameraPosition.Y + dx * World.AbsoluteCameraSide.Y + dy * World.AbsoluteCameraUp.Y + dz * World.AbsoluteCameraDirection.Y;
					ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z += World.AbsoluteCameraPosition.Z + dx * World.AbsoluteCameraSide.Z + dy * World.AbsoluteCameraUp.Z + dz * World.AbsoluteCameraDirection.Z;
				} else {
					ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X += Object.States[s].Position.X;
					ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y += Object.States[s].Position.Y;
					ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z += Object.States[s].Position.Z;
					World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z);
					ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X += Position.X;
					ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y += Position.Y;
					ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z += Position.Z;
				}
			}
			// update normals
			for (int k = 0; k < Object.States[s].Object.Mesh.Faces.Length; k++) {
				for (int h = 0; h < Object.States[s].Object.Mesh.Faces[k].Vertices.Length; h++) {
					ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal = Object.States[s].Object.Mesh.Faces[k].Vertices[h].Normal;
				}
				for (int h = 0; h < Object.States[s].Object.Mesh.Faces[k].Vertices.Length; h++) {
					if (!Object.States[s].Object.Mesh.Faces[k].Vertices[h].Normal.IsZero()) {
						if (rotateX) {
							World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.X, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Y, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Z, Object.RotateXDirection.X, Object.RotateXDirection.Y, Object.RotateXDirection.Z, cosX, sinX);
						}
						if (rotateY) {
							World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.X, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Y, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Z, Object.RotateYDirection.X, Object.RotateYDirection.Y, Object.RotateYDirection.Z, cosY, sinY);
						}
						if (rotateZ) {
							World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.X, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Y, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Z, Object.RotateZDirection.X, Object.RotateZDirection.Y, Object.RotateZDirection.Z, cosZ, sinZ);
						}
						World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.X, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Y, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Z, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z);
					}
				}
				// visibility changed
				if (Show) {
					if (Overlay) {
						Renderer.ShowObject(i, Renderer.ObjectType.Overlay);
					} else {
						Renderer.ShowObject(i, Renderer.ObjectType.Dynamic);
					}
				} else {
					Renderer.HideObject(i);
				}
			}
		}
コード例 #19
0
ファイル: Renderer.cs プロジェクト: openbve/OpenBVE
 // get distance factor
 private static double GetDistanceFactor(World.Vertex[] Vertices, ref World.MeshFace Face, ushort GlowAttenuationData, double CameraX, double CameraY, double CameraZ)
 {
     if (Face.Vertices.Length != 0) {
         World.GlowAttenuationMode mode; double halfdistance;
         World.SplitGlowAttenuationData(GlowAttenuationData, out mode, out halfdistance);
         int i = (int)Face.Vertices[0].Index;
         double dx = Vertices[i].Coordinates.X - CameraX;
         double dy = Vertices[i].Coordinates.Y - CameraY;
         double dz = Vertices[i].Coordinates.Z - CameraZ;
         switch (mode) {
             case World.GlowAttenuationMode.DivisionExponent2:
                 {
                     double t = dx * dx + dy * dy + dz * dz;
                     return t / (t + halfdistance * halfdistance);
                 }
             case World.GlowAttenuationMode.DivisionExponent4:
                 {
                     double t = dx * dx + dy * dy + dz * dz;
                     t *= t; halfdistance *= halfdistance;
                     return t / (t + halfdistance * halfdistance);
                 }
             default:
                 return 1.0;
         }
     } else {
         return 1.0;
     }
 }
コード例 #20
0
ファイル: TextureManager.cs プロジェクト: leezer3/OpenBVE
		internal static int RegisterTexture(string FileName, World.ColorRGB TransparentColor, byte TransparentColorUsed, TextureLoadMode LoadMode, TextureWrapMode WrapModeX, TextureWrapMode WrapModeY, bool DontAllowUnload, int ClipLeft, int ClipTop, int ClipWidth, int ClipHeight)
		{
			if (FileName == null)
			{
				//Need to find out why the object parser sometimes decides to pass a null filename, but this works around it
				return -1;
			}
			
			int i = FindTexture(FileName, TransparentColor, TransparentColorUsed, LoadMode, WrapModeX, WrapModeY, ClipLeft, ClipTop, ClipWidth, ClipHeight);
			if (i >= 0)
			{
				return i;
			}
			else
			{
				i = GetFreeTexture();
				Textures[i] = new Texture
				{
					Queried = false,
					Loaded = false,
					FileName = FileName,
					TransparentColor = TransparentColor,
					TransparentColorUsed = TransparentColorUsed,
					LoadMode = LoadMode,
					WrapModeX = WrapModeX,
					WrapModeY = WrapModeY,
					ClipLeft = ClipLeft,
					ClipTop = ClipTop,
					ClipWidth = ClipWidth,
					ClipHeight = ClipHeight,
					DontAllowUnload = DontAllowUnload,
					LoadImmediately = false,
					OpenGlTextureIndex = 0
				};
				bool alpha = false;
				switch (System.IO.Path.GetExtension(Textures[i].FileName).ToLowerInvariant())
				{
					case ".gif":
					case ".png":
						alpha = true;
						Textures[i].LoadImmediately = true;
						break;
				}
				if (alpha)
				{
					Textures[i].Transparency = TextureTransparencyMode.Alpha;
				}
				else if (TransparentColorUsed != 0)
				{
					Textures[i].Transparency = TextureTransparencyMode.TransparentColor;
				}
				else
				{
					Textures[i].Transparency = TextureTransparencyMode.None;
				}
				Textures[i].IsRGBA = Textures[i].Transparency != TextureTransparencyMode.None | LoadMode != TextureLoadMode.Normal;
				return i;
			}
		}
コード例 #21
0
ファイル: SoundManager.cs プロジェクト: noidelsucre/OpenBVE
		internal static void PlaySound(ref int SoundSourceIndex, int SoundBufferIndex, World.Vector3D Position, Importance Important, bool Looped) {
			PlaySound(ref SoundSourceIndex, true, SoundBufferIndex, null, -1, Position, Important, Looped, 1.0, 1.0);
		}
コード例 #22
0
ファイル: TextureManager.cs プロジェクト: leezer3/OpenBVE
		// find texture
		private static int FindTexture(string FileName, World.ColorRGB TransparentColor, byte TransparentColorUsed, TextureLoadMode LoadMode, TextureWrapMode WrapModeX, TextureWrapMode WrapModeY, int ClipLeft, int ClipTop, int ClipWidth, int ClipHeight)
		{
			for (int i = 1; i < Textures.Length; i++)
			{
				if (Textures[i] != null && Textures[i].FileName != null)
				{
					if (string.Compare(Textures[i].FileName, FileName, StringComparison.OrdinalIgnoreCase) == 0)
					{
						if (Textures[i].LoadMode == LoadMode & Textures[i].WrapModeX == WrapModeX & Textures[i].WrapModeY == WrapModeY)
						{
							if (Textures[i].ClipLeft == ClipLeft & Textures[i].ClipTop == ClipTop & Textures[i].ClipWidth == ClipWidth & Textures[i].ClipHeight == ClipHeight)
							{
								if (TransparentColorUsed == 0)
								{
									if (Textures[i].TransparentColorUsed == 0)
									{
										return i;
									}
								}
								else
								{
									if (Textures[i].TransparentColorUsed != 0)
									{
										if (Textures[i].TransparentColor.R == TransparentColor.R & Textures[i].TransparentColor.G == TransparentColor.G & Textures[i].TransparentColor.B == TransparentColor.B)
										{
											return i;
										}
									}
								}
							}
						}
					}
				}
			}
			return -1;
		}
コード例 #23
0
ファイル: SoundManager.cs プロジェクト: noidelsucre/OpenBVE
		internal static void PlaySound(int SoundBufferIndex, World.Vector3D Position, Importance Important, bool Looped) {
			int a = -1;
			PlaySound(ref a, false, SoundBufferIndex, null, -1, Position, Important, Looped, 1.0, 1.0);
		}
コード例 #24
0
ファイル: ObjectManager.cs プロジェクト: sladen/openbve
 internal static int CreateAnimatedWorldObject(AnimatedObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, double TrackPosition, double Brightness)
 {
     int a = AnimatedWorldObjectsUsed;
     if (a >= AnimatedWorldObjects.Length) {
         Array.Resize<AnimatedWorldObject>(ref AnimatedWorldObjects, AnimatedWorldObjects.Length << 1);
     }
     World.Transformation FinalTransformation = new World.Transformation(BaseTransformation, AuxTransformation);
     AnimatedWorldObjects[a] = new AnimatedWorldObject();
     AnimatedWorldObjects[a].Position = Position;
     AnimatedWorldObjects[a].Direction = FinalTransformation.Z;
     AnimatedWorldObjects[a].Up = FinalTransformation.Y;
     AnimatedWorldObjects[a].Side = FinalTransformation.X;
     AnimatedWorldObjects[a].Object = Prototype.Clone();
     AnimatedWorldObjects[a].Object.ObjectIndex = CreateDynamicObject();
     AnimatedWorldObjects[a].SectionIndex = SectionIndex;
     AnimatedWorldObjects[a].TrackPosition = TrackPosition;
     for (int i = 0; i < AnimatedWorldObjects[a].Object.States.Length; i++) {
         if (AnimatedWorldObjects[a].Object.States[i].Object == null) {
             AnimatedWorldObjects[a].Object.States[i].Object = new StaticObject();
             AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Faces = new World.MeshFace[] { };
             AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials = new World.MeshMaterial[] { };
             AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Vertices = new World.Vertex[] { };
             AnimatedWorldObjects[a].Object.States[i].Object.RendererIndex = -1;
         }
     }
     double r = 0.0;
     for (int i = 0; i < AnimatedWorldObjects[a].Object.States.Length; i++) {
         for (int j = 0; j < AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials.Length; j++) {
             AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials[j].Color.R = (byte)Math.Round((double)Prototype.States[i].Object.Mesh.Materials[j].Color.R * Brightness);
             AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials[j].Color.G = (byte)Math.Round((double)Prototype.States[i].Object.Mesh.Materials[j].Color.G * Brightness);
             AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Materials[j].Color.B = (byte)Math.Round((double)Prototype.States[i].Object.Mesh.Materials[j].Color.B * Brightness);
         }
         for (int j = 0; j < AnimatedWorldObjects[a].Object.States[i].Object.Mesh.Vertices.Length; j++) {
             double x = Prototype.States[i].Object.Mesh.Vertices[j].Coordinates.X;
             double y = Prototype.States[i].Object.Mesh.Vertices[j].Coordinates.Y;
             double z = Prototype.States[i].Object.Mesh.Vertices[j].Coordinates.Z;
             double t = x * x + y * y + z * z;
             if (t > r) r = t;
         }
     }
     AnimatedWorldObjects[a].Radius = Math.Sqrt(r);
     AnimatedWorldObjects[a].Visible = false;
     InitializeAnimatedObject(ref AnimatedWorldObjects[a].Object, 0, false, false);
     AnimatedWorldObjectsUsed++;
     return a;
 }
コード例 #25
0
ファイル: SoundManager.cs プロジェクト: noidelsucre/OpenBVE
		internal static void PlaySound(int SoundBufferIndex, TrainManager.Train Train, int CarIndex, World.Vector3D Position, Importance Important, bool Looped) {
			int a = -1;
			PlaySound(ref a, false, SoundBufferIndex, Train, CarIndex, Position, Important, Looped, 1.0, 1.0);
		}
コード例 #26
0
ファイル: ObjectManager.cs プロジェクト: sladen/openbve
 // create object
 internal static void CreateObject(UnifiedObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition)
 {
     CreateObject(Prototype, Position, BaseTransformation, AuxTransformation, -1, AccurateObjectDisposal, StartingDistance, EndingDistance, BlockLength, TrackPosition, 1.0, false);
 }
コード例 #27
0
ファイル: SoundManager.cs プロジェクト: noidelsucre/OpenBVE
		internal static void PlaySound(ref int SoundSourceIndex, int SoundBufferIndex, TrainManager.Train Train, int CarIndex, World.Vector3D Position, Importance Important, bool Looped, double Pitch, double Gain) {
			PlaySound(ref SoundSourceIndex, true, SoundBufferIndex, Train, CarIndex, Position, Important, Looped, Pitch, Gain);
		}
コード例 #28
0
ファイル: ObjectManager.cs プロジェクト: sladen/openbve
 // create static object
 internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition)
 {
     return CreateStaticObject(Prototype, Position, BaseTransformation, AuxTransformation, AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, BlockLength, TrackPosition, 1.0, false);
 }
コード例 #29
0
ファイル: SoundManager.cs プロジェクト: noidelsucre/OpenBVE
		private static void PlaySound(ref int SoundSourceIndex, bool ReturnHandle, int SoundBufferIndex, TrainManager.Train Train, int CarIndex, World.Vector3D Position, Importance Important, bool Looped, double Pitch, double Gain) {
			if (OpenAlContext != IntPtr.Zero) {
				if (Game.MinimalisticSimulation & Important == Importance.DontCare | SoundBufferIndex == -1) {
					return;
				}
				if (SoundSourceIndex >= 0) {
					StopSound(ref SoundSourceIndex);
				}
				int i;
				for (i = 0; i < SoundSources.Length; i++) {
					if (SoundSources[i] == null) break;
				}
				if (i >= SoundSources.Length) {
					Array.Resize<SoundSource>(ref SoundSources, SoundSources.Length << 1);
				}
				SoundSources[i] = new SoundSource();
				SoundSources[i].Position = Position;
				SoundSources[i].OpenAlPosition = new float[] { 0.0f, 0.0f, 0.0f };
				SoundSources[i].OpenAlVelocity = new float[] { 0.0f, 0.0f, 0.0f };
				SoundSources[i].SoundBufferIndex = SoundBufferIndex;
				SoundSources[i].Radius = SoundBuffers[SoundBufferIndex].Radius;
				SoundSources[i].Pitch = (float)Pitch;
				SoundSources[i].Gain = (float)Gain;
				SoundSources[i].Looped = Looped;
				SoundSources[i].Suppressed = true;
				SoundSources[i].FinishedPlaying = false;
				SoundSources[i].Train = Train;
				SoundSources[i].CarIndex = CarIndex;
				SoundSources[i].OpenAlSourceIndex = new OpenAlIndex(0, false);
				SoundSources[i].HasHandle = ReturnHandle;
				SoundSourceIndex = i;
			}
		}
コード例 #30
0
ファイル: ObjectManager.cs プロジェクト: sladen/openbve
 internal static void ApplyStaticObjectData(ref StaticObject Object, StaticObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials)
 {
     Object = new StaticObject();
     Object.StartingDistance = float.MaxValue;
     Object.EndingDistance = float.MinValue;
     bool brightnesschange = Brightness != 1.0;
     // vertices
     Object.Mesh.Vertices = new World.Vertex[Prototype.Mesh.Vertices.Length];
     for (int j = 0; j < Prototype.Mesh.Vertices.Length; j++) {
         Object.Mesh.Vertices[j] = Prototype.Mesh.Vertices[j];
         if (AccurateObjectDisposal) {
             World.Rotate(ref Object.Mesh.Vertices[j].Coordinates.X, ref Object.Mesh.Vertices[j].Coordinates.Y, ref Object.Mesh.Vertices[j].Coordinates.Z, AuxTransformation);
             if (Object.Mesh.Vertices[j].Coordinates.Z < Object.StartingDistance) {
                 Object.StartingDistance = (float)Object.Mesh.Vertices[j].Coordinates.Z;
             }
             if (Object.Mesh.Vertices[j].Coordinates.Z > Object.EndingDistance) {
                 Object.EndingDistance = (float)Object.Mesh.Vertices[j].Coordinates.Z;
             }
             Object.Mesh.Vertices[j].Coordinates = Prototype.Mesh.Vertices[j].Coordinates;
         }
         World.Rotate(ref Object.Mesh.Vertices[j].Coordinates.X, ref Object.Mesh.Vertices[j].Coordinates.Y, ref Object.Mesh.Vertices[j].Coordinates.Z, AuxTransformation);
         World.Rotate(ref Object.Mesh.Vertices[j].Coordinates.X, ref Object.Mesh.Vertices[j].Coordinates.Y, ref Object.Mesh.Vertices[j].Coordinates.Z, BaseTransformation);
         Object.Mesh.Vertices[j].Coordinates.X += Position.X;
         Object.Mesh.Vertices[j].Coordinates.Y += Position.Y;
         Object.Mesh.Vertices[j].Coordinates.Z += Position.Z;
     }
     if (AccurateObjectDisposal) {
         Object.StartingDistance += (float)AccurateObjectDisposalZOffset;
         Object.EndingDistance += (float)AccurateObjectDisposalZOffset;
     }
     // faces
     Object.Mesh.Faces = new World.MeshFace[Prototype.Mesh.Faces.Length];
     for (int j = 0; j < Prototype.Mesh.Faces.Length; j++) {
         Object.Mesh.Faces[j].Flags = Prototype.Mesh.Faces[j].Flags;
         Object.Mesh.Faces[j].Material = Prototype.Mesh.Faces[j].Material;
         Object.Mesh.Faces[j].Vertices = new World.MeshFaceVertex[Prototype.Mesh.Faces[j].Vertices.Length];
         for (int k = 0; k < Prototype.Mesh.Faces[j].Vertices.Length; k++) {
             Object.Mesh.Faces[j].Vertices[k] = Prototype.Mesh.Faces[j].Vertices[k];
             double nx = Object.Mesh.Faces[j].Vertices[k].Normal.X;
             double ny = Object.Mesh.Faces[j].Vertices[k].Normal.Y;
             double nz = Object.Mesh.Faces[j].Vertices[k].Normal.Z;
             if (nx * nx + ny * ny + nz * nz != 0.0) {
                 World.Rotate(ref Object.Mesh.Faces[j].Vertices[k].Normal.X, ref Object.Mesh.Faces[j].Vertices[k].Normal.Y, ref Object.Mesh.Faces[j].Vertices[k].Normal.Z, AuxTransformation);
                 World.Rotate(ref Object.Mesh.Faces[j].Vertices[k].Normal.X, ref Object.Mesh.Faces[j].Vertices[k].Normal.Y, ref Object.Mesh.Faces[j].Vertices[k].Normal.Z, BaseTransformation);
             }
         }
     }
     // materials
     Object.Mesh.Materials = new World.MeshMaterial[Prototype.Mesh.Materials.Length];
     for (int j = 0; j < Prototype.Mesh.Materials.Length; j++) {
         Object.Mesh.Materials[j] = Prototype.Mesh.Materials[j];
         Object.Mesh.Materials[j].Color.R = (byte)Math.Round((double)Prototype.Mesh.Materials[j].Color.R * Brightness);
         Object.Mesh.Materials[j].Color.G = (byte)Math.Round((double)Prototype.Mesh.Materials[j].Color.G * Brightness);
         Object.Mesh.Materials[j].Color.B = (byte)Math.Round((double)Prototype.Mesh.Materials[j].Color.B * Brightness);
     }
     const double minBlockLength = 20.0;
     if (BlockLength < minBlockLength) {
         BlockLength = BlockLength * Math.Ceiling(minBlockLength / BlockLength);
     }
     if (AccurateObjectDisposal) {
         Object.StartingDistance += (float)TrackPosition;
         Object.EndingDistance += (float)TrackPosition;
         double z = BlockLength * Math.Floor(TrackPosition / BlockLength);
         StartingDistance = Math.Min(z - BlockLength, (double)Object.StartingDistance);
         EndingDistance = Math.Max(z + 2.0 * BlockLength, (double)Object.EndingDistance);
         Object.StartingDistance = (float)(BlockLength * Math.Floor(StartingDistance / BlockLength));
         Object.EndingDistance = (float)(BlockLength * Math.Ceiling(EndingDistance / BlockLength));
     } else {
         Object.StartingDistance = (float)StartingDistance;
         Object.EndingDistance = (float)EndingDistance;
     }
     if (BlockLength != 0.0) {
         checked {
             Object.GroupIndex = (short)Mod(Math.Floor(Object.StartingDistance / BlockLength), Math.Ceiling(Interface.CurrentOptions.ViewingDistance / BlockLength));
         }
     }
 }
コード例 #31
0
 internal static void ApplyStaticObjectData(ref StaticObject Object, StaticObject Prototype, World.Vector3D Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double TrackPosition, double Brightness, bool DuplicateMaterials)
 {
     Object = new StaticObject();
     Object.StartingDistance = float.MaxValue;
     Object.EndingDistance = float.MinValue;
     bool brightnesschange = Brightness != 1.0;
     // vertices
     Object.Mesh.Vertices = new World.Vertex[Prototype.Mesh.Vertices.Length];
     for (int j = 0; j < Prototype.Mesh.Vertices.Length; j++) {
         Object.Mesh.Vertices[j] = Prototype.Mesh.Vertices[j];
         if (AccurateObjectDisposal) {
             World.Rotate(ref Object.Mesh.Vertices[j].Coordinates.X, ref Object.Mesh.Vertices[j].Coordinates.Y, ref Object.Mesh.Vertices[j].Coordinates.Z, AuxTransformation);
             if (Object.Mesh.Vertices[j].Coordinates.Z < Object.StartingDistance) {
                 Object.StartingDistance = (float)Object.Mesh.Vertices[j].Coordinates.Z;
             }
             if (Object.Mesh.Vertices[j].Coordinates.Z > Object.EndingDistance) {
                 Object.EndingDistance = (float)Object.Mesh.Vertices[j].Coordinates.Z;
             }
             Object.Mesh.Vertices[j].Coordinates = Prototype.Mesh.Vertices[j].Coordinates;
         }
         World.Rotate(ref Object.Mesh.Vertices[j].Coordinates.X, ref Object.Mesh.Vertices[j].Coordinates.Y, ref Object.Mesh.Vertices[j].Coordinates.Z, AuxTransformation);
         World.Rotate(ref Object.Mesh.Vertices[j].Coordinates.X, ref Object.Mesh.Vertices[j].Coordinates.Y, ref Object.Mesh.Vertices[j].Coordinates.Z, BaseTransformation);
         Object.Mesh.Vertices[j].Coordinates.X += Position.X;
         Object.Mesh.Vertices[j].Coordinates.Y += Position.Y;
         Object.Mesh.Vertices[j].Coordinates.Z += Position.Z;
     }
     if (AccurateObjectDisposal) {
         Object.StartingDistance += (float)AccurateObjectDisposalZOffset;
         Object.EndingDistance += (float)AccurateObjectDisposalZOffset;
     }
     // faces
     Object.Mesh.Faces = new World.MeshFace[Prototype.Mesh.Faces.Length];
     for (int j = 0; j < Prototype.Mesh.Faces.Length; j++) {
         Object.Mesh.Faces[j].Flags = Prototype.Mesh.Faces[j].Flags;
         Object.Mesh.Faces[j].Material = Prototype.Mesh.Faces[j].Material;
         Object.Mesh.Faces[j].Vertices = new World.MeshFaceVertex[Prototype.Mesh.Faces[j].Vertices.Length];
         for (int k = 0; k < Prototype.Mesh.Faces[j].Vertices.Length; k++) {
             Object.Mesh.Faces[j].Vertices[k] = Prototype.Mesh.Faces[j].Vertices[k];
             double nx = Object.Mesh.Faces[j].Vertices[k].Normal.X;
             double ny = Object.Mesh.Faces[j].Vertices[k].Normal.Y;
             double nz = Object.Mesh.Faces[j].Vertices[k].Normal.Z;
             if (nx * nx + ny * ny + nz * nz != 0.0) {
                 World.Rotate(ref Object.Mesh.Faces[j].Vertices[k].Normal.X, ref Object.Mesh.Faces[j].Vertices[k].Normal.Y, ref Object.Mesh.Faces[j].Vertices[k].Normal.Z, AuxTransformation);
                 World.Rotate(ref Object.Mesh.Faces[j].Vertices[k].Normal.X, ref Object.Mesh.Faces[j].Vertices[k].Normal.Y, ref Object.Mesh.Faces[j].Vertices[k].Normal.Z, BaseTransformation);
             }
         }
     }
     // materials
     Object.Mesh.Materials = new World.MeshMaterial[Prototype.Mesh.Materials.Length];
     for (int j = 0; j < Prototype.Mesh.Materials.Length; j++) {
         Object.Mesh.Materials[j] = Prototype.Mesh.Materials[j];
         Object.Mesh.Materials[j].Color.R = (byte)Math.Round((double)Prototype.Mesh.Materials[j].Color.R * Brightness);
         Object.Mesh.Materials[j].Color.G = (byte)Math.Round((double)Prototype.Mesh.Materials[j].Color.G * Brightness);
         Object.Mesh.Materials[j].Color.B = (byte)Math.Round((double)Prototype.Mesh.Materials[j].Color.B * Brightness);
     }
     if (AccurateObjectDisposal) {
         Object.StartingDistance += (float)TrackPosition;
         Object.EndingDistance += (float)TrackPosition;
     } else {
         Object.StartingDistance = (float)StartingDistance;
         Object.EndingDistance = (float)EndingDistance;
     }
 }
コード例 #32
0
		// execute function script
		private static void ExecuteFunctionScript(FunctionScript Function, TrainManager.Train Train, int CarIndex, World.Vector3D Position, double TrackPosition, int SectionIndex, bool IsPartOfTrain, double TimeElapsed) {
			int s = 0, c = 0;
			for (int i = 0; i < Function.Instructions.Length; i++) {
				switch (Function.Instructions[i]) {
						// system
					case Instructions.SystemHalt:
						i = Function.Instructions.Length;
						break;
					case Instructions.SystemConstant:
						Function.Stack[s] = Function.Constants[c];
						s++; c++; break;
					case Instructions.SystemConstantArray:
						{
							int n = (int)Function.Instructions[i + 1];
							for (int j = 0; j < n; j++) {
								Function.Stack[s + j] = Function.Constants[c + j];
							} s += n; c += n; i++;
						} break;
					case Instructions.SystemValue:
						Function.Stack[s] = Function.LastResult;
						s++; break;
					case Instructions.SystemDelta:
						Function.Stack[s] = TimeElapsed;
						s++; break;
						// stack
					case Instructions.StackCopy:
						Function.Stack[s] = Function.Stack[s - 1];
						s++; break;
					case Instructions.StackSwap:
						{
							double a = Function.Stack[s - 1];
							Function.Stack[s - 1] = Function.Stack[s - 2];
							Function.Stack[s - 2] = a;
						} break;
						// math
					case Instructions.MathPlus:
						Function.Stack[s - 2] += Function.Stack[s - 1];
						s--; break;
					case Instructions.MathSubtract:
						Function.Stack[s - 2] -= Function.Stack[s - 1];
						s--; break;
					case Instructions.MathMinus:
						Function.Stack[s - 1] = -Function.Stack[s - 1];
						break;
					case Instructions.MathTimes:
						Function.Stack[s - 2] *= Function.Stack[s - 1];
						s--; break;
					case Instructions.MathDivide:
						Function.Stack[s - 2] = Function.Stack[s - 1] == 0.0 ? 0.0 : Function.Stack[s - 2] / Function.Stack[s - 1];
						s--; break;
					case Instructions.MathReciprocal:
						Function.Stack[s - 1] = Function.Stack[s - 1] == 0.0 ? 0.0 : 1.0 / Function.Stack[s - 1];
						break;
					case Instructions.MathPower:
						{
							double a = Function.Stack[s - 2];
							double b = Function.Stack[s - 1];
							if (b == 2.0) {
								Function.Stack[s - 2] = a * a;
							} else if (b == 3.0) {
								Function.Stack[s - 2] = a * a * a;
							} else if (b == 4.0) {
								double t = a * a;
								Function.Stack[s - 2] = t * t;
							} else if (b == 5.0) {
								double t = a * a;
								Function.Stack[s - 2] = t * t * a;
							} else if (b == 6.0) {
								double t = a * a * a;
								Function.Stack[s - 2] = t * t;
							} else if (b == 7.0) {
								double t = a * a * a;
								Function.Stack[s - 2] = t * t * a;
							} else if (b == 8.0) {
								double t = a * a; t *= t;
								Function.Stack[s - 2] = t * t;
							} else if (b == 0.0) {
								Function.Stack[s - 2] = 1.0;
							} else if (b < 0.0) {
								Function.Stack[s - 2] = 0.0;
							} else {
								Function.Stack[s - 2] = Math.Pow(a, b);
							}
							s--; break;
						}
					case Instructions.MathIncrement:
						Function.Stack[s - 1] += 1.0;
						break;
					case Instructions.MathDecrement:
						Function.Stack[s - 1] -= 1.0;
						break;
					case Instructions.MathFusedMultiplyAdd:
						Function.Stack[s - 3] = Function.Stack[s - 3] * Function.Stack[s - 2] + Function.Stack[s - 1];
						s -= 2; break;
					case Instructions.MathQuotient:
						Function.Stack[s - 2] = Function.Stack[s - 1] == 0.0 ? 0.0 : Math.Floor(Function.Stack[s - 2] / Function.Stack[s - 1]);
						s--; break;
					case Instructions.MathMod:
						Function.Stack[s - 2] = Function.Stack[s - 1] == 0.0 ? 0.0 : Function.Stack[s - 2] - Function.Stack[s - 1] * Math.Floor(Function.Stack[s - 2] / Function.Stack[s - 1]);
						s--; break;
					case Instructions.MathFloor:
						Function.Stack[s - 1] = Math.Floor(Function.Stack[s - 1]);
						break;
					case Instructions.MathCeiling:
						Function.Stack[s - 1] = Math.Ceiling(Function.Stack[s - 1]);
						break;
					case Instructions.MathRound:
						Function.Stack[s - 1] = Math.Round(Function.Stack[s - 1]);
						break;
					case Instructions.MathMin:
						Function.Stack[s - 2] = Function.Stack[s - 2] < Function.Stack[s - 1] ? Function.Stack[s - 2] : Function.Stack[s - 1];
						s--; break;
					case Instructions.MathMax:
						Function.Stack[s - 2] = Function.Stack[s - 2] > Function.Stack[s - 1] ? Function.Stack[s - 2] : Function.Stack[s - 1];
						s--; break;
					case Instructions.MathAbs:
						Function.Stack[s - 1] = Math.Abs(Function.Stack[s - 1]);
						break;
					case Instructions.MathSign:
						Function.Stack[s - 1] = Math.Sign(Function.Stack[s - 1]);
						break;
					case Instructions.MathExp:
						Function.Stack[s - 1] = Math.Exp(Function.Stack[s - 1]);
						break;
					case Instructions.MathLog:
						Function.Stack[s - 1] = Log(Function.Stack[s - 1]);
						break;
					case Instructions.MathSqrt:
						Function.Stack[s - 1] = Sqrt(Function.Stack[s - 1]);
						break;
					case Instructions.MathSin:
						Function.Stack[s - 1] = Math.Sin(Function.Stack[s - 1]);
						break;
					case Instructions.MathCos:
						Function.Stack[s - 1] = Math.Cos(Function.Stack[s - 1]);
						break;
					case Instructions.MathTan:
						Function.Stack[s - 1] = Tan(Function.Stack[s - 1]);
						break;
					case Instructions.MathArcTan:
						Function.Stack[s - 1] = Math.Atan(Function.Stack[s - 1]);
						break;
						// comparisons
					case Instructions.CompareEqual:
						Function.Stack[s - 2] = Function.Stack[s - 2] == Function.Stack[s - 1] ? 1.0 : 0.0;
						s--; break;
					case Instructions.CompareUnequal:
						Function.Stack[s - 2] = Function.Stack[s - 2] != Function.Stack[s - 1] ? 1.0 : 0.0;
						s--; break;
					case Instructions.CompareLess:
						Function.Stack[s - 2] = Function.Stack[s - 2] < Function.Stack[s - 1] ? 1.0 : 0.0;
						s--; break;
					case Instructions.CompareGreater:
						Function.Stack[s - 2] = Function.Stack[s - 2] > Function.Stack[s - 1] ? 1.0 : 0.0;
						s--; break;
					case Instructions.CompareLessEqual:
						Function.Stack[s - 2] = Function.Stack[s - 2] <= Function.Stack[s - 1] ? 1.0 : 0.0;
						s--; break;
					case Instructions.CompareGreaterEqual:
						Function.Stack[s - 2] = Function.Stack[s - 2] >= Function.Stack[s - 1] ? 1.0 : 0.0;
						s--; break;
					case Instructions.CompareConditional:
						Function.Stack[s - 3] = Function.Stack[s - 3] != 0.0 ? Function.Stack[s - 2] : Function.Stack[s - 1];
						s -= 2; break;
						// logical
					case Instructions.LogicalNot:
						Function.Stack[s - 1] = Function.Stack[s - 1] != 0.0 ? 0.0 : 1.0;
						break;
					case Instructions.LogicalAnd:
						Function.Stack[s - 2] = Function.Stack[s - 2] != 0.0 & Function.Stack[s - 1] != 0.0 ? 1.0 : 0.0;
						s--; break;
					case Instructions.LogicalOr:
						Function.Stack[s - 2] = Function.Stack[s - 2] != 0.0 | Function.Stack[s - 1] != 0.0 ? 1.0 : 0.0;
						s--; break;
					case Instructions.LogicalNand:
						Function.Stack[s - 2] = Function.Stack[s - 2] != 0.0 & Function.Stack[s - 1] != 0.0 ? 0.0 : 1.0;
						s--; break;
					case Instructions.LogicalNor:
						Function.Stack[s - 2] = Function.Stack[s - 2] != 0.0 | Function.Stack[s - 1] != 0.0 ? 0.0 : 1.0;
						s--; break;
					case Instructions.LogicalXor:
						Function.Stack[s - 2] = Function.Stack[s - 2] != 0.0 ^ Function.Stack[s - 1] != 0.0 ? 1.0 : 0.0;
						s--; break;
						// time/camera
					case Instructions.TimeSecondsSinceMidnight:
						Function.Stack[s] = Game.SecondsSinceMidnight;
						s++; break;
					case Instructions.CameraDistance:
						{
							double dx = World.AbsoluteCameraPosition.X - Position.X;
							double dy = World.AbsoluteCameraPosition.Y - Position.Y;
							double dz = World.AbsoluteCameraPosition.Z - Position.Z;
							Function.Stack[s] = Math.Sqrt(dx * dx + dy * dy + dz * dz);
							s++;
						} break;
						// train
					case Instructions.TrainCars:
						if (Train != null) {
							Function.Stack[s] = (double)Train.Cars.Length;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.TrainSpeed:
						if (Train != null) {
							Function.Stack[s] = Train.Cars[CarIndex].Specs.CurrentSpeed;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.TrainSpeedOfCar:
						if (Train != null) {
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								Function.Stack[s - 1] = Train.Cars[j].Specs.CurrentSpeed;
							} else {
								Function.Stack[s - 1] = 0.0;
							}
						} else {
							Function.Stack[s - 1] = 0.0;
						}
						break;
					case Instructions.TrainSpeedometer:
						if (Train != null) {
							Function.Stack[s] = Train.Cars[CarIndex].Specs.CurrentPerceivedSpeed;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.TrainSpeedometerOfCar:
						if (Train != null) {
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								Function.Stack[s - 1] = Train.Cars[j].Specs.CurrentPerceivedSpeed;
							} else {
								Function.Stack[s - 1] = 0.0;
							}
						} else {
							Function.Stack[s - 1] = 0.0;
						}
						break;
					case Instructions.TrainAcceleration:
						if (Train != null) {
							Function.Stack[s] = Train.Cars[CarIndex].Specs.CurrentAcceleration;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.TrainAccelerationOfCar:
						if (Train != null) {
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								Function.Stack[s - 1] = Train.Cars[j].Specs.CurrentAcceleration;
							} else {
								Function.Stack[s - 1] = 0.0;
							}
						} else {
							Function.Stack[s - 1] = 0.0;
						}
						break;
					case Instructions.TrainAccelerationMotor:
						if (Train != null) {
							Function.Stack[s] = 0.0;
							for (int j = 0; j < Train.Cars.Length; j++) {
								if (Train.Cars[j].Specs.IsMotorCar) {
									// hack: CurrentAccelerationOutput does not distinguish between forward/backward
									if (Train.Cars[j].Specs.CurrentAccelerationOutput < 0.0) {
										Function.Stack[s] = Train.Cars[j].Specs.CurrentAccelerationOutput * (double)Math.Sign(Train.Cars[j].Specs.CurrentSpeed);
									} else if (Train.Cars[j].Specs.CurrentAccelerationOutput > 0.0) {
										Function.Stack[s] = Train.Cars[j].Specs.CurrentAccelerationOutput * (double)Train.Specs.CurrentReverser.Actual;
									} else {
										Function.Stack[s] = 0.0;
									}
									break;
								}
							}
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.TrainAccelerationMotorOfCar:
						if (Train != null) {
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								// hack: CurrentAccelerationOutput does not distinguish between forward/backward
								if (Train.Cars[j].Specs.CurrentAccelerationOutput < 0.0) {
									Function.Stack[s - 1] = Train.Cars[j].Specs.CurrentAccelerationOutput * (double)Math.Sign(Train.Cars[j].Specs.CurrentSpeed);
								} else if (Train.Cars[j].Specs.CurrentAccelerationOutput > 0.0) {
									Function.Stack[s - 1] = Train.Cars[j].Specs.CurrentAccelerationOutput * (double)Train.Specs.CurrentReverser.Actual;
								} else {
									Function.Stack[s - 1] = 0.0;
								}
							} else {
								Function.Stack[s - 1] = 0.0;
							}
						} else {
							Function.Stack[s - 1] = 0.0;
						}
						break;
					case Instructions.TrainDistance:
						if (Train != null) {
							double dist = double.MaxValue;
							for (int j = 0; j < Train.Cars.Length; j++) {
								double fx = Train.Cars[j].FrontAxle.Follower.WorldPosition.X - Position.X;
								double fy = Train.Cars[j].FrontAxle.Follower.WorldPosition.Y - Position.Y;
								double fz = Train.Cars[j].FrontAxle.Follower.WorldPosition.Z - Position.Z;
								double f = fx * fx + fy * fy + fz * fz;
								if (f < dist) dist = f;
								double rx = Train.Cars[j].RearAxle.Follower.WorldPosition.X - Position.X;
								double ry = Train.Cars[j].RearAxle.Follower.WorldPosition.Y - Position.Y;
								double rz = Train.Cars[j].RearAxle.Follower.WorldPosition.Z - Position.Z;
								double r = rx * rx + ry * ry + rz * rz;
								if (r < dist) dist = r;
							}
							Function.Stack[s] = Math.Sqrt(dist);
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.TrainDistanceToCar:
						if (Train != null) {
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								double x = 0.5 * (Train.Cars[j].FrontAxle.Follower.WorldPosition.X + Train.Cars[j].RearAxle.Follower.WorldPosition.X) - Position.X;
								double y = 0.5 * (Train.Cars[j].FrontAxle.Follower.WorldPosition.Y + Train.Cars[j].RearAxle.Follower.WorldPosition.Y) - Position.Y;
								double z = 0.5 * (Train.Cars[j].FrontAxle.Follower.WorldPosition.Z + Train.Cars[j].RearAxle.Follower.WorldPosition.Z) - Position.Z;
								Function.Stack[s - 1] = Math.Sqrt(x * x + y * y + z * z);
							} else {
								Function.Stack[s - 1] = 0.0;
							}
						} else {
							Function.Stack[s - 1] = 0.0;
						}
						break;
					case Instructions.TrainTrackDistance:
						if (Train != null) {
							int r = Train.Cars.Length - 1;
							double t0 = Train.Cars[0].FrontAxle.Follower.TrackPosition - Train.Cars[0].FrontAxlePosition + 0.5 * Train.Cars[0].Length;
							double t1 = Train.Cars[r].RearAxle.Follower.TrackPosition - Train.Cars[r].RearAxlePosition - 0.5 * Train.Cars[r].Length;
							Function.Stack[s] = TrackPosition > t0 ? TrackPosition - t0 : TrackPosition < t1 ? TrackPosition - t1 : 0.0;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.TrainTrackDistanceToCar:
						if (Train != null) {
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								double p = 0.5 * (Train.Cars[j].FrontAxle.Follower.TrackPosition + Train.Cars[j].RearAxle.Follower.TrackPosition);
								Function.Stack[s - 1] = TrackPosition - p;
							} else {
								Function.Stack[s - 1] = 0.0;
							}
						} else {
							Function.Stack[s - 1] = 0.0;
						}
						break;
						// door
					case Instructions.Doors:
						if (Train != null) {
							double a = 0.0;
							for (int j = 0; j < Train.Cars.Length; j++) {
								for (int k = 0; k < Train.Cars[j].Specs.Doors.Length; k++) {
									if (Train.Cars[j].Specs.Doors[k].State > a) {
										a = Train.Cars[j].Specs.Doors[k].State;
									}
								}
							}
							Function.Stack[s] = a;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.DoorsIndex:
						if (Train != null) {
							double a = 0.0;
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								for (int k = 0; k < Train.Cars[j].Specs.Doors.Length; k++) {
									if (Train.Cars[j].Specs.Doors[k].State > a) {
										a = Train.Cars[j].Specs.Doors[k].State;
									}
								}
							}
							Function.Stack[s - 1] = a;
						} else {
							Function.Stack[s - 1] = 0.0;
						}
						break;
					case Instructions.LeftDoors:
						if (Train != null) {
							double a = 0.0;
							for (int j = 0; j < Train.Cars.Length; j++) {
								for (int k = 0; k < Train.Cars[j].Specs.Doors.Length; k++) {
									if (Train.Cars[j].Specs.Doors[k].Direction == -1 & Train.Cars[j].Specs.Doors[k].State > a) {
										a = Train.Cars[j].Specs.Doors[k].State;
									}
								}
							}
							Function.Stack[s] = a;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.LeftDoorsIndex:
						if (Train != null) {
							double a = 0.0;
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								for (int k = 0; k < Train.Cars[j].Specs.Doors.Length; k++) {
									if (Train.Cars[j].Specs.Doors[k].Direction == -1 & Train.Cars[j].Specs.Doors[k].State > a) {
										a = Train.Cars[j].Specs.Doors[k].State;
									}
								}
							}
							Function.Stack[s - 1] = a;
						} else {
							Function.Stack[s - 1] = 0.0;
						}
						break;
					case Instructions.RightDoors:
						if (Train != null) {
							double a = 0.0;
							for (int j = 0; j < Train.Cars.Length; j++) {
								for (int k = 0; k < Train.Cars[j].Specs.Doors.Length; k++) {
									if (Train.Cars[j].Specs.Doors[k].Direction == 1 & Train.Cars[j].Specs.Doors[k].State > a) {
										a = Train.Cars[j].Specs.Doors[k].State;
									}
								}
							}
							Function.Stack[s] = a;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.RightDoorsIndex:
						if (Train != null) {
							double a = 0.0;
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								for (int k = 0; k < Train.Cars[j].Specs.Doors.Length; k++) {
									if (Train.Cars[j].Specs.Doors[k].Direction == 1 & Train.Cars[j].Specs.Doors[k].State > a) {
										a = Train.Cars[j].Specs.Doors[k].State;
									}
								}
							}
							Function.Stack[s - 1] = a;
						} else {
							Function.Stack[s - 1] = 0.0;
						}
						break;
					case Instructions.LeftDoorsTarget:
						if (Train != null) {
							bool q = false;
							for (int j = 0; j < Train.Cars.Length; j++) {
								if (Train.Cars[j].Specs.AnticipatedLeftDoorsOpened) {
									q = true;
									break;
								}
							}
							Function.Stack[s] = q ? 1.0 : 0.0;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.LeftDoorsTargetIndex:
						if (Train != null) {
							bool q = false;
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								for (int k = 0; k < Train.Cars[j].Specs.Doors.Length; k++) {
									if (Train.Cars[j].Specs.AnticipatedLeftDoorsOpened) {
										q = true;
										break;
									}
								}
							}
							Function.Stack[s] = q ? 1.0 : 0.0;
						} else {
							Function.Stack[s - 1] = 0.0;
						}
						break;
					case Instructions.RightDoorsTarget:
						if (Train != null) {
							bool q = false;
							for (int j = 0; j < Train.Cars.Length; j++) {
								if (Train.Cars[j].Specs.AnticipatedRightDoorsOpened) {
									q = true;
									break;
								}
							}
							Function.Stack[s] = q ? 1.0 : 0.0;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.RightDoorsTargetIndex:
						if (Train != null) {
							bool q = false;
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								for (int k = 0; k < Train.Cars[j].Specs.Doors.Length; k++) {
									if (Train.Cars[j].Specs.AnticipatedRightDoorsOpened) {
										q = true;
										break;
									}
								}
							}
							Function.Stack[s] = q ? 1.0 : 0.0;
						} else {
							Function.Stack[s - 1] = 0.0;
						}
						break;
						// handles
					case Instructions.ReverserNotch:
						if (Train != null) {
							Function.Stack[s] = (double)Train.Specs.CurrentReverser.Driver;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.PowerNotch:
						if (Train != null) {
							Function.Stack[s] = (double)Train.Specs.CurrentPowerNotch.Driver;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.PowerNotches:
						if (Train != null) {
							Function.Stack[s] = (double)Train.Specs.MaximumPowerNotch;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.BrakeNotch:
						if (Train != null) {
							if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) {
								Function.Stack[s] = (double)Train.Specs.AirBrake.Handle.Driver;
							} else {
								Function.Stack[s] = (double)Train.Specs.CurrentBrakeNotch.Driver;
							}
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.BrakeNotches:
						if (Train != null) {
							if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) {
								Function.Stack[s] = 2.0;
							} else {
								Function.Stack[s] = (double)Train.Specs.MaximumBrakeNotch;
							}
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.BrakeNotchLinear:
						if (Train != null) {
							if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) {
								if (Train.Specs.CurrentEmergencyBrake.Driver) {
									Function.Stack[s] = 3.0;
								} else {
									Function.Stack[s] = (double)Train.Specs.AirBrake.Handle.Driver;
								}
							} else if (Train.Specs.HasHoldBrake) {
								if (Train.Specs.CurrentEmergencyBrake.Driver) {
									Function.Stack[s] = (double)Train.Specs.MaximumBrakeNotch + 2.0;
								} else if (Train.Specs.CurrentBrakeNotch.Driver > 0) {
									Function.Stack[s] = (double)Train.Specs.CurrentBrakeNotch.Driver + 1.0;
								} else {
									Function.Stack[s] = Train.Specs.CurrentHoldBrake.Driver ? 1.0 : 0.0;
								}
							} else {
								if (Train.Specs.CurrentEmergencyBrake.Driver) {
									Function.Stack[s] = (double)Train.Specs.MaximumBrakeNotch + 1.0;
								} else {
									Function.Stack[s] = (double)Train.Specs.CurrentBrakeNotch.Driver;
								}
							}
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.BrakeNotchesLinear:
						if (Train != null) {
							if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) {
								Function.Stack[s] = 3.0;
							} else if (Train.Specs.HasHoldBrake) {
								Function.Stack[s] = Train.Specs.MaximumBrakeNotch + 2.0;
							} else {
								Function.Stack[s] = Train.Specs.MaximumBrakeNotch + 1.0;
							}
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.EmergencyBrake:
						if (Train != null) {
							Function.Stack[s] = Train.Specs.CurrentEmergencyBrake.Driver ? 1.0 : 0.0;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.HasAirBrake:
						if (Train != null) {
							Function.Stack[s] = Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake ? 1.0 : 0.0;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.HoldBrake:
						if (Train != null) {
							Function.Stack[s] = Train.Specs.CurrentHoldBrake.Driver ? 1.0 : 0.0;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.HasHoldBrake:
						if (Train != null) {
							Function.Stack[s] = Train.Specs.HasHoldBrake ? 1.0 : 0.0;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.ConstSpeed:
						if (Train != null) {
							Function.Stack[s] = Train.Specs.CurrentConstSpeed ? 1.0 : 0.0;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.HasConstSpeed:
						if (Train != null) {
							Function.Stack[s] = Train.Specs.HasConstSpeed ? 1.0 : 0.0;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
						// brake
					case Instructions.BrakeMainReservoir:
						if (Train != null) {
							Function.Stack[s] = Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.BrakeMainReservoirOfCar:
						if (Train == null) {
							Function.Stack[s - 1] = 0.0;
						} else {
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								Function.Stack[s - 1] = Train.Cars[j].Specs.AirBrake.MainReservoirCurrentPressure;
							} else {
								Function.Stack[s - 1] = 0.0;
							}
						}
						break;
					case Instructions.BrakeEqualizingReservoir:
						if (Train != null) {
							Function.Stack[s] = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.BrakeEqualizingReservoirOfCar:
						if (Train == null) {
							Function.Stack[s - 1] = 0.0;
						} else {
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								Function.Stack[s - 1] = Train.Cars[j].Specs.AirBrake.EqualizingReservoirCurrentPressure;
							} else {
								Function.Stack[s - 1] = 0.0;
							}
						}
						break;
					case Instructions.BrakeBrakePipe:
						if (Train != null) {
							Function.Stack[s] = Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.BrakeBrakePipeOfCar:
						if (Train == null) {
							Function.Stack[s - 1] = 0.0;
						} else {
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								Function.Stack[s - 1] = Train.Cars[j].Specs.AirBrake.BrakePipeCurrentPressure;
							} else {
								Function.Stack[s - 1] = 0.0;
							}
						}
						break;
					case Instructions.BrakeBrakeCylinder:
						if (Train != null) {
							Function.Stack[s] = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.BrakeBrakeCylinderOfCar:
						if (Train == null) {
							Function.Stack[s - 1] = 0.0;
						} else {
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								Function.Stack[s - 1] = Train.Cars[j].Specs.AirBrake.BrakeCylinderCurrentPressure;
							} else {
								Function.Stack[s - 1] = 0.0;
							}
						}
						break;
					case Instructions.BrakeStraightAirPipe:
						if (Train != null) {
							Function.Stack[s] = Train.Cars[CarIndex].Specs.AirBrake.StraightAirPipeCurrentPressure;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.BrakeStraightAirPipeOfCar:
						if (Train == null) {
							Function.Stack[s - 1] = 0.0;
						} else {
							int j = (int)Math.Round(Function.Stack[s - 1]);
							if (j < 0) j += Train.Cars.Length;
							if (j >= 0 & j < Train.Cars.Length) {
								Function.Stack[s - 1] = Train.Cars[j].Specs.AirBrake.StraightAirPipeCurrentPressure;
							} else {
								Function.Stack[s - 1] = 0.0;
							}
						}
						break;
						// safety
					case Instructions.SafetyPluginAvailable:
						if (Train == TrainManager.PlayerTrain) {
							Function.Stack[s] = TrainManager.PlayerTrain.Specs.Safety.Mode == TrainManager.SafetySystem.Plugin ? 1.0 : 0.0;
						} else {
							Function.Stack[s] = 0.0;
						}
						s++; break;
					case Instructions.SafetyPluginState:
						if (Train == null) {
							Function.Stack[s - 1] = 0.0;
						} else {
							int n = (int)Math.Round(Function.Stack[s - 1]);
							if (Train.Specs.Safety.Mode == TrainManager.SafetySystem.Plugin) {
								if (n >= 0 & n < PluginManager.CurrentPlugin.Panel.Length) {
									Function.Stack[s - 1] = (double)PluginManager.CurrentPlugin.Panel[n];
								} else {
									Function.Stack[s - 1] = 0.0;
								}
							} else {
								Function.Stack[s - 1] = 0.0;
								switch(n) {
									case 256:
										// ATS
										if (Train.Specs.Safety.Mode == TrainManager.SafetySystem.AtsSn) {
											if (Train.Specs.Safety.State == TrainManager.SafetyState.Normal | Train.Specs.Safety.State == TrainManager.SafetyState.Initialization) {
												Function.Stack[s - 1] = 1.0;
											}
										} break;
									case 257:
										// ATS RUN (separate flashing)
										if (Train.Specs.Safety.Mode == TrainManager.SafetySystem.AtsSn) {
											if (Train.Specs.Safety.State == TrainManager.SafetyState.Ringing) {
												Function.Stack[s - 1] = 1.0;
											} else if (Train.Specs.Safety.State == TrainManager.SafetyState.Emergency | Train.Specs.Safety.State == TrainManager.SafetyState.Pattern | Train.Specs.Safety.State == TrainManager.SafetyState.Service) {
												Function.Stack[s - 1] = 2.0;
											}
										} break;
									case 258:
										// ATS RUN (integrated flashing)
										if (Train.Specs.Safety.Mode == TrainManager.SafetySystem.AtsSn) {
											if (Train.Specs.Safety.State == TrainManager.SafetyState.Ringing) {
												Function.Stack[s - 1] = 1.0;
											} else if (Train.Specs.Safety.State == TrainManager.SafetyState.Emergency | Train.Specs.Safety.State == TrainManager.SafetyState.Pattern | Train.Specs.Safety.State == TrainManager.SafetyState.Service) {
												if (((int)Math.Floor(2.0 * Game.SecondsSinceMidnight) & 1) == 0) {
													Function.Stack[s - 1] = 1.0;
												} else {
													Function.Stack[s - 1] = 0.0;
												}
											}
										} break;
									case 259:
										// P POWER
										if ((Train.Specs.Safety.Mode == TrainManager.SafetySystem.AtsSn | Train.Specs.Safety.Mode == TrainManager.SafetySystem.AtsP) & Train.Specs.Safety.Ats.AtsPAvailable) {
											Function.Stack[s - 1] = 1.0;
										} break;
									case 260:
										// PATTERN APPROACH
										if (Train.Specs.Safety.Mode == TrainManager.SafetySystem.AtsP) {
											if (Train.Specs.Safety.State == TrainManager.SafetyState.Pattern | Train.Specs.Safety.State == TrainManager.SafetyState.Service) {
												Function.Stack[s - 1] = 1.0;
											}
										} break;
									case 261:
										// BRAKE RELEASE
										if (Train.Specs.Safety.Mode == TrainManager.SafetySystem.AtsP) {
											if (Train.Specs.Safety.Ats.AtsPOverride) {
												Function.Stack[s - 1] = 1.0;
											}
										} break;
									case 262:
										// BRAKE OPERATION
										if (Train.Specs.Safety.Mode == TrainManager.SafetySystem.AtsP) {
											if (Train.Specs.Safety.State == TrainManager.SafetyState.Service & !Train.Specs.Safety.Ats.AtsPOverride) {
												Function.Stack[s - 1] = 1.0;
											}
										} break;
									case 263:
										// ATS-P
										if (Train.Specs.Safety.Mode == TrainManager.SafetySystem.AtsP) {
											Function.Stack[s - 1] = 1.0;
										} break;
									case 264:
										// FAILURE
										if (Train.Specs.Safety.Mode != TrainManager.SafetySystem.None) {
											if (Train.Specs.Safety.State == TrainManager.SafetyState.Initialization) {
												Function.Stack[s - 1] = 1.0;
											} else if (Train.Specs.Safety.Mode == TrainManager.SafetySystem.AtsP) {
												if (Train.Specs.Safety.State == TrainManager.SafetyState.Ringing | Train.Specs.Safety.State == TrainManager.SafetyState.Emergency) {
													Function.Stack[s - 1] = 1.0;
												}
											}
										} break;
									case 265:
										// ATC
										if (Train.Specs.Safety.Mode == TrainManager.SafetySystem.Atc) {
											Function.Stack[s - 1] = 1.0;
										} break;
									case 266:
										// ATC POWER
										if ((Train.Specs.Safety.Mode == TrainManager.SafetySystem.Atc | Train.Specs.Safety.Mode != TrainManager.SafetySystem.None & Train.Specs.Safety.Atc.AutomaticSwitch)) {
											Function.Stack[s - 1] = 1.0;
										} break;
									case 267:
										// ATC SERVICE
										if (Train.Specs.Safety.Mode == TrainManager.SafetySystem.Atc) {
											if (Train.Specs.Safety.State == TrainManager.SafetyState.Service) {
												Function.Stack[s - 1] = 1.0;
											}
										} break;
									case 268:
										// ATC EMERGENCY
										if (Train.Specs.Safety.Mode == TrainManager.SafetySystem.Atc) {
											if (!Train.Specs.Safety.Atc.Transmitting) {
												Function.Stack[s - 1] = 1.0;
											}
										} break;
									case 269:
										// EB
										if (Train.Specs.Safety.Mode != TrainManager.SafetySystem.None) {
											if (Train.Specs.Safety.Eb.BellState == TrainManager.SafetyState.Ringing) {
												Function.Stack[s - 1] = 1.0;
											}
										} break;
									case 270:
										// CONST SPEED
										if (Train.Specs.HasConstSpeed) {
											if (Train.Specs.CurrentConstSpeed) {
												Function.Stack[s - 1] = 1.0;
											}
										} break;
									case 271:
										// atc speedometer state
										if (Train.Specs.Safety.Mode == TrainManager.SafetySystem.Atc) {
											if (!Train.Specs.Safety.Atc.Transmitting) {
												Function.Stack[s - 1] = 0.0;
											} else {
												if (Train.Specs.Safety.Atc.SpeedRestriction < 4.1666) {
													Function.Stack[s - 1] = 1.0;
												} else if (Train.Specs.Safety.Atc.SpeedRestriction < 6.9443) {
													Function.Stack[s - 1] = 2.0;
												} else if (Train.Specs.Safety.Atc.SpeedRestriction < 12.4999) {
													Function.Stack[s - 1] = 3.0;
												} else if (Train.Specs.Safety.Atc.SpeedRestriction < 15.2777) {
													Function.Stack[s - 1] = 4.0;
												} else if (Train.Specs.Safety.Atc.SpeedRestriction < 18.0555) {
													Function.Stack[s - 1] = 5.0;
												} else if (Train.Specs.Safety.Atc.SpeedRestriction < 20.8333) {
													Function.Stack[s - 1] = 6.0;
												} else if (Train.Specs.Safety.Atc.SpeedRestriction < 24.9999) {
													Function.Stack[s - 1] = 7.0;
												} else if (Train.Specs.Safety.Atc.SpeedRestriction < 27.7777) {
													Function.Stack[s - 1] = 8.0;
												} else if (Train.Specs.Safety.Atc.SpeedRestriction < 30.5555) {
													Function.Stack[s - 1] = 9.0;
												} else if (Train.Specs.Safety.Atc.SpeedRestriction < 33.3333) {
													Function.Stack[s - 1] = 10.0;
												} else {
													Function.Stack[s - 1] = 11.0;
												}
											}
										} else {
											Function.Stack[s - 1] = 12.0;
										} break;

								}
							}
						} break;
						// timetable
					case Instructions.TimetableVisible:
						Function.Stack[s] = Timetable.CurrentTimetable == Timetable.TimetableState.Custom & Timetable.CustomTimetableAvailable ? 0.0 : -1.0;
						s++; break;
						// sections
					case Instructions.SectionAspectNumber:
						if (IsPartOfTrain) {
							int nextSectionIndex = Train.CurrentSectionIndex + 1;
							if (nextSectionIndex >= 0 & nextSectionIndex < Game.Sections.Length) {
								int a = Game.Sections[nextSectionIndex].CurrentAspect;
								if (a >= 0 & a < Game.Sections[nextSectionIndex].Aspects.Length) {
									Function.Stack[s] = (double)Game.Sections[nextSectionIndex].Aspects[a].Number;
								} else {
									Function.Stack[s] = 0;
								}
							}
						} else if (SectionIndex >= 0 & SectionIndex < Game.Sections.Length) {
							int a = Game.Sections[SectionIndex].CurrentAspect;
							if (a >= 0 & a < Game.Sections[SectionIndex].Aspects.Length) {
								Function.Stack[s] = (double)Game.Sections[SectionIndex].Aspects[a].Number;
							} else {
								Function.Stack[s] = 0;
							}
						} else {
							Function.Stack[s] = 0;
						}
						s++; break;
						// default
					default:
						throw new System.InvalidOperationException("The unknown instruction " + Function.Instructions[i].ToString() + " was encountered in ExecuteFunctionScript.");
				}
			}
			Function.LastResult = Function.Stack[s - 1];
		}
コード例 #33
0
ファイル: Screen.cs プロジェクト: tsdworks/RAGLINK
        /// <summary>Changes to or from fullscreen mode.</summary>
        internal static void ToggleFullscreen()
        {
            Fullscreen = !Fullscreen;
            // begin HACK //
            Renderer.ClearDisplayLists();

            GL.Disable(EnableCap.Fog);
            GL.Disable(EnableCap.Lighting);
            Renderer.LightingEnabled = false;
            if (Fullscreen)
            {
                IList <DisplayResolution> resolutions = OpenTK.DisplayDevice.Default.AvailableResolutions;

                for (int i = 0; i < resolutions.Count; i++)
                {
                    //Test each resolution
                    if (resolutions[i].Width == Interface.CurrentOptions.FullscreenWidth &&
                        resolutions[i].Height == Interface.CurrentOptions.FullscreenHeight &&
                        resolutions[i].BitsPerPixel == Interface.CurrentOptions.FullscreenBits)
                    {
                        OpenTK.DisplayDevice.Default.ChangeResolution(resolutions[i]);
                        Program.currentGameWindow.Width  = resolutions[i].Width;
                        Program.currentGameWindow.Height = resolutions[i].Height;
                        Screen.Width  = Interface.CurrentOptions.FullscreenWidth;
                        Screen.Height = Interface.CurrentOptions.FullscreenHeight;
                        Program.currentGameWindow.WindowState = WindowState.Fullscreen;
                        break;
                    }
                }
                System.Threading.Thread.Sleep(20);
                if (Program.currentGameWindow.WindowState != WindowState.Fullscreen)
                {
                    MessageBox.Show(Translations.GetInterfaceString("errors_fullscreen_switch1") + System.Environment.NewLine +
                                    Translations.GetInterfaceString("errors_fullscreen_switch2"), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand);
                    Fullscreen = false;
                }
            }
            else
            {
                OpenTK.DisplayDevice.Default.RestoreResolution();
                Program.currentGameWindow.WindowState = WindowState.Normal;
                Program.currentGameWindow.Width       = Interface.CurrentOptions.WindowWidth;
                Program.currentGameWindow.Height      = Interface.CurrentOptions.WindowHeight;

                Screen.Width  = Interface.CurrentOptions.WindowWidth;
                Screen.Height = Interface.CurrentOptions.WindowHeight;
            }
            Renderer.InitializeLighting();
            Renderer.UpdateViewport(Renderer.ViewPortChangeMode.NoChange);
            Renderer.InitializeMotionBlur();
            lock (Illustrations.Locker)
            {
                Timetable.CreateTimetable();
            }
            Timetable.UpdateCustomTimetable(null, null);

            World.InitializeCameraRestriction();
            if (Renderer.OptionBackfaceCulling)
            {
                GL.Enable(EnableCap.CullFace);
            }
            else
            {
                GL.Disable(EnableCap.CullFace);
            }
            Renderer.ReAddObjects();
            // end HACK //

            //Reset the camera when switching between fullscreen and windowed mode
            //Otherwise, if the aspect ratio changes distortion will occur until the view is changed or the camera reset
            if (World.CameraMode == CameraViewMode.Interior | World.CameraMode == CameraViewMode.InteriorLookAhead)
            {
                World.CameraCurrentAlignment.Position = new OpenBveApi.Math.Vector3(0.0, 0.0, 0.0);
            }
            World.CameraCurrentAlignment.Yaw   = 0.0;
            World.CameraCurrentAlignment.Pitch = 0.0;
            World.CameraCurrentAlignment.Roll  = 0.0;
        }