00001
00002 namespace NewGamePhysics.GraphicalElements
00003 {
00004 using System;
00005 using System.Collections.Generic;
00006 using System.Linq;
00007 using System.Text;
00008 using Microsoft.Xna.Framework;
00009 using Microsoft.Xna.Framework.Content;
00010 using Microsoft.Xna.Framework.Graphics;
00011
00012 using NewGamePhysics.Mathematics;
00013
00014 public class TexturedSphere
00015 {
00016 VertexBuffer vertexbuffer;
00017 IndexBuffer indexbuffer;
00018 BasicEffect effect;
00019 VertexDeclaration declaration;
00020
00021 int strideSize;
00022 int nvertices;
00023 int nfaces;
00024
00025 Matrix sphereRollingMatrix = Matrix.Identity;
00026
00035 public TexturedSphere(GraphicsDevice device, int Stacks, int Slices, float Radius, Texture2D texture)
00036 {
00037
00038 nvertices = (Stacks + 1) * (Slices + 1);
00039 VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[nvertices];
00040
00041 int numIndices = (3 * Stacks * (Slices + 1)) * 2;
00042 int[] indices = new int[numIndices];
00043 nfaces = numIndices/3;
00044
00045 float StackAngle = MathHelper.Pi / (float)Stacks;
00046 float SliceAngle = (float)(Math.PI * 2.0) / (float)Slices;
00047
00048 int vertexindex = 0;
00049
00050
00051 int vertexcount = 0;
00052 int indexcount = 0;
00053
00054 for (int stack = 0; stack < (Stacks+1); stack++)
00055 {
00056
00057 float r = (float)Math.Sin((float)stack * StackAngle);
00058 float y = (float)Math.Cos((float)stack * StackAngle);
00059
00060 double lat = ((double)stack / (double)Stacks - 0.5) * 180.0;
00061 double v = EquirectangularProjection.latToY(lat);
00062
00063
00064 for (int slice = 0; slice < (Slices+1); slice++)
00065 {
00066 float x = r * (float)Math.Sin((float)slice * SliceAngle);
00067 float z = r * (float)Math.Cos((float)slice * SliceAngle);
00068 vertices[vertexcount].Position = new Vector3(x * Radius, y * Radius, z * Radius);
00069 vertices[vertexcount].Normal = Vector3.Normalize(new Vector3(x, y, z));
00070
00071 double lon = ((double)slice / (double)Slices) * 360.0;
00072 double u = 1.0 - EquirectangularProjection.lonToX(lon);
00073
00074 vertices[vertexcount].TextureCoordinate = new Vector2((float)u, (float)v);
00075
00076 vertexcount++;
00077 if (!(stack == (Stacks - 1)))
00078 {
00079 indices[indexcount] = vertexindex + (Slices + 1);
00080 indexcount++;
00081 indices[indexcount] = vertexindex + 1;
00082 indexcount++;
00083 indices[indexcount] = vertexindex;
00084 indexcount++;
00085 indices[indexcount] = vertexindex + (Slices);
00086 indexcount++;
00087 indices[indexcount] = vertexindex + (Slices + 1);
00088 indexcount++;
00089 indices[indexcount] = vertexindex;
00090 indexcount++;
00091 vertexindex++;
00092 }
00093 }
00094 }
00095
00096 vertexbuffer = new VertexBuffer(device, typeof(VertexPositionNormalTexture), nvertices, BufferUsage.None);
00097 vertexbuffer.SetData(vertices, 0, vertices.Length);
00098 indexbuffer = new IndexBuffer(device , typeof(int), numIndices, BufferUsage.None);
00099 indexbuffer.SetData(indices, 0, indices.Length);
00100
00101 this.effect = new BasicEffect(device, null);
00102 this.effect.Texture = texture;
00103 this.effect.Alpha = 1.0f;
00104 this.effect.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f);
00105 this.effect.SpecularColor = new Vector3(0.25f, 0.25f, 0.25f);
00106 this.effect.SpecularPower = 5.0f;
00107 this.effect.AmbientLightColor = new Vector3(0.75f, 0.75f, 0.75f);
00108 this.effect.TextureEnabled = true;
00109
00110 declaration = new VertexDeclaration(device, VertexPositionNormalTexture.VertexElements);
00111 strideSize = VertexPositionNormalTexture.SizeInBytes;
00112 }
00113
00121 public void Render(GraphicsDevice device, Matrix view, Matrix projection, Matrix sphereRollingMatrix, float alpha)
00122 {
00123 device.Indices = indexbuffer;
00124 device.VertexDeclaration = declaration;
00125 device.Vertices[0].SetSource(vertexbuffer, 0, strideSize);
00126 this.effect.World = sphereRollingMatrix;
00127 this.effect.Projection = projection;
00128 this.effect.View = view;
00129 this.effect.Alpha = alpha;
00130 this.effect.Begin();
00131
00132 foreach (EffectPass effectPass in this.effect.CurrentTechnique.Passes)
00133 {
00134 effectPass.Begin();
00135
00136 device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, nvertices, 0, nfaces);
00137
00138 effectPass.End();
00139 }
00140 this.effect.End();
00141 }
00142 }
00143 }