📄 world.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Reflection;
using System.IO;
using Microsoft.WindowsMobile.DirectX;
using Microsoft.WindowsMobile.DirectX.Direct3D;
using Microsoft.Samples.MD3DM;
using WorldWindow;
namespace cfWorldWind
{
class World
{
Mesh mesh = null;
Material meshMaterial;
Texture meshTexture;
Material outlineMaterial;
// Materials for the mesh
//Material[] meshMaterials;
// Textures for the mesh
//Texture[] meshTextures;
public World()
{
outlineMaterial = new Material();
outlineMaterial.Diffuse = Color.DarkOrange;
outlineMaterial.Ambient = Color.DarkOrange;
}
public void InitializeMesh(Device device)
{
//mesh = Mesh.Sphere(device, Settings.Radius, precision, precision); //will not take texture
//mesh = TexturedSphere(device, Settings.Radius, Settings.Precision, Settings.Precision); //LH from the web
//mesh = CreateMesh(device, Settings.Radius, Settings.Precision); //RH from WorldWind
Material[] outMaterials;
string[] outTextures;
string meshPath = "cfWorldWind.sphere.md3dm";
Stream meshStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(meshPath);
mesh = MeshLoader.LoadMesh(device, meshStream, MeshFlags.SystemMemory, out outMaterials, out outTextures);
meshStream.Close();
meshMaterial = new Material();
meshMaterial.Diffuse = Color.White;
meshMaterial.Ambient = Color.White;
//TextureRequirements texReq = new TextureRequirements();
//TextureLoader.CheckTextureRequirements(device, ref texReq);
//Format A1R5G5B5
//Height 1
//NumberMipLevels 1
//Pool SystemMemory
//Usage None
//Width 1
//TODO http://www.gotdotnet.com/Community/MessageBoard/Thread.aspx?id=310254
//Clone the mesh into a new mesh with a vertex format that contains texture coordinates
//Walk through the vertex buffer in the new mesh and assign sensible values to the u,v coordinates
//TODO get .DDS texture to work
//switched to .BMP for now
string textureFilename = Settings.PathBlueMarbleTexture;
meshTexture = TextureLoader.FromFile(device, textureFilename);
//meshTexture = TextureLoader.FromFile(device, textureFilename, 1024, 512, 1, Usage.None, Format.A1R5G5B5, Pool.VideoMemory, Filter.Linear, Filter.None, 0);
//device.RenderState.NormalizeNormals = true;
//device.RenderState.TexturePerspective = true;
}
public static Mesh TexturedSphere(Device device, float radius, int slices, int stacks)
{
int numVertices = (slices + 1) * (stacks + 1);
int numFaces = slices * stacks * 2;
int indexCount = numFaces * 3;// numVertices + (slices-1)*(stacks);
Mesh mesh = new Mesh(numFaces, numVertices, MeshFlags.Managed, CustomVertex.PositionNormalTextured.Format, device);
// Get the original sphere's vertex buffer.
//int[] ranks = new int[1];
//ranks[0] = mesh.NumberVertices;
int vertexCount = mesh.NumberVertices;
System.Array arr = mesh.VertexBuffer.Lock(0, typeof(CustomVertex.PositionNormalTextured), LockFlags.None, vertexCount);
// Set the vertex buffer
int vertIndex = 0;
for (int slice = 0; slice <= slices; slice++)
{
float alphaY = (float)slice / slices * (float)Math.PI * 2.0f; // Angle around Y-axis
float currentStack = stacks;
for (int stack = -(stacks + 1) / 2; stack <= (stacks + 1) / 2; stack++)
{
CustomVertex.PositionNormalTextured pnt = new CustomVertex.PositionNormalTextured();
float alphaZ = (float)stack / stacks * (float)Math.PI * 1.0f; // Angle around Z-axis.
//too small?
//pnt.X = (float)(Math.Cos(alphaY) * radius / 2.0f) * (float)Math.Cos(alphaZ);
//pnt.Z = (float)(Math.Sin(alphaY) * radius / 2.0f) * (float)Math.Cos(alphaZ);
//pnt.Y = (float)(Math.Sin(alphaZ) * radius / 2.0f);
pnt.X = (float)(Math.Cos(alphaY) * radius) * (float)Math.Cos(alphaZ);
//LH
//pnt.Z = (float)(Math.Sin(alphaY) * radius) * (float)Math.Cos(alphaZ);
//pnt.Y = (float)(Math.Sin(alphaZ) * radius);
//RH
pnt.Z = (float)(Math.Sin(alphaZ) * radius);
pnt.Y = (float)(Math.Sin(alphaY) * radius) * (float)Math.Cos(alphaZ);
pnt.Tu = 1f / slices * slice;
pnt.Tv = 1f / stacks * currentStack--;
//TODO set normals?
arr.SetValue(pnt, vertIndex++);
}
}
//mesh.VertexBuffer.SetData(arr, 0, LockFlags.None); //already locked exception
mesh.VertexBuffer.Unlock();
//ranks[0] = indexCount;
arr = mesh.IndexBuffer.Lock(0, typeof(short), LockFlags.None, indexCount);
int i = 0;
short leftVertex = 0;
short rightVertex = 0;
for (short x = 0; x < slices; x++)
//for (short x = (short)(slices-1); x >=0; x--)
{
leftVertex = (short)((stacks + 1) * x);
rightVertex = (short)(leftVertex + stacks + 1);
for (int y = 0; y < stacks; y++)
//for (int y = stacks-1; y >=0; y--)
{
//LH?
arr.SetValue(rightVertex, i++);
arr.SetValue(leftVertex, i++);
arr.SetValue((short)(leftVertex + 1), i++);
arr.SetValue(rightVertex, i++);
arr.SetValue((short)(leftVertex + 1), i++);
arr.SetValue((short)(rightVertex + 1), i++);
leftVertex++;
rightVertex++;
}
}
//mesh.IndexBuffer.SetData(arr, 0, LockFlags.None); //already locked exception
//mesh.ComputeNormals(); //TODO for lighting?
mesh.IndexBuffer.Unlock();
return mesh;
}
//private void createMesh()
public static Mesh CreateMesh(Device device, float layerRadius, int precision)
{
//CustomVertex.PositionColoredTextured[] vertexData;
//short[] indices;
float minLat = -90;
float maxLat = 90;
float minLon = -180;
float maxLon = 180;
//short[,] heightData = null;
float scaleFactor = (float)1 / precision;
float latrange = Math.Abs(maxLat - minLat);
float lonrange;
if(minLon < maxLon)
lonrange = Math.Abs(minLon - maxLon);
else
lonrange = 180.0f - minLon + 180.0f + maxLon;
int numVertices = (precision + 1) * (precision + 1);
int numFaces = precision * precision * 2;
Mesh mesh = new Mesh(numFaces, numVertices, MeshFlags.Managed, CustomVertex.PositionColoredTextured.Format, device);
int vertexCount = mesh.NumberVertices;
System.Array arr = mesh.VertexBuffer.Lock(0, typeof(CustomVertex.PositionColoredTextured), LockFlags.None, vertexCount);
int vertIndex = 0;
//vertexData = new CustomVertex.PositionColoredTextured[(precision+1) * (precision+1)];
for(int i = 0; i <= precision; i++)
{
for(int j = 0; j <= precision; j++)
{
CustomVertex.PositionColoredTextured pnt = new CustomVertex.PositionColoredTextured();
float height = 0;
height = 0;
Vector3 pos = MathEngine.SphericalToCartesian((float)maxLat - scaleFactor*latrange*i,minLon + (float)scaleFactor*lonrange*j, layerRadius + height);
//[i * (precision + 1) + j]
pnt.X = pos.X;
pnt.Y = pos.Y;
pnt.Z = pos.Z;
pnt.Tu = j * scaleFactor;
pnt.Tv = i * scaleFactor;
pnt.Color = Color.White.ToArgb();
arr.SetValue(pnt, vertIndex++);
}
}
mesh.VertexBuffer.Unlock();
int indexCount = 2 * precision * precision * 3; //numFaces * 3;
arr = mesh.IndexBuffer.Lock(0, typeof(short), LockFlags.None, indexCount);
//indices = new short[2 * precision * precision * 3];
for(int i = 0; i < precision; i++)
{
for(int j = 0; j < precision; j++)
{
arr.SetValue((short)(i * (precision + 1) + j),(2 * 3 * i * (precision)) + 6 * j); //indices[] = ;
arr.SetValue((short)((i+1)*(precision+1) + j),(2*3*i*(precision)) + 6*j + 1); //indices[] = ;
arr.SetValue((short)(i*(precision+1) + j+1),(2*3*i*(precision)) + 6*j + 2); //indices[] = ;
arr.SetValue((short)(i*(precision+1) + j+1),(2*3*i*(precision)) + 6*j + 3); //indices[] = ;
arr.SetValue((short)((i+1)*(precision+1) + j),(2*3*i*(precision)) + 6*j + 4); //indices[] = ;
arr.SetValue((short)((i+1)*(precision+1) + j+1),(2*3*i*(precision)) + 6*j + 5); //indices[] = ;
}
}
mesh.IndexBuffer.Unlock();
//FileStream fs = new FileStream(@"\My Documents\sphere.md3", FileMode.Create);
//MeshLoader.SaveMesh(fs, mesh, new Material[0], new string[0]);
//fs.Close();
return mesh;
}
public void RenderMesh(Device device)
{
device.Material = meshMaterial;
if (Settings.Texture == true)
{
device.SetTexture(0, meshTexture);
}
else
{
device.SetTexture(0, null);
}
mesh.DrawSubset(0);
//Mesh sphereMesh = Mesh.Sphere(device, Settings.Radius, 32, 32);
//sphereMesh.DrawSubset(0);
}
Texture defaultTexture;
string splitStr = ":";
char[] splitChar;
public void InitializeTiles(Device device)
{
splitChar = splitStr.ToCharArray();
//preload the default texture
string defaultTexturePath = Settings.DirectoryBlueMarbleTextures + "DefaultTexture.dds";
//string defaultTexturePath = Settings.DirectoryBlueMarbleTextures + "DefaultTexture.bmp";
defaultTexture = TextureLoader.FromFile(device, defaultTexturePath);
//TODO save this texture off to a PPC format
}
private bool levelChange = false;
public bool LevelChange
{
get
{
return levelChange;
}
}
int lastLevel = -1;
int lastRow = -1;
int lastCol = -1;
Dictionary<string, RenderTile> htRenderItems = new Dictionary<string, RenderTile>();
public void CalculateTiles(Device device, Camera camera)
{
int level = -1;
float tileSize = -1; //degrees
int numRows = -1;
int numCols = -1;
//if (camera.Altitude > 5700000)
if (camera.Altitude <= 10000000 && camera.Altitude > 5700000)
{
level = 0;
tileSize = 36;
numRows = 5;
numCols = 10;
}
if (camera.Altitude <= 5700000 && camera.Altitude > 3300000)
{
level = 1;
tileSize = 18;
numRows = 10;
numCols = 20;
}
if (camera.Altitude <= 3300000 && camera.Altitude > 1700000)
{
level = 2;
tileSize = 9;
numRows = 20;
numCols = 40;
}
if (camera.Altitude <= 1700000)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -