Imports System
Imports System.Drawing
Imports System.Windows.Forms
Imports Microsoft.WindowsMobile.DirectX
Imports Microsoft.WindowsMobile.DirectX.Direct3D
Imports Microsoft.VisualBasic
Class MeshPickingHowto
Inherits Form
Private Const numberOfMeshes As Integer = 9
Private meshes() As Mesh
Private meshColors() As Color = {Color.Green, Color.Orange, Color.Purple, Color.Pink, Color.Violet, Color.Blue, Color.Yellow, Color.Brown, Color.Aquamarine}
Private meshLocations() As Vector3
Private meshBoundingBoxMinValues() As Vector3
Private meshBoundingBoxMaxValues() As Vector3
Private activeMesh As Mesh
Private device As Device
Public Sub New()
Dim present As PresentParameters
Me.Text = "Mesh Picking"
' Enable the form to be closed.
' This is required so that Hwnd of the form changes.
Me.MinimizeBox = False
present = New PresentParameters()
present.Windowed = True
present.AutoDepthStencilFormat = DepthFormat.D16
present.EnableAutoDepthStencil = True
present.SwapEffect = SwapEffect.Discard
device = New Device(0, DeviceType.Default, Me, CreateFlags.None, present)
AddHandler device.DeviceReset, AddressOf OnDeviceReset
OnDeviceReset(Nothing, EventArgs.Empty)
End Sub
Private Sub OnDeviceReset(ByVal sender As Object, ByVal e As EventArgs)
' Meshes must be recreated whenever the device
' is reset, no matter which pool they are created in.
meshes = New Mesh(numberOfMeshes) {}
meshLocations = New Vector3(numberOfMeshes) {}
meshBoundingBoxMinValues = New Vector3(numberOfMeshes) {}
meshBoundingBoxMaxValues = New Vector3(numberOfMeshes) {}
activeMesh = Nothing
' Create several meshes and associated data.
Dim i As Integer
For i = 0 To numberOfMeshes
Dim vertexData As GraphicsStream
meshes(i) = Mesh.Box(device, 1F, 1F, 1F)
' Arrange the boxes in a grid, with each
' successive box farther in the distance.
meshLocations(i) = New Vector3((i Mod 3) * 2 - 2, i / 3 * 2 - 2, i)
' Compute the bounding box for a mesh.
Dim description As VertexBufferDescription = meshes(i).VertexBuffer.Description
vertexData = meshes(i).VertexBuffer.Lock(0, 0, LockFlags.ReadOnly)
Geometry.ComputeBoundingBox(vertexData, meshes(i).NumberVertices, description.VertexFormat, meshBoundingBoxMinValues(i), meshBoundingBoxMaxValues(i))
meshes(i).VertexBuffer.Unlock()
Next i
' Set the transformation matrices.
device.Transform.Projection = Matrix.PerspectiveFovRH(System.Convert.ToSingle(Math.PI) / 4F, System.Convert.ToSingle(Me.ClientSize.Width) / System.Convert.ToSingle(Me.ClientSize.Height), 0.001F, 40)
device.Transform.View = Matrix.LookAtRH(New Vector3(0, 2, - 7), New Vector3(0, 0, 0), New Vector3(0, 1, 0))
device.RenderState.Ambient = Color.White
End Sub
Protected Overrides Sub OnPaintBackground(ByVal e As PaintEventArgs)
' Do nothing.
End Sub
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Dim material As New Material()
' Begin the scene and clear the back buffer to black.
device.BeginScene()
device.Clear(ClearFlags.Target Or ClearFlags.ZBuffer, Color.Black, 1F, 0)
' Draw each mesh to the screen.
' The active mesh is drawn in red.
Dim i As Integer
For i = 0 To numberOfMeshes
If activeMesh Is meshes(i) Then
material.Ambient = Color.Red
Else
material.Ambient = meshColors(i)
End If
device.Transform.World = Matrix.Translation(meshLocations(i))
device.Material = material
meshes(i).DrawSubset(0)
Next i
' Finish the scene and present it on the screen.
device.EndScene()
device.Present()
End Sub
' This method demonstrates picking.
Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
' The technique used here is to create a ray through the entire
' logical 3-D space, and then perform an intersection test
' for the bounding box and ray.
Dim i As Integer
For i = 0 To numberOfMeshes
Dim nearVector As New Vector3(e.X, e.Y, 0)
Dim farVector As New Vector3(e.X, e.Y, 1)
' Create ray.
nearVector.Unproject(device.Viewport, device.Transform.Projection, device.Transform.View, Matrix.Translation(meshLocations(i)))
farVector.Unproject(device.Viewport, device.Transform.Projection, device.Transform.View, Matrix.Translation(meshLocations(i)))
farVector.Subtract(nearVector)
' Perform intersection test for the bounding box and ray.
If Geometry.BoxBoundProbe(meshBoundingBoxMinValues(i), meshBoundingBoxMaxValues(i), nearVector, farVector) Then
' Perform operation on detection of click on mesh object.
' In this case, you designate the mesh as the active
' mesh and invalidate the window so that it is redrawn.
activeMesh = meshes(i)
Me.Invalidate()
Exit For
End If
Next i
End Sub
Shared Sub Main()
Application.Run(New MeshPickingHowto())
End Sub
End Class