/// <summary> /// Draw quad (Must be inside GL_TRIANGLES or GL_LINES for wireframe) /// </summary> /// <param name="gl">OpenGL isntance</param> /// <param name="map">Shared map data</param> /// <param name="plane">Plane this quad belongs to</param> /// <param name="planeNormal">Normal vector of the plane</param> /// <param name="wireframe">Draw as wireframe</param> public void Draw(SharpGL.OpenGL gl, Powerslave.Map map, Powerslave.Plane plane, Vector3D planeNormal, bool wireframe) { List <Powerslave.Vertex> quad = this.Indices.Select(index => map.Vertices[index + plane.VertexStart]).ToList(); if (Vector3D.DotProduct(planeNormal, Quad.GetQuadNormal(quad)) < 0.0f) { // Quad is rotated incorrectly, reverse it (might be used as a texture flip) quad.Reverse(); } foreach (Powerslave.Vertex point in wireframe ? quad.SelectMany((vertex, index) => new List <Powerslave.Vertex> { vertex, quad[(index + 1) % quad.Count] }) : Powerslave.GetTrianglesFromQuad(quad)) { if (wireframe) { gl.Color(1.0f, 1.0f, 1.0f); } else { Powerslave.SetVertexColor(gl, plane.Flags, point.Lightlevel); } gl.Vertex(point.X / 10.0f, point.Z / 10.0f, point.Y / 10.0f); } }
/// <summary> /// Draw plane (Must be inside GL_TRIANGLES or GL_LINES for wireframe) /// </summary> /// <param name="gl">OpenGL isntance</param> /// <param name="map">Shared map data</param> /// <param name="ignoreTiled">Do not draw tiled quads in planes</param> /// <param name="wireframe">Draw as wireframe</param> public void Draw(SharpGL.OpenGL gl, Powerslave.Map map, bool ignoreTiled, bool wireframe) { if (this.PolyStart != -1 && this.PolyEnd != -1 && !ignoreTiled) { Vector3D planeNormal = new Vector3D(this.Normal.X / (double)short.MaxValue, this.Normal.Z / (double)short.MaxValue, this.Normal.Y / (double)short.MaxValue); int start = Math.Min(this.PolyStart, this.PolyEnd); int end = Math.Max(this.PolyStart, this.PolyEnd); for (int polygon = start; polygon <= end; polygon++) { map.Quads[polygon].Draw(gl, map, this, planeNormal, wireframe); } } else { List <Powerslave.Vertex> vertices = this.PolyVert.Select(index => map.Vertices[index]).ToList(); foreach (Powerslave.Vertex point in wireframe ? vertices.SelectMany((vertex, index) => new List <Powerslave.Vertex> { vertex, vertices[(index + 1) % vertices.Count] }) : Powerslave.GetTrianglesFromQuad(vertices)) { if (wireframe) { gl.Color(1.0f, 1.0f, 1.0f); } else { Powerslave.SetVertexColor(gl, this.Flags, point.Lightlevel); } gl.Vertex(point.X / 10.0f, point.Z / 10.0f, point.Y / 10.0f); } } }
/// <summary> /// Get camera to plane distance /// </summary> /// <param name="point">Camera position</param> /// <param name="plane">Plane definition</param> /// <param name="map">Shared map data</param> /// <returns>Plane distance</returns> private static int GetDistance(Point3D point, Powerslave.Plane plane, Powerslave.Map map) { List <Powerslave.Vertex> vertices = plane.PolyVert.Select(vertex => map.Vertices[vertex]).ToList(); Powerslave.Vertex center = new Powerslave.Vertex() { X = (short)(vertices.Sum(vertex => vertex.X) / 4), Y = (short)(vertices.Sum(vertex => vertex.Y) / 4), Z = (short)(vertices.Sum(vertex => vertex.Z) / 4) }; return((int)(Math.Pow(point.X - (center.X / 10.0f), 2) + Math.Pow(point.Y - (center.Z / 10.0f), 2) + Math.Pow(point.Z - (center.Y / 10.0f), 2))); }
/// <summary> /// Load map from file /// </summary> /// <param name="sender">Button control</param> /// <param name="e">Empty event</param> private void LoadMap(object sender, RoutedEventArgs e) { MS.OpenFileDialog openFileDialog = new MS.OpenFileDialog { Filter = "PowerSlave (Saturn) map|*.LEV" }; if (openFileDialog.ShowDialog().Value) { if (this.map != null) { if (this.map.Sky != null) { this.map.Sky.Dispose(); } this.map = null; this.OnPropertyChanged("IsMapLoaded"); } this.camera.Position = new Point3D(4.0, 4.0, 10.0); this.camera.Target = new Point3D(0.0, 0.0, 0.0); this.IsMapNotLoading = false; new Thread(() => { Thread.CurrentThread.IsBackground = true; try { Powerslave.Map loaded = Powerslave.Map.Load(openFileDialog.FileName); loaded.Sky.Save("test.bmp"); this.Dispatcher.Invoke(() => { this.map = loaded; this.IsMapNotLoading = true; this.OnPropertyChanged("IsMapLoaded"); this.SetCameraPosition(); }); } catch (Exception ex) { this.Dispatcher.Invoke(() => { MessageBox.Show(this, ex.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error); this.IsMapNotLoading = true; }); } }).Start(); } }