[WorldWind学习]12.WavingFlags和WavingFlagLayer

WW目前的服务器似乎都连不上了,不知道Java版的是不是可以!

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

1.WavingFlagLayer对象

public class WavingFlagLayer : RenderableObject

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

1         public event System.EventHandler OnMouseEnterEvent; 2         public event System.EventHandler OnMouseLeaveEvent; 3         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方法。

 1 public override bool PerformSelectionAction(DrawArgs drawArgs)

 2         {

 3             Vector3 surfacePos = MathEngine.SphericalToCartesian(m_latitude, m_longitude, World.EquatorialRadius);

 4             Vector3 rc = new Vector3(

 5                 (float)drawArgs.WorldCamera.ReferenceCenter.X,

 6                 (float)drawArgs.WorldCamera.ReferenceCenter.Y,

 7                 (float)drawArgs.WorldCamera.ReferenceCenter.Z

 8                 );

 9             Vector3 projectedPoint = drawArgs.WorldCamera.Project(surfacePos - rc);

10             int mouseBuffer = 15;

11             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             {

16                 if (OnMouseUpEvent != null)//如果委托链不为空,执行事件委托链中的方法

17                 {

18                     OnMouseUpEvent(this, new System.Windows.Forms.MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 1, DrawArgs.LastMousePosition.X, DrawArgs.LastMousePosition.Y, 0));

19                 }

20                 return true;

21             }

22             return false;

23         }

2.WavingFlags是一个插件对象。

public class WavingFlags : WorldWind.PluginEngine.Plugin

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

  1   /// <summary>

  2         /// Plugin entry point - All plugins must implement this function

  3         /// </summary>

  4         public override void Load()

  5         {

  6             FileInfo savedFile = new FileInfo(SavedFilePath);

  7             if (!savedFile.Exists)

  8             {

  9                 if (!savedFile.Directory.Exists)

 10                     savedFile.Directory.Create();

 11 

 12                 try

 13                 {

 14                     WorldWind.Net.WebDownload download = new WorldWind.Net.WebDownload(DataFileUri);

 15                     download.DownloadFile(savedFile.FullName);

 16                     download.Dispose();

 17                 }

 18                 catch { }

 19             }

 20 

 21             m_wavingFlagsList = new RenderableObjectList("Waving Flags");

 22             m_wavingFlagsList.IsOn = false;

 23             System.Collections.Hashtable countryHash = new System.Collections.Hashtable();

 24 

 25             using (StreamReader reader = savedFile.OpenText())

 26             {

 27                 string header = reader.ReadLine();

 28                 string[] headers = header.Split('\t');

 29 

 30                 string line = reader.ReadLine();

 31                 while (line != null)

 32                 {

 33                     System.Collections.Hashtable fieldHash = new System.Collections.Hashtable();

 34                     string[] lineParts = line.Split('\t');

 35 

 36                     //Log.Write(string.Format("{0}\t{1}", lineParts[0], lineParts[1]));

 37                     try

 38                     {

 39                         double latitude = double.Parse(lineParts[3], System.Globalization.CultureInfo.InvariantCulture);

 40                         double longitude = double.Parse(lineParts[4], System.Globalization.CultureInfo.InvariantCulture);

 41 

 42                         if (lineParts[1].Length == 2)

 43                         {

 44                             string flagFileUri = FlagTextureDirectoryUri + "/" + lineParts[1] + FlagSuffix;

 45                             FileInfo savedFlagFile = new FileInfo(SavedFlagsDirectory + "\\" + lineParts[1] + ".dds");

 46 

 47                             WavingFlagLayer flag = new WavingFlagLayer(

 48                                 lineParts[0],

 49                                 ParentApplication.WorldWindow.CurrentWorld,

 50                                 latitude,

 51                                 longitude,

 52                                 flagFileUri);

 53 

 54                             flag.SavedImagePath = savedFlagFile.FullName;

 55                             flag.ScaleX = 100000;

 56                             flag.ScaleY = 100000;

 57                             flag.ScaleZ = 100000;

 58                             flag.Bar3D = new Bar3D(flag.Name, flag.World, latitude, longitude, 0, flag.ScaleZ, System.Drawing.Color.Red);

 59                             flag.Bar3D.ScaleX = 0.3f * flag.ScaleX;

 60                             flag.Bar3D.ScaleY = 0.3f * flag.ScaleY;

 61                             flag.Bar3D.IsOn = false;

 62                             flag.RenderPriority = RenderPriority.Custom;

 63 

 64                             flag.OnMouseEnterEvent += new EventHandler(flag_OnMouseEnterEvent);

 65                             flag.OnMouseLeaveEvent += new EventHandler(flag_OnMouseLeaveEvent);

 66                             flag.OnMouseUpEvent += new System.Windows.Forms.MouseEventHandler(flag_OnMouseUpEvent);

 67                             m_wavingFlagsList.Add(flag);

 68 

 69                             for (int i = 0; i < lineParts.Length; i++)

 70                             {

 71                                 try

 72                                 {

 73                                     double value = double.Parse(lineParts[i], System.Globalization.CultureInfo.InvariantCulture);

 74                                     fieldHash.Add(headers[i], value);

 75                                 }

 76                                 catch

 77                                 {

 78                                     fieldHash.Add(headers[i], lineParts[i]);

 79                                 }

 80                             }

 81                             countryHash.Add(lineParts[0], fieldHash);

 82                         }

 83                         else

 84                         {

 85                             //Log.Write(Log.Levels.Debug, "blank: " + lineParts[0]);

 86                         }

 87                     }

 88                     catch(Exception ex)

 89                     {

 90                         Log.Write(Log.Levels.Warning, string.Format("Exception: {0} - {1}", lineParts[0], ex.ToString()));

 91                     }

 92 

 93                     line = reader.ReadLine();

 94                 }

 95                 Headers = headers;

 96             }

 97             

 98             CountryHash = countryHash;

 99             

100             InitializeCiaForm();

101 

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

103         }

 WavingFlagLayer事件关联的方法。

 1  void flag_OnMouseUpEvent(object sender, System.Windows.Forms.MouseEventArgs e)

 2         {

 3             if (DrawArgs.NewRootWidget.OnMouseMove(e) || DrawArgs.RootWidget.OnMouseMove(e))

 4                 return;

 5 

 6             m_ciaForm.Visible = true;

 7         }

 8 

 9         void flag_OnMouseLeaveEvent(object sender, EventArgs e)

10         {

11             WavingFlagLayer wavingFlag = (WavingFlagLayer)sender;

12             wavingFlag.ShowHighlight = false;

13             

14         }

15 

16         void flag_OnMouseEnterEvent(object sender, EventArgs e)

17         {

18             System.Windows.Forms.MouseEventArgs mea = new System.Windows.Forms.MouseEventArgs(

19                 System.Windows.Forms.MouseButtons.None,

20                 0, 

21                 DrawArgs.LastMousePosition.X, 

22                 DrawArgs.LastMousePosition.Y, 

23                 0);

24 

25             // hack check to make sure that a widget isn't in the way

26             if (DrawArgs.NewRootWidget.OnMouseMove(mea) || DrawArgs.RootWidget.OnMouseMove(mea))

27                 return;

28 

29             WavingFlagLayer flag = (WavingFlagLayer)sender;

30             if (m_wavingFlagsList.IsOn && flag.Initialized && flag.IsOn)

31             {

32                 ChangeForm(flag.Name, m_currentCategoryIndex);

33                 //m_ciaForm.Visible = true;

34             }

35 

36             for (int i = 0; i < m_wavingFlagsList.ChildObjects.Count; i++)

37             {

38                 if (m_wavingFlagsList.ChildObjects[i] is WavingFlagLayer)

39                 {

40                     WavingFlagLayer wavingFlag = (WavingFlagLayer)m_wavingFlagsList.ChildObjects[i];

41                     if (wavingFlag.Name != flag.Name)

42                         wavingFlag.ShowHighlight = false;

43                     else

44                         wavingFlag.ShowHighlight = true;

45                 }

46             }

47         }

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

 1  private void RenderFlag(DrawArgs drawArgs, double offset)

 2         {

 3             if (m_effect == null)

 4             {

 5                 string outerrors = "";

 6                 System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();

 7                 Stream effectStream = assembly.GetManifestResourceStream("WorldWind.Shaders.flag.fx");

 8                 m_effect =

 9                     Effect.FromStream(

10                     drawArgs.device,

11                     effectStream,

12                     null,

13                     null,

14                     ShaderFlags.None,

15                     null,

16                     out outerrors);

17                 if (outerrors != null && outerrors.Length > 0)

18                     Log.Write(Log.Levels.Error, outerrors);

19             }

20             if (m_vertexBuffer == null)

21             {

22                 drawArgs.device.DeviceReset += new EventHandler(device_DeviceReset);

23                 device_DeviceReset(drawArgs.device, null);

24             }

25             if (m_flagPoleVertices == null)

26             {

27                 CreateFlagPole(drawArgs.device);

28             }

29             Vector3 pos =

30                         MathEngine.SphericalToCartesian(m_latitude, m_longitude, World.EquatorialRadius + World.Settings.VerticalExaggeration * ScaleZ + offset);

31             Vector3 surfacePos = MathEngine.SphericalToCartesian(m_latitude, m_longitude, World.EquatorialRadius + offset);

32             Vector3 rc = new Vector3(

33                 (float)drawArgs.WorldCamera.ReferenceCenter.X,

34                 (float)drawArgs.WorldCamera.ReferenceCenter.Y,

35                 (float)drawArgs.WorldCamera.ReferenceCenter.Z

36                 );

37             drawArgs.device.Transform.World = Matrix.Scaling(World.Settings.VerticalExaggeration * ScaleX * 0.01f, World.Settings.VerticalExaggeration * ScaleY * 0.01f, -World.Settings.VerticalExaggeration * 2 * ScaleZ);

38             drawArgs.device.Transform.World *= Matrix.RotationY((float)-MathEngine.DegreesToRadians(90));

39             drawArgs.device.Transform.World *= Matrix.RotationY((float)-MathEngine.DegreesToRadians(m_latitude));

40             drawArgs.device.Transform.World *= Matrix.RotationZ((float)MathEngine.DegreesToRadians(m_longitude));

41             drawArgs.device.Transform.World *= Matrix.Translation(surfacePos - rc);

42             drawArgs.device.VertexFormat = CustomVertex.PositionColored.Format;

43             drawArgs.device.TextureState[0].ColorOperation = TextureOperation.SelectArg1;

44             drawArgs.device.TextureState[0].ColorArgument1 = TextureArgument.Diffuse;

45             drawArgs.device.TextureState[0].AlphaArgument1 = TextureArgument.Diffuse;

46             drawArgs.device.TextureState[0].AlphaOperation = TextureOperation.SelectArg1;

47             drawArgs.device.DrawIndexedUserPrimitives(PrimitiveType.TriangleList, 0, m_flagPoleVertices.Length, m_flagPoleIndices.Length / 3, m_flagPoleIndices, true, m_flagPoleVertices);

48             drawArgs.device.DrawIndexedUserPrimitives(PrimitiveType.LineList, 0, m_outlineFlagPoleVertices.Length, m_outlineFlagPoleIndices.Length / 2, m_outlineFlagPoleIndices, true, m_outlineFlagPoleVertices);

49             m_angle += .04f;

50             if (m_angle > 360)

51                 m_angle = 0;

52             drawArgs.device.VertexFormat = CustomVertex.PositionNormalTextured.Format;

53             drawArgs.device.Transform.World = Matrix.Scaling(World.Settings.VerticalExaggeration * ScaleX, World.Settings.VerticalExaggeration * ScaleY, World.Settings.VerticalExaggeration * ScaleZ);

54             drawArgs.device.Transform.World *= Matrix.RotationY((float)-MathEngine.DegreesToRadians(m_latitude));

55             drawArgs.device.Transform.World *= Matrix.RotationZ((float)MathEngine.DegreesToRadians(m_longitude));

56             drawArgs.device.Transform.World *= Matrix.Translation(pos - rc);

57 

58             Matrix worldViewProj = drawArgs.device.Transform.World * drawArgs.device.Transform.View * drawArgs.device.Transform.Projection;

59             System.DateTime currentTime = TimeKeeper.CurrentTimeUtc;

60             Point3d sunPosition = SunCalculator.GetGeocentricPosition(currentTime);

61             Vector3 sunVector = new Vector3(

62                 (float)-sunPosition.X,

63                 (float)-sunPosition.Y,

64                 (float)-sunPosition.Z);

65             m_effect.Technique = "VertexAndPixelShader";

66             m_effect.SetValue("angle", (float)m_angle);

67             m_effect.SetValue("attentuation", Attentuation);

68             m_effect.SetValue("World", drawArgs.device.Transform.World);

69             m_effect.SetValue("View", drawArgs.device.Transform.View);

70             m_effect.SetValue("Projection", drawArgs.device.Transform.Projection);

71             m_effect.SetValue("Tex0", m_texture);

72             m_effect.SetValue("lightDir", new Vector4(sunVector.X, sunVector.Y, sunVector.Z, 0));

73             drawArgs.device.Indices = m_indexBuffer;

74             drawArgs.device.SetStreamSource(0, m_vertexBuffer, 0);

75             int numPasses = m_effect.Begin(0);

76             for (int i = 0; i < numPasses; i++)

77             {

78                 m_effect.BeginPass(i);

79                 drawArgs.device.DrawIndexedPrimitives(

80                     PrimitiveType.TriangleList,

81                     0,

82                     0,

83                     m_vertices.Length,

84                     0,

85                     m_indices.Length / 3);

86                 m_effect.EndPass();

87             }

88             m_effect.End();

89             drawArgs.device.Indices = null;

90             drawArgs.device.Transform.World = drawArgs.WorldCamera.WorldMatrix;

91             drawArgs.device.Transform.View = drawArgs.WorldCamera.ViewMatrix;

92         }
View Code

 

你可能感兴趣的:(flag)