Click Here!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Cutting Edge Direct 3D Programming
(Publisher: The Coriolis Group)
Author(s): Stan Trujillo
ISBN: 1576100502
Publication Date: 11/01/96

Bookmark It

Search this book:
 
Previous Table of Contents Next


The FacePickWin::PickFace() Function

The PickFace() function uses the Direct3DRMViewport Pick() function to perform the actual picking operation. If an object is returned as a result of the picking operation, its face index is returned. The PickFace() function looks like this:

int FacePickWin::PickFace( const CPoint& point )
{
    HRESULT r;
    LPDIRECT3DRMPICKEDARRAY pickarray;

    viewport->Pick( point.x, point.y, &pickarray );

    int faceindex=-1;
    DWORD numpicks=pickarray->GetSize();
    if (numpicks>0)
    {
        LPDIRECT3DRMVISUAL visual;
        LPDIRECT3DRMFRAMEARRAY framearray;
        D3DRMPICKDESC pickdesc;

        r=pickarray->GetPick( 0, &visual, &framearray, &pickdesc );
        if (r==D3DRM_OK)
        {
            faceindex=pickdesc.ulFaceIdx;
            visual->Release();
            framearray->Release();
        }
    }
    pickarray->Release();
    return faceindex;
}

First, the Direct3DRMViewport Pick() function is called. The function takes the mouse cursor location as the first two arguments. The third argument is the address of a pointer to the Direct3DRMPickedArray interface.

Next, the GetSize() function is used to determine if any objects were picked. If the array is empty, the pickarray pointer is released, and the function returns -1. If there are items in the array, the first is extracted with the GetPick() function. We only need the first item because the array is sorted by Z order, and we are only interesting in the object closest to the viewer.

The GetPick() function initializes two pointers and a structure. The first pointer points to the visual object that was picked. In our case, the visual pointer will point to the mesh that was created in the CreateScene() function (because the mesh is the scene’s only visual object). We are not, however, interested in a pointer to the visual object. We would be if the scene contained multiple meshes (as with the MeshPick demo). The second pointer that GetPick() initializes is a pointer to an array of frames. We aren’t interested in this data either, for the same reasons that we aren’t interested in the pointer to the visual object.

The data that we need is the index of the face that was picked. The GetPick() function stores this value in the ulFaceIdx field of the D3DRMPICKDESC structure. The PickFace() function stores and returns this value after releasing its local pointers, thereby completing its task.

Incidentally, the D3DRMPICKDESC structure contains two other fields that might be of use:

  lGroupIdx: Indicates the face’s group index. The Direct3DRMMesh interface supports multiple groups of faces. The group index identifies the group to which the selected face belongs.
  vPosition: The orientation of the face. This vector indicates the facing direction of the selected face.

The FacePickWin::UpdateDrag() Function

The UpdateDrag() function is a callback that is installed by the CreateScene() function. UpdateDrag() is responsible for calculating new rotation attributes for the mesh during drag operations. The function looks like this:

void FacePickWin::UpdateDrag(LPDIRECT3DRMFRAME frame, void*, D3DVALUE)
{
    if (drag)
    {
        double delta_x = GetMouseX() - last_x;
        double delta_y = GetMouseY() - last_y;
        last_x = GetMouseX();
        last_y = GetMouseY();
        double delta_r = sqrt( delta_x * delta_x + delta_y * delta_y );
        double radius = 50;
        double denom = sqrt( radius * radius + delta_r * delta_r );

        if (!(delta_r == 0 || denom == 0))
            frame->SetRotation( 0,
                    D3DDivide( -delta_y, delta_r ),
                    D3DDivide( -delta_x, delta_r ),
                    D3DVALUE(0.0),
                    D3DDivide( delta_r, denom) );
    }

    if (end_drag)
    {
        drag=FALSE;
        end_drag=FALSE;
    }
}

The function uses the current mouse position and the position of the mouse when the drag sequence was initiated to calculate a rotation vector and a rotation speed. In essence, the two-dimensional mouse movement data is converted into a vector, while the difference between the old and new mouse positions is used to calculate a rotation speed. These values are installed using the Direct3DRMFrame SetRotation() function.

Notice that each time the UpdateDrag() function is called, it checks the end_drag flag. This is the flag that is set by the OnLButtonUp() function to indicate that the drag operation should be terminated. If the end_drag flag is set, the drag operation is terminated.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited.