Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.02.22;
Скачать: CL | DM;

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.014 c
3-1215423644
alles
2008-07-07 13:40
2009.02.22
Как работать с индексами таблицы dbf?


2-1231431032
Johnnnn
2009-01-08 19:10
2009.02.22
Как грамотно вынести процедуру в отдельный модуль?


15-1230014400
Германн
2008-12-23 09:40
2009.02.22
Глюки обоняния


15-1230064090
Anatoly Podgoretsky
2008-12-23 23:28
2009.02.22
ГЛЮК


2-1231924532
andreoman
2009-01-14 12:15
2009.02.22
treeview при двойном щелчке менялась пиктограмма узла