Compartilhar via


Como: Exibir e selecionar malhas

Você pode criar e exibir uma matriz de malhas de modo que quando uma malha é selecionada (clicada) no dispositivo, ela altera de cor.

Observação:

M Direct3D gerenciado aplicação obile cations exigem v do Windows Mobile software ersion 5.0 para Pocket PCs e Smartphones.Consulte Recursos externos para o .NET Compact Framework Para obter informações sobre o software Windows Mobile e SDKs.

O formulário para este exemplo de código possui os seguintes objetos:

  • A Mesh objeto para a malha ativo.

  • Uma matriz de nove Mesh objetos de várias cores que podem ser selecionadas.

  • A Vector3 estrutura que define os locais de malha.

  • Two Vector3 estruturas que definem a caixa delimitadora.

  • A Device objeto.

O construtor do formulário especifica as configurações do dispositivo de PresentationParameters propriedade, cria o Device objeto, adiciona o OnDeviceReset manipulador de eventos para o dispositivo DeviceReset evento e, em seguida, chama o OnDeviceReset método para começar a criar as malhas. A tabela a seguir descreve os métodos que desenham as malhas e permitem interação com o usuário.

Método

Ações

OnDeviceReset

Cria as malhas, as coloca nos locais na caixa delimitadora, e define as matrizes de transformação.

OnPaint

Começa a cena, desenha as malhas, e termina cena.

OnMouseDown

Demonstra a separação de uma malha usando uma técnica que cria um raio através do espaço lógico 3D e faz uma interseção caixa-ray.

O ray representa pressionando a caneta através do espaço 3D.A caixa representa uma caixa delimitadora ao redor do objeto 3D.Se os dois se interceptam, o usuário clicou em um local que contém o objeto 3D.

Exemplo

O exemplo de código a seguir fornece um formulário completo.Ele exibe Mesh objetos de várias cores que podem ser selecionadas. Quando uma malha é selecionada, a sua cor altera.

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
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.WindowsMobile.DirectX;
using Microsoft.WindowsMobile.DirectX.Direct3D;

namespace MeshPick
{
    class MeshPickingHowto : Form
    {
        const int numberOfMeshes = 9;
        Mesh [] meshes;
        Color [] meshColors = new Color [] { Color.Green, Color.Orange,
            Color.Purple, Color.Pink, Color.Violet, Color.Blue, Color.Yellow,
            Color.Brown, Color.Aquamarine };

        Vector3 [] meshLocations;
        Vector3 [] meshBoundingBoxMinValues;
        Vector3 [] meshBoundingBoxMaxValues;
        Mesh activeMesh;

        Device device;

        public MeshPickingHowto()
        {
            PresentParameters present;

            this.Text = "Mesh Picking";

            // Enable the form to be closed.
            // This is required so that Hwnd of the form changes.
            this.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, this,
                                CreateFlags.None, present);
            device.DeviceReset += new EventHandler(OnDeviceReset);
            OnDeviceReset(null, EventArgs.Empty);
        }

        private void OnDeviceReset(object sender, EventArgs e)
        {
            // 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 = null;
            // Create several meshes and associated data.
            for (int i = 0; i < numberOfMeshes; i++)
            {
                GraphicsStream vertexData;

                meshes[i] = Mesh.Box(device, 1.0f, 1.0f, 1.0f);

                // Arrange the boxes in a grid, with each
                // successive box farther in the distance.
                meshLocations[i] = new Vector3(((i % 3) * 2) - 2,
                                            ((i / 3) * 2) - 2, i);

                // Compute the bounding box for a mesh.
                VertexBufferDescription description =
                    meshes[i].VertexBuffer.Description;
                vertexData = meshes[i].VertexBuffer.Lock
                                         (0, 0, LockFlags.ReadOnly);
                Geometry.ComputeBoundingBox(vertexData,
                    meshes[i].NumberVertices,description.VertexFormat,
                    out meshBoundingBoxMinValues[i],
                    out meshBoundingBoxMaxValues[i]);
                meshes[i].VertexBuffer.Unlock();
            }
            // Set the transformation matrices.
            device.Transform.Projection = Matrix.PerspectiveFovRH(
               (float)Math.PI/4.0F,
               (float)this.ClientSize.Width / (float)this.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;
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            // Do nothing.
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Material material = new Material();

            // Begin the scene and clear the back buffer to black.
            device.BeginScene();
            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer,
                        Color.Black, 1.0f, 0);

            // Draw each mesh to the screen.
            // The active mesh is drawn in red.
            for (int i = 0; i < numberOfMeshes; i++)
            {
                if (activeMesh == meshes[i])
                    material.Ambient = Color.Red;
                else
                    material.Ambient = meshColors[i];

                device.Transform.World = Matrix.Translation(meshLocations[i]);
                device.Material = material;
                meshes[i].DrawSubset(0);
            }

            // Finish the scene and present it on the screen.
            device.EndScene();
            device.Present();
        }

        // This method demonstrates picking.
        protected override void OnMouseDown(MouseEventArgs e)
        {
            // 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.
            for (int i = 0; i < numberOfMeshes; i++)
            {
                Vector3 nearVector = new Vector3(e.X, e.Y, 0);
                Vector3 farVector = 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))
                {
                    // 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];
                    this.Invalidate();
                    break;
                }
            }
        }

        static void Main()
        {
            Application.Run(new MeshPickingHowto());
        }
    }
}

Compilando o código

Este exemplo requer referências aos seguintes namespaces:

Consulte também

Conceitos

Tópicos "como" do .NET compact estrutura

Outros recursos

Programação Direct3D móvel no .NET Compact estrutura