您的位置:首页 > 其它

[WorldWind学习]12.WavingFlags和WavingFlagLayer

2013-04-20 16:42 465 查看
WW目前的服务器似乎都连不上了,不知道Java版的是不是可以!

WW实现了旗帜标注,鼠标移动到旗帜的位置,旗帜会高亮显示。点击,探出对话框显示标注的信息。

1.WavingFlagLayer对象

public class WavingFlagLayer : RenderableObject

WavingFlagLayer继承自RenderableObject,定义了三个事件如下:

public event System.EventHandler OnMouseEnterEvent;
public event System.EventHandler OnMouseLeaveEvent;
public event System.Windows.Forms.MouseEventHandler OnMouseUpEvent;


string highlightTexturePath = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + "\\Data\\ring.dds";

//高亮显示采用的图片路径

该对象重点查看PerformSelectionAction(DrawArgs drawArgs)方法,重载了RenderableObject的PerformSelectionAction方法。

public override bool PerformSelectionAction(DrawArgs drawArgs)
{
Vector3 surfacePos = MathEngine.SphericalToCartesian(m_latitude, m_longitude, World.EquatorialRadius);
Vector3 rc = new Vector3(
(float)drawArgs.WorldCamera.ReferenceCenter.X,
(float)drawArgs.WorldCamera.ReferenceCenter.Y,
(float)drawArgs.WorldCamera.ReferenceCenter.Z
);
Vector3 projectedPoint = drawArgs.WorldCamera.Project(surfacePos - rc);
int mouseBuffer = 15;
if (projectedPoint.X > DrawArgs.LastMousePosition.X - mouseBuffer &&
12                     projectedPoint.X < DrawArgs.LastMousePosition.X + mouseBuffer &&
13                     projectedPoint.Y > DrawArgs.LastMousePosition.Y - mouseBuffer &&
14                     projectedPoint.Y < DrawArgs.LastMousePosition.Y + mouseBuffer)//通过包围盒判断是否选中,转换到屏幕坐标来判断
15             {
if (OnMouseUpEvent != null)//如果委托链不为空,执行事件委托链中的方法
{
OnMouseUpEvent(this, new System.Windows.Forms.MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 1, DrawArgs.LastMousePosition.X, DrawArgs.LastMousePosition.Y, 0));
}
return true;
}
return false;
}


2.WavingFlags是一个插件对象。

public class WavingFlags : WorldWind.PluginEngine.Plugin

WavingFlags的Load方法从文件中读取WavingFlagLayer信息,加载。绑定事件关联的方法。

/// <summary>
/// Plugin entry point - All plugins must implement this function
/// </summary>
public override void Load()
{
FileInfo savedFile = new FileInfo(SavedFilePath);
if (!savedFile.Exists)
{
if (!savedFile.Directory.Exists)
savedFile.Directory.Create();

try
{
WorldWind.Net.WebDownload download = new WorldWind.Net.WebDownload(DataFileUri);
download.DownloadFile(savedFile.FullName);
download.Dispose();
}
catch { }
}

m_wavingFlagsList = new RenderableObjectList("Waving Flags");
m_wavingFlagsList.IsOn = false;
System.Collections.Hashtable countryHash = new System.Collections.Hashtable();

using (StreamReader reader = savedFile.OpenText())
{
string header = reader.ReadLine();
string[] headers = header.Split('\t');

string line = reader.ReadLine();
while (line != null)
{
System.Collections.Hashtable fieldHash = new System.Collections.Hashtable();
string[] lineParts = line.Split('\t');

//Log.Write(string.Format("{0}\t{1}", lineParts[0], lineParts[1]));
try
{
double latitude = double.Parse(lineParts[3], System.Globalization.CultureInfo.InvariantCulture);
double longitude = double.Parse(lineParts[4], System.Globalization.CultureInfo.InvariantCulture);

if (lineParts[1].Length == 2)
{
string flagFileUri = FlagTextureDirectoryUri + "/" + lineParts[1] + FlagSuffix;
FileInfo savedFlagFile = new FileInfo(SavedFlagsDirectory + "\\" + lineParts[1] + ".dds");

WavingFlagLayer flag = new WavingFlagLayer(
48                                 lineParts[0],
49                                 ParentApplication.WorldWindow.CurrentWorld,
50                                 latitude,
51                                 longitude,
52                                 flagFileUri);

flag.SavedImagePath = savedFlagFile.FullName;
flag.ScaleX = 100000;
flag.ScaleY = 100000;
flag.ScaleZ = 100000;
flag.Bar3D = new Bar3D(flag.Name, flag.World, latitude, longitude, 0, flag.ScaleZ, System.Drawing.Color.Red);
flag.Bar3D.ScaleX = 0.3f * flag.ScaleX;
flag.Bar3D.ScaleY = 0.3f * flag.ScaleY;
flag.Bar3D.IsOn = false;
flag.RenderPriority = RenderPriority.Custom;

64                             flag.OnMouseEnterEvent += new EventHandler(flag_OnMouseEnterEvent);
65                             flag.OnMouseLeaveEvent += new EventHandler(flag_OnMouseLeaveEvent);
66                             flag.OnMouseUpEvent += new System.Windows.Forms.MouseEventHandler(flag_OnMouseUpEvent);
m_wavingFlagsList.Add(flag);

for (int i = 0; i < lineParts.Length; i++)
{
try
{
double value = double.Parse(lineParts[i], System.Globalization.CultureInfo.InvariantCulture);
fieldHash.Add(headers[i], value);
}
catch
{
fieldHash.Add(headers[i], lineParts[i]);
}
}
countryHash.Add(lineParts[0], fieldHash);
}
else
{
//Log.Write(Log.Levels.Debug, "blank: " + lineParts[0]);
}
}
catch(Exception ex)
{
Log.Write(Log.Levels.Warning, string.Format("Exception: {0} - {1}", lineParts[0], ex.ToString()));
}

line = reader.ReadLine();
}
Headers = headers;
}

CountryHash = countryHash;

InitializeCiaForm();

ParentApplication.WorldWindow.CurrentWorld.RenderableObjects.Add(m_wavingFlagsList);
}


WavingFlagLayer事件关联的方法。

void flag_OnMouseUpEvent(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (DrawArgs.NewRootWidget.OnMouseMove(e) || DrawArgs.RootWidget.OnMouseMove(e))
return;

m_ciaForm.Visible = true;
}

void flag_OnMouseLeaveEvent(object sender, EventArgs e)
{
WavingFlagLayer wavingFlag = (WavingFlagLayer)sender;
wavingFlag.ShowHighlight = false;

}

void flag_OnMouseEnterEvent(object sender, EventArgs e)
{
System.Windows.Forms.MouseEventArgs mea = new System.Windows.Forms.MouseEventArgs(
System.Windows.Forms.MouseButtons.None,
0,
DrawArgs.LastMousePosition.X,
DrawArgs.LastMousePosition.Y,
0);

// hack check to make sure that a widget isn't in the way
if (DrawArgs.NewRootWidget.OnMouseMove(mea) || DrawArgs.RootWidget.OnMouseMove(mea))
return;

WavingFlagLayer flag = (WavingFlagLayer)sender;
if (m_wavingFlagsList.IsOn && flag.Initialized && flag.IsOn)
{
ChangeForm(flag.Name, m_currentCategoryIndex);
//m_ciaForm.Visible = true;
}

for (int i = 0; i < m_wavingFlagsList.ChildObjects.Count; i++)
{
if (m_wavingFlagsList.ChildObjects[i] is WavingFlagLayer)
{
WavingFlagLayer wavingFlag = (WavingFlagLayer)m_wavingFlagsList.ChildObjects[i];
if (wavingFlag.Name != flag.Name)
wavingFlag.ShowHighlight = false;
else
wavingFlag.ShowHighlight = true;
}
}
}


该对象用到了Shader编程的知识,Effect类,需要具体查看。

private void RenderFlag(DrawArgs drawArgs, double offset)
{
if (m_effect == null)
{
string outerrors = "";
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
Stream effectStream = assembly.GetManifestResourceStream("WorldWind.Shaders.flag.fx");
m_effect =
Effect.FromStream(
drawArgs.device,
effectStream,
null,
null,
ShaderFlags.None,
null,
out outerrors);
if (outerrors != null && outerrors.Length > 0)
Log.Write(Log.Levels.Error, outerrors);
}
if (m_vertexBuffer == null)
{
drawArgs.device.DeviceReset += new EventHandler(device_DeviceReset);
device_DeviceReset(drawArgs.device, null);
}
if (m_flagPoleVertices == null)
{
CreateFlagPole(drawArgs.device);
}
Vector3 pos =
MathEngine.SphericalToCartesian(m_latitude, m_longitude, World.EquatorialRadius + World.Settings.VerticalExaggeration * ScaleZ + offset);
Vector3 surfacePos = MathEngine.SphericalToCartesian(m_latitude, m_longitude, World.EquatorialRadius + offset);
Vector3 rc = new Vector3(
(float)drawArgs.WorldCamera.ReferenceCenter.X,
(float)drawArgs.WorldCamera.ReferenceCenter.Y,
(float)drawArgs.WorldCamera.ReferenceCenter.Z
);
drawArgs.device.Transform.World = Matrix.Scaling(World.Settings.VerticalExaggeration * ScaleX * 0.01f, World.Settings.VerticalExaggeration * ScaleY * 0.01f, -World.Settings.VerticalExaggeration * 2 * ScaleZ);
drawArgs.device.Transform.World *= Matrix.RotationY((float)-MathEngine.DegreesToRadians(90));
drawArgs.device.Transform.World *= Matrix.RotationY((float)-MathEngine.DegreesToRadians(m_latitude));
drawArgs.device.Transform.World *= Matrix.RotationZ((float)MathEngine.DegreesToRadians(m_longitude));
drawArgs.device.Transform.World *= Matrix.Translation(surfacePos - rc);
drawArgs.device.VertexFormat = CustomVertex.PositionColored.Format;
drawArgs.device.TextureState[0].ColorOperation = TextureOperation.SelectArg1;
drawArgs.device.TextureState[0].ColorArgument1 = TextureArgument.Diffuse;
drawArgs.device.TextureState[0].AlphaArgument1 = TextureArgument.Diffuse;
drawArgs.device.TextureState[0].AlphaOperation = TextureOperation.SelectArg1;
drawArgs.device.DrawIndexedUserPrimitives(PrimitiveType.TriangleList, 0, m_flagPoleVertices.Length, m_flagPoleIndices.Length / 3, m_flagPoleIndices, true, m_flagPoleVertices);
drawArgs.device.DrawIndexedUserPrimitives(PrimitiveType.LineList, 0, m_outlineFlagPoleVertices.Length, m_outlineFlagPoleIndices.Length / 2, m_outlineFlagPoleIndices, true, m_outlineFlagPoleVertices);
m_angle += .04f;
if (m_angle > 360)
m_angle = 0;
drawArgs.device.VertexFormat = CustomVertex.PositionNormalTextured.Format;
drawArgs.device.Transform.World = Matrix.Scaling(World.Settings.VerticalExaggeration * ScaleX, World.Settings.VerticalExaggeration * ScaleY, World.Settings.VerticalExaggeration * ScaleZ);
drawArgs.device.Transform.World *= Matrix.RotationY((float)-MathEngine.DegreesToRadians(m_latitude));
drawArgs.device.Transform.World *= Matrix.RotationZ((float)MathEngine.DegreesToRadians(m_longitude));
drawArgs.device.Transform.World *= Matrix.Translation(pos - rc);

Matrix worldViewProj = drawArgs.device.Transform.World * drawArgs.device.Transform.View * drawArgs.device.Transform.Projection;
System.DateTime currentTime = TimeKeeper.CurrentTimeUtc;
Point3d sunPosition = SunCalculator.GetGeocentricPosition(currentTime);
Vector3 sunVector = new Vector3(
(float)-sunPosition.X,
(float)-sunPosition.Y,
(float)-sunPosition.Z);
m_effect.Technique = "VertexAndPixelShader";
m_effect.SetValue("angle", (float)m_angle);
m_effect.SetValue("attentuation", Attentuation);
m_effect.SetValue("World", drawArgs.device.Transform.World);
m_effect.SetValue("View", drawArgs.device.Transform.View);
m_effect.SetValue("Projection", drawArgs.device.Transform.Projection);
m_effect.SetValue("Tex0", m_texture);
m_effect.SetValue("lightDir", new Vector4(sunVector.X, sunVector.Y, sunVector.Z, 0));
drawArgs.device.Indices = m_indexBuffer;
drawArgs.device.SetStreamSource(0, m_vertexBuffer, 0);
int numPasses = m_effect.Begin(0);
for (int i = 0; i < numPasses; i++)
{
m_effect.BeginPass(i);
drawArgs.device.DrawIndexedPrimitives(
PrimitiveType.TriangleList,
0,
0,
m_vertices.Length,
0,
m_indices.Length / 3);
m_effect.EndPass();
}
m_effect.End();
drawArgs.device.Indices = null;
drawArgs.device.Transform.World = drawArgs.WorldCamera.WorldMatrix;
drawArgs.device.Transform.View = drawArgs.WorldCamera.ViewMatrix;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: