ПрограммированиеФорумГрафика

Помогите разобратся с поворотом объекта в DirectX

#0
21:22, 19 янв 2010

Суть такова: есть куб, при нажатии клавиши <Right> - он вращается вокруг оси Y вправо; <Left> - влево.
Обьявил глобально переменные Right и Left для обозначения нажатия клавиш:

  BOOL         Right = FALSE;
  BOOL         Left = FALSE;

При нажатии на клавишу в переменные пишется TRUE.

Собственно обработка ввода:

if(KEYDOWN(Keyboard, DIK_RIGHT))
{
  Right = TRUE;
};

Для поворота влево - аналогично.

Вот код вращения:

VOID MoveRight()
{
  D3DXMATRIX MatrixWorld, MatrixWorldX, MatrixWorldY, MatrixWorldZ;
  D3DXMATRIX MatrixView;
  D3DXMATRIX MatrixProjection;
  FLOAT Time = timeGetTime() % 5000;
  FLOAT Angle = Time * (2.0f * D3DX_PI) / 5000.0f;
  //Мировая матрица
  D3DXMatrixRotationY(&MatrixWorld, -Angle);  
  pDirect3DDevice->SetTransform(D3DTS_WORLD, &MatrixWorld);

}

Для поворота влево - идентично, только угол Angle - положительный.
Эта ф-я вызывается при обработке нажатия клавиши <Right>

Код обработки:

if(Right) 
{
  DrawMyText("RIGHT", 924, 10, 1014, 50, D3DCOLOR_ARGB(255, 255, 255, 50));
  MoveRight();
  Right = FALSE;
}

Проблема: Если зажать и держать клавишу непрерывно, то куб поворачивается нормально, красивенько. Но если клацать клавишами, то куб вращается рывками. Т.е. он и должен рывками, но такое впечатление что вращается не на одинаковый угол и очень некрасиво. Вот для наглядности сама программа - Cube.
Как сделать чтоб при нажатии на клавиши рывками - куб поворачивался нормально?

Заранее благодарен!

#1
21:36, 19 янв 2010

AxeR
> Вот для наглядности сама программа - Cube.
---------------------------
Cube.exe - Не удалось найти компонент
---------------------------
Приложению не удалось запуститься, поскольку d3dx9_42.dll не был найден. Повторная установка приложения может исправить эту проблему.
---------------------------
ОК 
---------------------------

#2
21:40, 19 янв 2010

X512
Разные версии SDK...

А по тому что я описал никак помочь не сможешь?...

#3
21:45, 19 янв 2010

Про рывки не совсем понял... Возможно дело в высоком FPS(нет vSync).
... хотя стоп, это что?
> FLOAT Time = timeGetTime() % 5000;
Скорее всего проблема в этом.

#4
21:51, 19 янв 2010

Поддерживаю предыдущего оратора. У тебя вращение зависит от времени. :) Сделай вместо этого угол, и увеличивай его, если вращаешь вправо, и уменьшай - если влево. Обойдёшься одной функцией.

#5
21:54, 19 янв 2010

X512
Если проблема в этом, тогда почиму при зажатой кнопке движется нормально...

.dll не смог залить на сервер. Размер велик. Вот ссылка http://dllnotfound.com/d3dx9-42.dll,20069.
Думаю ты знаешь куда ее потом положить;-)

#6
22:00, 19 янв 2010

И на дельту времени умножай.
Например так:

float dt=0.0f;
void Rotate(float value)//value в радиан/секунда.
{
    static float angle=0.0f;
    D3DXMATRIX MatrixWorld;
    angle += value*dt;
    D3DXMatrixRotationY(&MatrixWorld, angle);  
}

bool gameLoop()
{
   static DWORD lastTime=0;
   DWORD time = timeGetTime();
   dt = float(time - lastTime) * 1000.0f;
   lastTime = time;
}

AxeR
> Если проблема в этом, тогда почиму при зажатой кнопке движется нормально...
Когда ты на кнопку не нажимаешь время то идёт...

#7
22:12, 19 янв 2010

K.V.
X512
Хм... раньше делал и не получалось... Вот:
Создал глобальную переменную:

float  Degree = 0;//Градусы

Вместо:

  FLOAT Time = timeGetTime() % 5000;
  FLOAT Angle = Time * (2.0f * D3DX_PI) / 5000.0f;
  D3DXMatrixRotationY(&MatrixWorld, -Angle);  
  pDirect3DDevice->SetTransform(D3DTS_WORLD, &MatrixWorld);

Сделал это:

  float Angle;
  Angle = Degree / 180 * D3DX_PI;
  D3DXMatrixRotationY(&MatrixWorld, -Angle);  
  Degree ++;
  pDirect3DDevice->SetTransform(D3DTS_WORLD, &MatrixWorld);

И работает:)

Буквально часа 2 назад делал тоже самое. Не работало, капец.
Спасибо!

ПрограммированиеФорумГрафика

Тема в архиве.