internal static void UpdateMouseGrab(double TimeElapsed) { if (MainLoop.MouseGrabEnabled) { double factor; if (Program.Renderer.Camera.CurrentMode == CameraViewMode.Interior | Program.Renderer.Camera.CurrentMode == CameraViewMode.InteriorLookAhead) { factor = 1.0; } else { factor = 3.0; } Program.Renderer.Camera.AlignmentDirection.Yaw += factor * MouseGrabTarget.X; Program.Renderer.Camera.AlignmentDirection.Pitch -= factor * MouseGrabTarget.Y; MouseGrabTarget = OpenBveApi.Math.Vector2.Null; } }
internal static void UpdateMouse(double TimeElapsed) { if (Game.CurrentInterface != Game.InterfaceType.Menu) { timeSinceLastMouseEvent += TimeElapsed; } else { timeSinceLastMouseEvent = 0; //Always show the mouse in the menu } if (Interface.CurrentOptions.CursorHideDelay > 0 && timeSinceLastMouseEvent > Interface.CurrentOptions.CursorHideDelay) { Program.currentGameWindow.CursorVisible = false; } else { Program.currentGameWindow.CursorVisible = true; } if (MainLoop.MouseGrabEnabled) { double factor; if (Program.Renderer.Camera.CurrentMode == CameraViewMode.Interior | Program.Renderer.Camera.CurrentMode == CameraViewMode.InteriorLookAhead) { factor = 1.0; } else { factor = 3.0; } Program.Renderer.Camera.AlignmentDirection.Yaw += factor * MouseGrabTarget.X; Program.Renderer.Camera.AlignmentDirection.Pitch -= factor * MouseGrabTarget.Y; MouseGrabTarget = OpenBveApi.Math.Vector2.Null; } }
internal static void ProcessKeyboard() { if (Interface.CurrentOptions.UseJoysticks) { for (int k = 0; k < JoystickManager.AttachedJoysticks.Length; k++) { JoystickManager.AttachedJoysticks[k].Poll(); } } if (Game.CurrentInterface == Game.InterfaceType.Menu && Game.Menu.IsCustomizingControl()) { if (Interface.CurrentOptions.UseJoysticks) { for (int k = 0; k < JoystickManager.AttachedJoysticks.Length; k++) { int axes = JoystickManager.AttachedJoysticks[k].AxisCount(); for (int i = 0; i < axes; i++) { double aa = JoystickManager.AttachedJoysticks[k].GetAxis(i); if (aa < -0.75) { Game.Menu.SetControlJoyCustomData(k, Interface.JoystickComponent.Axis, i, -1); return; } if (aa > 0.75) { Game.Menu.SetControlJoyCustomData(k, Interface.JoystickComponent.Axis, i, 1); return; } } int buttons = JoystickManager.AttachedJoysticks[k].ButtonCount(); for (int i = 0; i < buttons; i++) { if (JoystickManager.AttachedJoysticks[k].GetButton(i) == ButtonState.Pressed) { Game.Menu.SetControlJoyCustomData(k, Interface.JoystickComponent.Button, i, 1); return; } } int hats = JoystickManager.AttachedJoysticks[k].HatCount(); for (int i = 0; i < hats; i++) { JoystickHatState hat = JoystickManager.AttachedJoysticks[k].GetHat(i); if (hat.Position != HatPosition.Centered) { Game.Menu.SetControlJoyCustomData(k, Interface.JoystickComponent.Hat, i, (int)hat.Position); return; } } } } return; } if (MouseGrabEnabled) { previousMouseState = currentMouseState; currentMouseState = Mouse.GetState(); if (previousMouseState != currentMouseState) { if (MouseGrabIgnoreOnce) { MouseGrabIgnoreOnce = false; } else if (MouseGrabEnabled) { MouseGrabTarget = new OpenBveApi.Math.Vector2(currentMouseState.X - previousMouseState.X, currentMouseState.Y - previousMouseState.Y); } } } //Traverse the controls array for (int i = 0; i < Interface.CurrentControls.Length; i++) { int currentDevice = Interface.CurrentControls[i].Device; //Check to see if our device is currently available switch (Interface.CurrentControls[i].Method) { case Interface.ControlMethod.Joystick: if (JoystickManager.AttachedJoysticks.Length == 0 || !Joystick.GetCapabilities(Interface.CurrentControls[i].Device).IsConnected) { //Not currently connected continue; } break; case Interface.ControlMethod.RailDriver: if (JoystickManager.RailDriverIndex == -1) { //Not currently connected continue; } currentDevice = JoystickManager.RailDriverIndex; break; default: //Not a joystick / RD continue; } switch (Interface.CurrentControls[i].Component) { case Interface.JoystickComponent.Axis: var axisState = JoystickManager.GetAxis(currentDevice, Interface.CurrentControls[i].Element); if (axisState.ToString(CultureInfo.InvariantCulture) != Interface.CurrentControls[i].LastState) { Interface.CurrentControls[i].LastState = axisState.ToString(CultureInfo.InvariantCulture); if (Interface.CurrentControls[i].InheritedType == Translations.CommandType.AnalogHalf) { if (Math.Sign(axisState) == Math.Sign(Interface.CurrentControls[i].Direction)) { axisState = Math.Abs(axisState); if (axisState < Interface.CurrentOptions.JoystickAxisThreshold) { Interface.CurrentControls[i].AnalogState = 0.0; } else if (Interface.CurrentOptions.JoystickAxisThreshold != 1.0) { Interface.CurrentControls[i].AnalogState = (axisState - Interface.CurrentOptions.JoystickAxisThreshold) / (1.0 - Interface.CurrentOptions.JoystickAxisThreshold); } else { Interface.CurrentControls[i].AnalogState = 1.0; } } } else if (Interface.CurrentControls[i].InheritedType == Translations.CommandType.AnalogFull) { axisState *= (float)Interface.CurrentControls[i].Direction; if (axisState > -Interface.CurrentOptions.JoystickAxisThreshold & axisState < Interface.CurrentOptions.JoystickAxisThreshold) { Interface.CurrentControls[i].AnalogState = 0.0; } else if (Interface.CurrentOptions.JoystickAxisThreshold != 1.0) { if (axisState < 0.0) { Interface.CurrentControls[i].AnalogState = (axisState + Interface.CurrentOptions.JoystickAxisThreshold) / (1.0 - Interface.CurrentOptions.JoystickAxisThreshold); } else if (axisState > 0.0) { Interface.CurrentControls[i].AnalogState = (axisState - Interface.CurrentOptions.JoystickAxisThreshold) / (1.0 - Interface.CurrentOptions.JoystickAxisThreshold); } else { Interface.CurrentControls[i].AnalogState = 0.0; } } else { Interface.CurrentControls[i].AnalogState = (double)Math.Sign(axisState); } } else { if (Math.Sign(axisState) == Math.Sign(Interface.CurrentControls[i].Direction)) { axisState = Math.Abs(axisState); if (axisState < Interface.CurrentOptions.JoystickAxisThreshold) { axisState = 0.0f; } else if (Interface.CurrentOptions.JoystickAxisThreshold != 1.0) { axisState = (float)((axisState - Interface.CurrentOptions.JoystickAxisThreshold) / (1.0 - Interface.CurrentOptions.JoystickAxisThreshold)); } else { axisState = 1.0f; } if (Interface.CurrentControls[i].DigitalState == Interface.DigitalControlState.Released | Interface.CurrentControls[i].DigitalState == Interface.DigitalControlState.ReleasedAcknowledged) { if (axisState > 0.67) { Interface.CurrentControls[i].DigitalState = Interface.DigitalControlState.Pressed; } } else { if (axisState < 0.33) { Interface.CurrentControls[i].DigitalState = Interface.DigitalControlState.Released; } } } } } break; case Interface.JoystickComponent.Button: //Load the current state var buttonState = JoystickManager.GetButton(currentDevice, Interface.CurrentControls[i].Element); //Test whether the state is the same as the last frame if (buttonState.ToString() != Interface.CurrentControls[i].LastState) { if (buttonState == ButtonState.Pressed) { Interface.CurrentControls[i].AnalogState = 1.0; Interface.CurrentControls[i].DigitalState = Interface.DigitalControlState.Pressed; AddControlRepeat(i); } else { Interface.CurrentControls[i].AnalogState = 0.0; Interface.CurrentControls[i].DigitalState = Interface.DigitalControlState.Released; RemoveControlRepeat(i); } //Store the state Interface.CurrentControls[i].LastState = buttonState.ToString(); } break; case Interface.JoystickComponent.Hat: //Load the current state var hatState = JoystickManager.GetHat(currentDevice, Interface.CurrentControls[i].Element).Position; //Test if the state is the same as last frame if (hatState.ToString() != Interface.CurrentControls[i].LastState) { if ((int)hatState == Interface.CurrentControls[i].Direction) { Interface.CurrentControls[i].AnalogState = 1.0; Interface.CurrentControls[i].DigitalState = Interface.DigitalControlState.Pressed; AddControlRepeat(i); } else { Interface.CurrentControls[i].AnalogState = 0.0; Interface.CurrentControls[i].DigitalState = Interface.DigitalControlState.Released; RemoveControlRepeat(i); } //Store the state Interface.CurrentControls[i].LastState = hatState.ToString(); } break; } } }
/// <summary>Creates or updates the display list for the static objects. If the display list already exists, it is recreated.</summary> internal void CreateOrUpdateDisplayList() { /* * Load all textures used by the objects in this leaf node. * */ this.LoadTextures(); /* * Begin rendering to the display list. * */ Renderer.OpenGlState state; this.DisplayList.Begin(out state); /* * Render all attached static objects. * */ Renderer.RenderStaticOpaqueObjects(this.StaticOpaqueObjects, this.StaticOpaqueObjectCount, ref state); if (Program.CurrentOptions.ShowGrid) { /* * Render the rectangle and bounding rectangle for debugging purposes. * */ OpenBveApi.Color.ColorRGB brightColor = new OpenBveApi.Color.ColorRGB( (float)Program.RandomNumberGenerator.NextDouble(), (float)Program.RandomNumberGenerator.NextDouble(), (float)Program.RandomNumberGenerator.NextDouble() ); OpenBveApi.Color.ColorRGB darkColor = new OpenBveApi.Color.ColorRGB( 0.5f * brightColor.R, 0.5f * brightColor.G, 0.5f * brightColor.B ); { /* Render the rectangle. */ double x = 0.5 * (this.Rectangle.Right - this.Rectangle.Left); double z = 0.5 * (this.Rectangle.Far - this.Rectangle.Near); OpenBveApi.Math.Vector3[] vertices = new OpenBveApi.Math.Vector3[] { new OpenBveApi.Math.Vector3(-x, -1.1, -z), new OpenBveApi.Math.Vector3(-x, -1.1, z), new OpenBveApi.Math.Vector3(x, -1.1, z), new OpenBveApi.Math.Vector3(x, -1.1, -z) }; Renderer.RenderPolygonFromVertices(vertices, darkColor, OpenBveApi.Color.ColorRGB.Black, ref state); } { /* Render the bounding rectangle. */ OpenBveApi.Math.Vector2 center = new OpenBveApi.Math.Vector2( 0.5 * (this.Rectangle.Left + this.Rectangle.Right), 0.5 * (this.Rectangle.Near + this.Rectangle.Far) ); OpenBveApi.Math.Vector2 nearLeft = new OpenBveApi.Math.Vector2( this.BoundingRectangle.Left - center.X, this.BoundingRectangle.Near - center.Y ); OpenBveApi.Math.Vector2 nearRight = new OpenBveApi.Math.Vector2( this.BoundingRectangle.Right - center.X, this.BoundingRectangle.Near - center.Y ); OpenBveApi.Math.Vector2 farLeft = new OpenBveApi.Math.Vector2( this.BoundingRectangle.Left - center.X, this.BoundingRectangle.Far - center.Y ); OpenBveApi.Math.Vector2 farRight = new OpenBveApi.Math.Vector2( this.BoundingRectangle.Right - center.X, this.BoundingRectangle.Far - center.Y ); OpenBveApi.Math.Vector3[] vertices = new OpenBveApi.Math.Vector3[] { new OpenBveApi.Math.Vector3(nearLeft.X, -1.0, nearLeft.Y), new OpenBveApi.Math.Vector3(farLeft.X, -1.0, farLeft.Y), new OpenBveApi.Math.Vector3(farRight.X, -1.0, farRight.Y), new OpenBveApi.Math.Vector3(nearRight.X, -1.0, nearRight.Y) }; Renderer.RenderPolygonFromVertices(vertices, brightColor, OpenBveApi.Color.ColorRGB.Black, ref state); } } /* * End rendering to the display list. * */ this.DisplayList.End(ref state); }
// constructors /// <summary>Creates a new instance of this class.</summary> /// <param name="points">An array of three points that describe the triangle.</param> internal Triangle(OpenBveApi.Math.Vector2[] points) { this.PointA = points[0]; this.PointB = points[1]; this.PointC = points[2]; this.BoundingRectangle = ObjectGrid.GridBounds.Uninitialized; for (int i = 0; i < 3; i++) { if (points[i].X < this.BoundingRectangle.Left) { this.BoundingRectangle.Left = points[i].X; } if (points[i].X > this.BoundingRectangle.Right) { this.BoundingRectangle.Right = points[i].X; } if (points[i].Y < this.BoundingRectangle.Near) { this.BoundingRectangle.Near = points[i].Y; } if (points[i].Y > this.BoundingRectangle.Far) { this.BoundingRectangle.Far = points[i].Y; } } this.CrossAB = OpenBveApi.Math.Vector2.Cross(this.PointB - this.PointA); this.CrossBC = OpenBveApi.Math.Vector2.Cross(this.PointC - this.PointB); this.CrossCA = OpenBveApi.Math.Vector2.Cross(this.PointA - this.PointC); }
private static void InitializeBlockClipping(out Triangle[] triangles) { /* * Set up the four corners of the screen in screen coordinates. * */ OpenBveApi.Math.Vector2[] corners = new OpenBveApi.Math.Vector2[] { new OpenBveApi.Math.Vector2(-1.0, -1.0), new OpenBveApi.Math.Vector2(1.0, -1.0), new OpenBveApi.Math.Vector2(1.0, 1.0), new OpenBveApi.Math.Vector2(-1.0, 1.0) }; /* * Project the corners into world coordinates by * extending them by the viewing distance. * Incorporate the position of the camera as * a fifth projected point. * */ double width = Math.Tan(0.5 * Camera.Viewport.HorizontalViewingAngle); double height = Math.Tan(0.5 * Camera.Viewport.VerticalViewingAngle); OpenBveApi.Math.Vector2[] projections = new OpenBveApi.Math.Vector2[5]; for (int i = 0; i < 4; i++) { OpenBveApi.Math.Vector3 direction = width * corners[i].X * Camera.Orientation.X + height * corners[i].Y * Camera.Orientation.Y + Camera.Orientation.Z; OpenBveApi.Math.Vector3 vector = Camera.Position + Camera.Viewport.FarClippingPlane * direction; projections[i] = new OpenBveApi.Math.Vector2(vector.X, vector.Z); } projections[4] = new OpenBveApi.Math.Vector2(Camera.Position.X, Camera.Position.Z); /* * Determine the convex hull of the five points. * The algorithm used is Graham Scan, but with * practical problems such as floating-point * imprecisions and coindicing points taken into * account. * */ int first = 0; for (int i = 1; i < projections.Length; i++) { const double threshold = 0.00000001; double deltaY = projections[i].Y - projections[first].Y; if (deltaY < -threshold | deltaY >= -threshold & deltaY <= threshold & projections[i].X < projections[first].X) { first = i; } } double[] angles = new double[projections.Length]; for (int i = 0; i < projections.Length; i++) { if (i == first) { angles[i] = double.MinValue; } else { double dx = projections[i].X - projections[first].X; double dy = projections[i].Y - projections[first].Y; if (dy < 0.0) { dy = -dy; } if (dy <= 0.00000001) { angles[i] = -1e200 + (1e200 * Math.Atan(dx / 4096.0)); } else { angles[i] = -dx / dy; } } } Array.Sort<double, OpenBveApi.Math.Vector2>(angles, projections); OpenBveApi.Math.Vector2[] hull = new OpenBveApi.Math.Vector2[projections.Length]; hull[0] = projections[0]; hull[1] = projections[1]; int count = 2; for (int i = 2; i < projections.Length; i++) { while (count >= 2) { const double c = 0.000000001; double d = (hull[count - 1].X - hull[count - 2].X) * (projections[i].Y - hull[count - 2].Y) - (hull[count - 1].Y - hull[count - 2].Y) * (projections[i].X - hull[count - 2].X); if (d <= c) { count--; } else { break; } } hull[count] = projections[i]; count++; } /* * Divide the convex hull into triangles. * */ if (count == 3) { triangles = new Triangle[] { new Triangle(new OpenBveApi.Math.Vector2[] { hull[0], hull[1], hull[2] }) }; } else if (count == 4) { triangles = new Triangle[] { new Triangle(new OpenBveApi.Math.Vector2[] { hull[0], hull[1], hull[2] }), new Triangle(new OpenBveApi.Math.Vector2[] { hull[0], hull[2], hull[3] }) }; } else if (count == 5) { triangles = new Triangle[] { new Triangle(new OpenBveApi.Math.Vector2[] { hull[0], hull[1], hull[2] }), new Triangle(new OpenBveApi.Math.Vector2[] { hull[0], hull[2], hull[3] }), new Triangle(new OpenBveApi.Math.Vector2[] { hull[0], hull[3], hull[4] }) }; } else { triangles = new Triangle[] { }; } }
private static void RenderCube(Vector3 Position, Vector3 Direction, Vector3 Up, Vector3 Side, double Size, double CameraX, double CameraY, double CameraZ, Texture TextureIndex) { Vector3[] v = new Vector3[8]; v[0] = new Vector3(Size, Size, -Size); v[1] = new Vector3(Size, -Size, -Size); v[2] = new Vector3(-Size, -Size, -Size); v[3] = new Vector3(-Size, Size, -Size); v[4] = new Vector3(Size, Size, Size); v[5] = new Vector3(Size, -Size, Size); v[6] = new Vector3(-Size, -Size, Size); v[7] = new Vector3(-Size, Size, Size); for (int i = 0; i < 8; i++) { v[i].Rotate(Direction, Up, Side); 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 }; if (TextureIndex == null || !Textures.LoadTexture(TextureIndex, OpenGlTextureWrapMode.ClampClamp)) { if (TexturingEnabled) { GL.Disable(EnableCap.Texture2D); TexturingEnabled = false; } for (int i = 0; i < 6; i++) { GL.Begin(PrimitiveType.Quads); GL.Color3(1.0, 1.0, 1.0); 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(); } return; } else { TexturingEnabled = true; GL.Enable(EnableCap.Texture2D); } GL.BindTexture(TextureTarget.Texture2D, TextureIndex.OpenGlTextures[(int)OpenGlTextureWrapMode.ClampClamp].Name); Vector2[][] t = new Vector2[6][]; t[0] = new Vector2[] { new Vector2(1.0, 0.0), new Vector2(1.0, 1.0), new Vector2(0.0, 1.0), new Vector2(0.0, 0.0) }; t[1] = new Vector2[] { new Vector2(0.0, 0.0), new Vector2(1.0, 0.0), new Vector2(1.0, 1.0), new Vector2(0.0, 1.0) }; t[2] = new Vector2[] { new Vector2(1.0, 1.0), new Vector2(0.0, 1.0), new Vector2(0.0, 0.0), new Vector2(1.0, 0.0) }; t[3] = new Vector2[] { new Vector2(1.0, 1.0), new Vector2(0.0, 1.0), new Vector2(0.0, 0.0), new Vector2(1.0, 0.0) }; t[4] = new Vector2[] { new Vector2(0.0, 1.0), new Vector2(0.0, 0.0), new Vector2(1.0, 0.0), new Vector2(1.0, 1.0) }; t[5] = new Vector2[] { new Vector2(0.0, 1.0), new Vector2(0.0, 0.0), new Vector2(1.0, 0.0), new Vector2(1.0, 1.0) }; for (int i = 0; i < 6; i++) { GL.Begin(PrimitiveType.Quads); GL.Color3(1.0, 1.0, 1.0); for (int j = 0; j < 4; j++) { GL.TexCoord2(t[i][j].X, t[i][j].Y); GL.Vertex3(v[Faces[i][j]].X, v[Faces[i][j]].Y, v[Faces[i][j]].Z); } GL.End(); } }