#region Copyright /* -------------------------------------------------------------------------------- This source file is part of Xenocide by Project Xenocide Team For the latest info on Xenocide, see http://www.projectxenocide.com/ This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.5/ or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA. -------------------------------------------------------------------------------- */ /* * @file GeoMarker.cs * @date Created: 2007/01/29 * @author File creator: dteviot * @author Credits: none */ #endregion #region Using Statements using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Content; using ProjectXenocide.Model.Geoscape; #endregion namespace ProjectXenocide.UI.Scenes.Geoscape { /// /// Used to draw a shape at a position of interest on the Globe /// class GeoMarker { public VertexDeclaration basicEffectVertexDeclaration; private VertexPositionNormalTexture[] meshVertices; private short[] meshIndices; VertexBuffer vertexBuffer; IndexBuffer indexBuffer; /// /// Load/create the graphic resources needed by the GeoMarker /// /// the display public void LoadContent(GraphicsDevice device) { // construct the shape InitializeMesh(); ConstructVertexBuffer(device); ConstructIndexBuffer(device); basicEffectVertexDeclaration = new VertexDeclaration( device, VertexPositionNormalTexture.VertexElements); } /// /// Creates the GeoMarker's mesh /// private void InitializeMesh() { Vector3 top = new Vector3( 0.00f, 0.00f, 0.0f); Vector3 baseTopLeft = new Vector3(-0.05f, 0.05f, 0.5f); Vector3 baseTopRight = new Vector3( 0.05f, 0.05f, 0.5f); Vector3 baseBottomLeft = new Vector3(-0.05f, -0.05f, 0.5f); Vector3 baseBottomRight = new Vector3( 0.05f, -0.05f, 0.5f); meshVertices = new VertexPositionNormalTexture[5]; meshVertices[0] = makeVertex(top); meshVertices[1] = makeVertex(baseTopLeft); meshVertices[2] = makeVertex(baseTopRight); meshVertices[3] = makeVertex(baseBottomLeft); meshVertices[4] = makeVertex(baseBottomRight); meshIndices = new short[18]{ // top, left bottom right 0, 2, 1, 0, 1, 3, 0, 3, 4, 0, 4, 2, // base 2, 3, 1, 3, 2, 4 }; } /// /// Construct a VertexPositionNormalTexture for this position /// /// Position of the vertex /// The vertex private static VertexPositionNormalTexture makeVertex(Vector3 position) { // we're using this Vertext type because there isn't a VertexPositionNormal type // but we're not using the texture (at this point in time) Vector2 texture = new Vector2(0.0f, 0.0f); return new VertexPositionNormalTexture(position, Vector3.Normalize(position), texture); } /// /// construct a vertex buffer that can be used to draw the GeoMarker /// public void ConstructVertexBuffer(GraphicsDevice device) { vertexBuffer = new VertexBuffer( device, VertexPositionNormalTexture.SizeInBytes * meshVertices.Length, BufferUsage.None ); vertexBuffer.SetData(meshVertices); } /// /// construct the triangle list that can be used to draw the GeoMarker. /// public void ConstructIndexBuffer(GraphicsDevice device) { indexBuffer = new IndexBuffer( device, sizeof(short) * meshIndices.Length, BufferUsage.None, IndexElementSize.SixteenBits ); indexBuffer.SetData(meshIndices); } /// /// Initialize the Basic effect prior to drawing a number of GeoMarkers /// /// /// public void setupEffect(GraphicsDevice device, BasicEffect effect) { device.RenderState.CullMode = CullMode.None; device.VertexDeclaration = basicEffectVertexDeclaration; device.Vertices[0].SetSource( vertexBuffer, 0, VertexPositionNormalTexture.SizeInBytes); device.Indices = indexBuffer; effect.TextureEnabled = false; } /// /// Draw the GeoMarker on the device /// /// Device to render the GeoMarker to /// GeoMarker's location on the globe /// effect to use to draw the GeoMarker public void Draw(GraphicsDevice device, Vector3 geoposition, BasicEffect effect) { effect.World = geopositionToWorld(geoposition); effect.Begin(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); device.DrawIndexedPrimitives( PrimitiveType.TriangleList, 0, 0, meshVertices.Length, 0, meshIndices.Length / 3 ); pass.End(); } effect.End(); } /// /// Converts a position on the globe into the World matrix for positioning the GeoMarker /// /// position on globe (in polar radians) /// World matrix used by Draw public static Matrix geopositionToWorld(Vector3 geoposition) { // make sure geopositon is on world geoposition.Z = 1.0f; return Matrix.CreateRotationX(-geoposition.Y) * Matrix.CreateRotationY(geoposition.X) * Matrix.CreateTranslation(GeoPosition.PolarToCartesian(geoposition)); } } }