Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Игры";
Текущий архив: 2009.02.22;
Скачать: [xml.tar.bz2];

Вниз

Проблема с камерой   Найти похожие ветки 

 
ElectriC ©   (2007-04-18 21:20) [0]

Есть проблемка с камерой: Допустим, когда начинаешь вертеть мышкой по/против часовой стрелки, камера, как и положено поворачивается вверх/вниз/влево/вправо, но при этом она ещё начинает переворачивается по/против часовой стрелки? Не подскажите, в чём проблем-ка.

P.S. Или посоветуйте что нужно улучшить.

Код движение камеры мышкой:

...

Xi, Yi : Single;
Cursor : TPoint

...

GetCursorPos(Cursor);
SetCursorPos(800 div 2, 600 div 2);

Xi := Xi + (Cursor.X  - 400)/100 * 0.1;
Yi := Yi - (300 - Cursor.Y)/100 * 0.1;

RotateLR(Xi);
RotateUD(Yi);
Xi := 0; Yi := 0;

...

Код модуля камеры:

 SLCamera = packed record
   CameraType : (FP, FREE);//камера для первого лица/свободная камера

   View, Proj : TD3DMatrix;

   Xi, Yi     : Single;

   LR, UD,
   LK, PS     : TD3DXVECTOR3;
 end;

var D3DDevice : IDirect3DDevice9;

procedure GetViewMatrix;
var X, Y, Z : Single;
begin
 with SLCamera do
  begin
    D3DXVec3Normalize(LK, LK);

    D3DXVec3Cross    (UD, LK, LR);
    D3DXVec3Normalize(UD, UD);

    D3DXVec3Cross    (LR, UD, LK);
    D3DXVec3Normalize(LR, LR);

    X := -D3DXVec3Dot(LR, PS);
    Y := -D3DXVec3Dot(UD, PS);
    Z := -D3DXVec3Dot(LK, PS);

    with View do
     begin
       m[0, 0] := LR.x;
       m[0, 1] := UD.x;
       m[0, 2] := LK.x;
       m[0, 3] :=  0.0;

       m[1, 0] := LR.y;
       m[1, 1] := UD.y;
       m[1, 2] := LK.y;
       m[1, 3] :=  0.0;

       m[2, 0] := LR.z;
       m[2, 1] := UD.z;
       m[2, 2] := LK.z;
       m[2, 3] :=  0.0;

       m[3, 0] :=    X;
       m[3, 1] :=    Y;
       m[3, 2] :=    Z;
       m[3, 3] :=  1.0;
     end;

    D3DDevice.SetTransform(D3DTS_VIEW, View);

    D3DXMatrixPerspectiveFovLH(Proj, D3DX_PI / 4, 1.0, 1.0, 1000.0);
    D3DDevice.SetTransform(D3DTS_PROJECTION, Proj);
  end;
end;

{ движение влево/вправо }
procedure MoveLR(Step : Single);
begin
 with SLCamera do
  case CameraType of
    FP   : PS := D3DXVECTOR3(PS.x + LR.x * Step,                0.0,
                             PS.z + LR.z * Step);
    FREE : PS := D3DXVECTOR3(PS.x + LR.x * Step, PS.y + LR.y * Step,
                             PS.z + LR.z * Step);
  end;

 GetViewMatrix;
end;

{ движение вверх/вниз }
procedure MoveUD(Step : Single);
begin
 with SLCamera do
  If CameraType = FREE then
   begin
     PS.x := PS.x + UD.x * Step;
     PS.y := PS.y + UD.y * Step;
     PS.z := PS.z + UD.z * Step;
   end;

 GetViewMatrix;
end;

{ движение вперёд/назад }
procedure MoveFB(Step : Single);
begin
 with SLCamera do
  case CameraType of
    FP   : PS := D3DXVECTOR3(PS.x + LK.x * Step, 0.0, PS.z + LK.z * Step);
    FREE : begin
             PS.x := PS.x + LK.x * Step;
             PS.y := PS.y + LK.y * Step;
             PS.z := PS.z + LK.z * Step;
           end;
  end;

 GetViewMatrix;
end;

{ поаорот влево/вправо }
procedure RotateLR(Step : Single);
var Mat : TD3DXMatrix;
begin
 with SLCamera do
  begin
    case CameraType of
      FP   : D3DXMatrixRotationY   (Mat, Step);
      FREE : D3DXMatrixRotationAxis(Mat,   UD, Step);
    end;

    D3DXVec3TransformCoord(LR, LR, Mat);
    D3DXVec3TransformCoord(LK, LK, Mat);
 end;

 GetViewMatrix;
end;

{ поворот вверх/вниз }
procedure RotateUD(Step : Single);
var Mat : TD3DXMatrix;
begin
 with SLCamera do
  begin
    D3DXMatrixRotationAxis(Mat, LR, Step);

    D3DXVec3TransformCoord( UD, UD,  Mat);
    D3DXVec3TransformCoord( LK, LK,  Mat);
  end;

 GetViewMatrix;
end;

{ поворот по/против часовой стрелки }
procedure RotateUC(Step : Single);
var Mat : TD3DXMatrix;
begin
 with SLEngine.SLCamera do
  If CameraType = FREE then
   begin
     D3DXMatrixRotationAxis(Mat, LK, Step);

     D3DXVec3TransformCoord( LR, LR,  Mat);
     D3DXVec3TransformCoord( UD, UD,  Mat);
   end;

 GetViewMatrix;
end;

end.


 
Sapersky   (2007-04-19 14:23) [1]

В примерах к DX SDK не вращается - видимо из-за того, что вращение там делается через кватернионы. В DX8 это класс D3DUtil.CD3DArcBall.
В принципе, само по себе вращение не порок, оно присутствует в некоторых коммерческих CAD, например. Даже логично - крутим мышкой вокруг объекта -> поворачиваем объект относительно перпендикулярной экрану оси.


 
ElectriC ©   (2007-04-19 15:57) [2]

Понятно!
Последний вопрос: Как сделать поворот камеры вокруг какого-либо объекта,
например дома, как это сделано, допустим, в Sims"ах?
P.S. Использование нмжеприведённого кода не предлагать:
     RotateLR( 0.02);
     MoveLR  (-0.02);
     если ошибаюсь, то
     RotateLR(-0.02);
     MoveLR  ( 0.02);


 
Sapersky   (2007-04-19 19:27) [3]

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


 
ElectriC ©   (2007-04-19 19:52) [4]

Можешь написать исходный текст?


 
Sapersky   (2007-04-19 21:10) [5]

Я так понял, что в [0] как раз и есть вращение камеры вокруг объекта (толком не вникал), а проблема в том, чтобы сделать вращение относительно произвольной точки.
Если нет... можно заранее подготовить видовую матрицу, направленную в 0 (тем же GetViewMatrix) и потом умножать её на матрицу вращения, полученную D3DXMatrixRotationAxis.
Матрица перемещения - D3DXMatrixTranslation. Потом ещё раз D3DXMatrixMultiply, потом SetTransform(D3DTS_VIEW, ...).


 
ElectriC ©   (2007-04-20 00:32) [6]

Спасибо, по-экспериментируем))


 
ElectriC ©   (2007-04-20 15:04) [7]

Чё т не выходит! Так можешь написать исходник процедуры, которая ворочает камеру вокруг точки, плиз!


 
ElectriC ©   (2007-04-20 18:17) [8]

...


 
Sapersky   (2007-04-20 18:44) [9]

Нет у меня конкретной процедуры, нужно выдирать куски из разных мест, а это долго.
Умножаешь матрицы в правильном порядке? Т.е. порядок передачи параметров в функцию имеет значение.
И чем всё-таки CD3DArcBall не угодил? Хотя в примерах SDK он в основном применяется к матрице модели, фактически можно применять и к видовой. Рекомендация глобального характера - см. ветку про текстуры, качай книги по ссылкам, читай.


 
ElectriC ©   (2007-04-29 21:51) [10]

Я понял, что надо так (хотя и не работает):

LK : TD3DXVECTOR3;
procedure Axis(Step : Single);
var Mat : TD3DXMatrix;
begin
 D3DXMatrixRotationAxis(Mat,     LK, Step);
 D3DXMatrixTranslation (Mat,   Step,  0.0, 0.0);
 D3DXMatrixMultiply     (Mat,    Mat,  Mat);
 Device.SetTransform   ( D3DTS_VIEW,  Mat);
end;
Или нет?


 
ElectriC ©   (2007-04-29 23:05) [11]

Лучше, наверное, будет этот код (и он тож не работает):
procedure Axis(Step : Single);
var matTrans, matRot, matWorld : TD3DXMatrix;
begin
  D3DXMatrixTranslation(matTrans, 0.0, 0.0, 10.0);
  D3DXMatrixRotationYawPitchRoll(matRot,
                                 D3DXToRadian(Step),
                                 0.0,
                                 0.0);

    matWorld.m[0, 0] := matRot.m[0, 0] * matTrans.m[0, 0];
    matWorld.m[0, 1] := matRot.m[0, 1] * matTrans.m[0, 1];
    matWorld.m[0, 2] := matRot.m[0, 2] * matTrans.m[0, 2];
    matWorld.m[0, 3] := matRot.m[0, 3] * matTrans.m[0, 3];

    matWorld.m[1, 0] := matRot.m[1, 0] * matTrans.m[1, 0];
    matWorld.m[1, 1] := matRot.m[1, 1] * matTrans.m[1, 1];
    matWorld.m[1, 2] := matRot.m[1, 2] * matTrans.m[1, 2];
    matWorld.m[1, 3] := matRot.m[1, 3] * matTrans.m[1, 3];

    matWorld.m[2, 0] := matRot.m[2, 0] * matTrans.m[2, 0];
    matWorld.m[2, 1] := matRot.m[2, 1] * matTrans.m[2, 1];
    matWorld.m[2, 2] := matRot.m[2, 2] * matTrans.m[2, 2];
    matWorld.m[2, 3] := matRot.m[2, 3] * matTrans.m[2, 3];

    matWorld.m[3, 0] := matRot.m[3, 0] * matTrans.m[3, 0];
    matWorld.m[3, 1] := matRot.m[3, 1] * matTrans.m[3, 1];
    matWorld.m[3, 2] := matRot.m[3, 2] * matTrans.m[3, 2];
    matWorld.m[3, 3] := matRot.m[3, 3] * matTrans.m[3, 3];

    Device.SetTransform(D3DTS_WORLD, matWorld);
 end;
end;

Пробовал изменять Device.SetTransform(D3DTS_WORLD, matWorld) на
Device.SetTransform(D3DTS_VIEW, matWorld) => Объекты вообще исчезают(((


 
ElectriC ©   (2007-04-30 11:29) [12]

А, всё!!! Въехал наконец-то)))



Страницы: 1 вся ветка

Форум: "Игры";
Текущий архив: 2009.02.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.005 c
15-1226314250
Xenus
2008-11-10 13:50
2009.02.22
Теневое копирование


15-1229921062
TUser
2008-12-22 07:44
2009.02.22
Виста, пользователи и будущее


11-1183565514
Delphuk
2007-07-04 20:11
2009.02.22
Работа с TreeView


2-1231843398
031178
2009-01-13 13:43
2009.02.22
Автофильтр


4-1206106972
chak_xakep
2008-03-21 16:42
2009.02.22
Как на Delphi посредством WIN32API создать MainMenu





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский