#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));
}
}
}