我要发帖 回复

正式会员

22

主题

85

积分

0

专家分

:

私信
发表时间 : 2007-10-30 17:28:47 | 浏览 : 2876    评论 : 14
我实现了游戏摇杆控制视角的平移和旋转,我想进一步实现游戏摇杆控制视角围绕视野中心点所指的模型点旋转
操作步骤是这样的:
    按摇杆上的某个按键,选取视野中心的模型点坐标(我可以实现)
    前后左右摇动摇杆让视野围绕选取的点坐标做原周运动(我可以得到视野中心线和坐标轴的夹角)
如何设置观察者的位置和角度信息来达到这一效果?有没有什么计算公式或者现成函数可以调用?

最近VR访客

morty 评论于2007-10-30 17:30:47
游戏摇杆的控制我已经会了,我已经能采集到游戏摇杆的数据了
obuil 评论于2007-10-30 17:51:36
相关已有的体会的可以发上来和大家分享一下嘛

另外 围绕选取点的旋转 这个不难

就是几个三角函数计算


我前年实现的绕指定物体旋转的部分代码 复制了过来 仅供参考:

dH=vgGetAtan2(intersection[0]-g_Position.x,intersection[1]-g_Position.y);
dP=vgGetAtan2(intersection[2]-g_Position.z,Dis);
Dis=vgGet2DRng(intersection[0]-g_Position.x,intersection[1]-g_Position.y);
vgGetSinCos(circH,&xsin,&xcos);
g_Position.x=intersection[0]+Dis*xsin;
g_Position.y=intersection[1]-Dis*xcos;
morty 评论于2007-10-31 09:39:21
谢谢obuil老大
下面是实现采集游戏摇杆数据的代码,不过这是一个前辈写的,我也不是非常清楚其中细节
---------------------------------------------------
HJoyStick.h文件
#pragma once

#ifndef  __HJOYSTICK_H__
#define  __HJOYSTICK_H__

#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")

#endif


//定义当前系统中支持的游戏杆数量,当前系统支持一个游戏杆
enum  JoyStickDevice
{
        JoyStickDevice = 1,
};

//定义游戏杆POV的状态类型
enum  JoyStickPOV
{
        Middle = 0,
        Header,
        Back,
        Left,
        Right
};

enum  JoyStickButton
{
        PutUp,
        PutDown
};

class HJoyStickDevice
{
public:
        int           POV1;
        bool          POVState1;
        int           POV2;
        bool          POVState2;
        int           POV3;
        bool          POVState3;
        int           POV4;
        bool          POVState4;

        JoyStickButton    Button[20];
        bool              ButtonState[20];

        int        PosX;
        bool       PosXState;
        int        PosY;
        bool       PosYState;
        int        PosZ;
        bool       PosZState;

        int        RotX;
        bool       RotXState;
        int        RotY;
        bool       RotYState;
        int        RotZ;
        bool       RotZState;

        int        Slider0;
        bool       Slider0State;
        int        Slider1;
        bool       Slider1State;

public:
    HJoyStickDevice(void);
};

HRESULT InitDirectInput( HWND hDlg,int*  JoyStickNum  );
VOID    FreeDirectInput();
int     GetAyatemJoyAtick( void );
HJoyStickDevice*  UpdateInputState( void );
----------------------------------------------------
HJoyStick.cpp文件
#define STRICT
#include "StdAfx.h"

#define DIRECTINPUT_VERSION 0x0800

#include <windows.h>
#include <commctrl.h>
#include <basetsd.h>
#include <dinput.h>

#include "hjoystick.h"

BOOL CALLBACK    EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext );
BOOL CALLBACK    EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext );
HRESULT InitDirectInput( HWND hDlg,int*  JoyStickNum );
VOID    FreeDirectInput();
int     g_SystemJoyStickNumber = 0;

//-----------------------------------------------------------------------------
// Defines, constants, and global variables
//-----------------------------------------------------------------------------
#define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }

LPDIRECTINPUT8           g_pDI              = NULL;         
LPDIRECTINPUTDEVICE8     g_pJoystick        = NULL;         


HJoyStickDevice    g_JoyStickDevice;




DEFINE_GUID(IID_IDirectInput8W_LWQ,    0xBF798031,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00);
#define DI8DEVCLASS_GAMECTRL_LWQ        4




HJoyStickDevice::HJoyStickDevice(void)
{
        POV1 = 0;
        POVState1 = false;

        POV2 = 0;
        POVState2 = false;

        POV2 = 0;
        POVState2 = false;;
   
        for( int i = 0;i < 20;i++ )
        {
          Button = PutUp;
          ButtonState = false;
        }

        PosX = -8;
        PosXState = false;
        PosY = -8;
        PosYState = false;
        PosZ = -8;
        PosZState = false;

        RotX = 0;
    RotXState = false;

        RotY = 0;
        RotYState = false;

        RotZ = 0;
        RotZState = false;

        Slider0 = 0;
        Slider0State = false;

        Slider1 = 0;
        Slider1State = false;  
}

//-----------------------------------------------------------------------------
// Name: EnumJoysticksCallback()
// Desc: Called once for each enumerated joystick. If we find one, create a
//       device interface on it so we can play with it.
//-----------------------------------------------------------------------------
BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
                                     VOID* pContext )
{
        static   int   nJoyStick = 0;
    HRESULT hr;

        if( nJoyStick >= 1 )
                return DIENUM_STOP;

        //HJoyStick::HasDefinedDevice[ nJoyStick ] = 1;

      // Obtain an interface to the enumerated joystick.
        if( nJoyStick == 0 )
        {
       hr = g_pDI->CreateDevice( pdidInstance->guidInstance, &g_pJoystick, NULL );
        }
    if( FAILED( hr ) )
        return  DIENUM_CONTINUE;

        nJoyStick++;
        g_SystemJoyStickNumber++;
    // Stop enumeration. Note: we're just taking the first joystick we get. You
    // could store all the enumerated joysticks and let the user pick.
    return  DIENUM_CONTINUE; //DIENUM_STOP;
}


//-----------------------------------------------------------------------------
// Name: EnumObjectsCallback()
// Desc: Callback function for enumerating objects (axes, buttons, POVs) on a
//       joystick. This function enables user interface elements for objects
//       that are found to exist, and scales axes min/max values.
//-----------------------------------------------------------------------------
BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
                                   VOID* pContext )
{
    //g_JoyStickDevice  hDlg = (HWND)pContext;
    HJoyStickDevice*   pJoyStickDevice = (HJoyStickDevice*)pContext;

    static int nSliderCount = 0;  // Number of returned slider controls
    static int nPOVCount = 0;     // Number of returned POV controls
    static int nButtonCount = 0;

    // For axes that are returned, set the DIPROP_RANGE property for the
    // enumerated axis in order to scale min/max values.
    if( pdidoi->dwType & DIDFT_AXIS )
    {
        DIPROPRANGE diprg;
        diprg.diph.dwSize       = sizeof(DIPROPRANGE);
        diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
        diprg.diph.dwHow        = DIPH_BYID;
        diprg.diph.dwObj        = pdidoi->dwType; // Specify the enumerated axis
        diprg.lMin              = -1000;
        diprg.lMax              = +1000;
   
        // Set the range for the axis
        if( FAILED( g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
            return DIENUM_STOP;
         
    }


    // Set the UI to reflect what objects the joystick supports
    if (pdidoi->guidType == GUID_XAxis)
    {
                pJoyStickDevice->PosXState = true;

    }

    if (pdidoi->guidType == GUID_YAxis)
    {
                pJoyStickDevice->PosYState = true;

    }

    if (pdidoi->guidType == GUID_ZAxis)
    {
                pJoyStickDevice->PosZState = true;
    }

    if (pdidoi->guidType == GUID_RxAxis)
    {
                pJoyStickDevice->RotXState = true;
        }

    if (pdidoi->guidType == GUID_RyAxis)
    {
                pJoyStickDevice->RotYState = true;
        }

    if (pdidoi->guidType == GUID_RzAxis)
    {
                pJoyStickDevice->RotZState = true;
        }

    if (pdidoi->guidType == GUID_Slider)
    {
        switch( nSliderCount++ )
        {
            case 0 :
                                pJoyStickDevice->Slider0State = true;
                                break;

            case 1 :
                                pJoyStickDevice->Slider1State = true;  
                                break;
        }
    }

    if (pdidoi->guidType == GUID_POV)
    {
        switch( nPOVCount++ )
        {
            case 0 :
                                pJoyStickDevice->POVState1 = true;
                                break;

            case 1 :
                                pJoyStickDevice->POVState2 = true;
                                break;

            case 2 :
                                pJoyStickDevice->POVState3 = true;
                                break;

            case 3 :
                                pJoyStickDevice->POVState4 = true;
                                break;
        }
    }

        if( pdidoi->guidType == GUID_Button )
        {
        switch( nButtonCount++ )
                {
                case 0 :
                        pJoyStickDevice->ButtonState[ 0] = true;
                        break;
                case 1 :
                        pJoyStickDevice->ButtonState[ 1] = true;
                        break;
                case 2 :
                        pJoyStickDevice->ButtonState[ 2] = true;
                        break;
                case 3 :
                        pJoyStickDevice->ButtonState[ 3] = true;
                        break;
                case 4 :
                        pJoyStickDevice->ButtonState[ 4] = true;
                        break;
                case 5 :
                        pJoyStickDevice->ButtonState[ 5] = true;
                        break;
                case 6 :
                        pJoyStickDevice->ButtonState[ 6] = true;
                        break;
                case 7 :
                        pJoyStickDevice->ButtonState[ 7] = true;
                        break;
                case 8 :
                        pJoyStickDevice->ButtonState[ 8] = true;
                        break;
                case 9 :
                        pJoyStickDevice->ButtonState[ 9] = true;
                        break;
                case 10 :
                        pJoyStickDevice->ButtonState[ 10] = true;
                        break;
                case 11 :
                        pJoyStickDevice->ButtonState[ 11] = true;
                        break;
                case 12 :
                        pJoyStickDevice->ButtonState[ 12] = true;
                        break;
                case 13 :
                        pJoyStickDevice->ButtonState[ 13] = true;
                        break;
                case 14 :
                        pJoyStickDevice->ButtonState[ 14] = true;
                        break;
                case 15 :
                        pJoyStickDevice->ButtonState[ 15] = true;
                        break;
                case 16 :
                        pJoyStickDevice->ButtonState[ 16] = true;
                        break;
                case 17 :
                        pJoyStickDevice->ButtonState[ 17] = true;
                        break;
                case 18 :
                        pJoyStickDevice->ButtonState[ 18] = true;
                        break;
                case 19 :
                        pJoyStickDevice->ButtonState[ 19] = true;
                        break;

                }
        }
    return DIENUM_CONTINUE;
}
////////////////////////////////////////////////////////////////////////
HRESULT InitDirectInput( HWND hDlg,int*  JoyStickNum  )
{
    HRESULT hr;
   
        *JoyStickNum = 0;
    // Register with the DirectInput subsystem and get a pointer
    // to a IDirectInput interface we can use.
    // Create a DInput object
    if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION,
                                         IID_IDirectInput8W, (VOID**)&g_pDI, NULL ) ) )
        return hr;

    // Look for a simple joystick we can use for this sample program.
    if( FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL_LWQ,
                                         EnumJoysticksCallback,
                                         NULL, DIEDFL_ATTACHEDONLY ) ) )
        return hr;

    if( g_SystemJoyStickNumber == 0 )
                return  S_FALSE;

     // Make sure we got a joystick
    if( g_pJoystick!= NULL )
    {
       // Set the data format to "simple joystick" - a predefined data format
       //
       // A data format specifies which controls on a device we are interested in,
       // and how they should be reported. This tells DInput that we will be
       // passing a DIJOYSTATE2 structure to IDirectInputDevice::GetDeviceState().
       if( FAILED( hr = g_pJoystick->SetDataFormat( &c_dfDIJoystick2 ) ) )
              return hr;
   
           // Set the cooperative level to let DInput know how this device should
       // interact with the system and with other DInput applications.
       if( FAILED( hr = g_pJoystick->SetCooperativeLevel( hDlg, DISCL_EXCLUSIVE |
                                                             DISCL_FOREGROUND ) ) )
               return hr;

       // Enumerate the joystick objects. The callback function enabled user
       // interface elements for objects that are found, and sets the min/max
       // values property for discovered axes.
       if( FAILED( hr = g_pJoystick->EnumObjects( EnumObjectsCallback,
                                                (VOID*)&g_JoyStickDevice, DIDFT_ALL ) ) )
            return hr;
           *JoyStickNum  += 1;
    }
        return  S_OK;
}

VOID    FreeDirectInput()
{
    if( g_pJoystick )
          g_pJoystick->Unacquire();
   
    // Release any DirectInput objects.
    SAFE_RELEASE( g_pJoystick );

    SAFE_RELEASE( g_pDI );

}

//-----------------------------------------------------------------------------
// Name: UpdateInputState()
// Desc: Get the input device's state and display it.
//-----------------------------------------------------------------------------
HJoyStickDevice*  UpdateInputState( void )
{
    HRESULT     hr;
    static DIJOYSTATE2 js;           // DInput joystick state

    if( NULL == g_pJoystick )
        return NULL;

    // Poll the device to read the current state
    hr = g_pJoystick->Poll();
    if( FAILED(hr) )  
    {
        // DInput is telling us that the input stream has been
        // interrupted. We aren't tracking any state between polls, so
        // we don't have any special reset that needs to be done. We
        // just re-acquire and try again.
        hr = g_pJoystick->Acquire();
        while( hr == DIERR_INPUTLOST )
            hr = g_pJoystick->Acquire();

        // hr may be DIERR_OTHERAPPHASPRIO or other errors.  This
        // may occur when the app is minimized or in the process of
        // switching, so just try again later
        return NULL;
    }

    // Get the input's device state
    if( FAILED( hr = g_pJoystick->GetDeviceState( sizeof(DIJOYSTATE2), &js ) ) )
        return NULL; // The device should have been acquired during the Poll()

    // Axes
        if( g_JoyStickDevice.PosXState == true )
                g_JoyStickDevice.PosX = js.lX;
        if( g_JoyStickDevice.PosYState == true )
                g_JoyStickDevice.PosY = js.lY;
        if( g_JoyStickDevice.PosZState == true )
                g_JoyStickDevice.PosX = js.lZ;

        if( g_JoyStickDevice.RotXState == true )
                g_JoyStickDevice.RotX = js.lRx;
        if( g_JoyStickDevice.RotYState == true )
                g_JoyStickDevice.RotY = js.lRy;
        if( g_JoyStickDevice.RotZState == true )
                g_JoyStickDevice.RotZ = js.lRz;
   
   
        if( g_JoyStickDevice.Slider0State == true )
                g_JoyStickDevice.Slider0 = js.rglSlider[0];
        if( g_JoyStickDevice.Slider1State == true )
                g_JoyStickDevice.Slider1 = js.rglSlider[1];

   
        if( g_JoyStickDevice.POVState1 == true )
                g_JoyStickDevice.POV1 = js.rgdwPOV[0];
        if( g_JoyStickDevice.POVState2 == true )
                g_JoyStickDevice.POV2 = js.rgdwPOV[1];
        if( g_JoyStickDevice.POVState3 == true )
                g_JoyStickDevice.POV3 = js.rgdwPOV[2];


   
    for( int i = 0; i < 20; i++ )
    {
        if ( js.rgbButtons & 0x80 )
                        g_JoyStickDevice.Button[ i] = PutDown;
                else
                        g_JoyStickDevice.Button[ i] = PutUp;
    }

    return &g_JoyStickDevice;
}

int     GetAyatemJoyAtick( void )
{
        return  g_SystemJoyStickNumber;
}
------------------------------------------------
调用方法:
HJoyStickDevice*  pjoyData = UpdateInputState();
使用pjoyData指针取用游戏摇杆的各个数据
------------------------------------------------
附:我所使用的游戏摇杆是EXTREME3D PRO
Logitech
上述代码中并没有使用游戏摇杆的油门键
morty 评论于2007-10-31 15:26:32
obuil老大,我实现了绕目标点的水平旋转
但是如何实现绕目标点垂直旋转呀,要求从水平平视目标点到垂直俯视目标点,目标点为视野中心?
求老大把公式贴一下
morty 评论于2007-11-8 00:15:11
问题已经解决
这么好的帖子没人顶呀,
可惜,
明天发给你,独山子老大
独山子 评论于2007-11-12 15:11:13
是不错的帖子,我也已经顺利实现,有问题可短信联系。
逆水行舟,不进则退。
jz0301 评论于2007-11-12 20:48:30
好东西。。。
tcpch 评论于2007-11-26 14:59:19
终于找到了,马上学习,这个搞了我好久啊
机器余专家组 认证企业会员 评论于2007-12-15 21:31:28
不错呀!朱,我强烈持支你
加油
ixidof 评论于2007-12-21 17:24:58
好东西啊
jackieyubupt 评论于2008-3-25 21:25:57
顶一个先
kou 评论于2010-6-17 19:14:43
请大家把实现围绕中心水平旋转的代码共享一下啊,十分感谢
kou 评论于2010-6-18 18:50:36
能不能把视点绕固定目标旋转的代码贴出来啊,十分感谢
keliever 评论于2014-5-29 21:20:27
看看,mark

手机版|VR开发网 统计 津ICP备18009691号
网安备12019202000257

GMT+8, 2021-9-21 10:42 PM

返回顶部