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

Вниз

Класс камеры DIrectX   Найти похожие ветки 

 
ElectriC ©   (2007-04-14 19:58) [0]

Нашёл "гибкий" класс описания камеры в DirectX.
Т.к. в С++ не слишком силён, может кто-нибудь, помочь, перевести на Pascal"евский (aka Delphi) язык
описание нижеприведённого кода с C++?
P.S.   Или не подскажите где можно найти\скачать готовый класс камеры?
P.P.S. Использование модулей DXUt, DXUtmisc и прочее не предлагать!

class Camera
{
public:
    enum CameraType { LANDOBJECT, AIRCRAFT };

    Camera();
    Camera(CameraType cameraType);
    ~Camera();

    void strafe(float units); // влево/вправо
    void fly(float units);    // вверх/вниз
    void walk(float units);   // вперед/назад

    void pitch(float angle); // вращение относительно правого вектора
    void yaw(float angle);   // вращение относительно верхнего вектора
    void roll(float angle);  // вращение относительно вектора взгляда

    void getViewMatrix(D3DXMATRIX* V);
    void setCameraType(CameraType cameraType);
    void getPosition(D3DXVECTOR3* pos);
    void setPosition(D3DXVECTOR3* pos);
    void getRight(D3DXVECTOR3* right);
    void getUp(D3DXVECTOR3* up);
    void getLook(D3DXVECTOR3* look);

private:
    CameraType  _cameraType;
    D3DXVECTOR3 _right;
    D3DXVECTOR3 _up;
    D3DXVECTOR3 _look;
    D3DXVECTOR3 _pos;
};

void Camera::getViewMatrix(D3DXMATRIX* V)
{
    // Делаем оси камеры ортогональными
    D3DXVec3Normalize(&_look, &_look);

    D3DXVec3Cross(&_up, &_look, &_right);
    D3DXVec3Normalize(&_up, &_up);

    D3DXVec3Cross(&_right, &_up, &_look);
    D3DXVec3Normalize(&_right, &_right);

    // Строим матрицу вида:
    float x = -D3DXVec3Dot(&_right, &_pos);
    float y = -D3DXVec3Dot(&_up, &_pos);
    float z = -D3DXVec3Dot(&_look, &_pos);

    (*V)(0, 0) = _right.x;
    (*V)(0, 1) = _up.x;
    (*V)(0, 2) = _look.x;
    (*V)(0, 3) = 0.0f;

    (*V)(1, 0) = _right.y;
    (*V)(1, 1) = _up.y;
    (*V)(1, 2) = _look.y;
    (*V)(1, 3) = 0.0f;

    (*V)(2, 0) = _right.z;
    (*V)(2, 1) = _up.z;
    (*V)(2, 2) = _look.z;
    (*V)(2, 3) = 0.0f;

    (*V)(3, 0) = x;
    (*V)(3, 1) = y;
    (*V)(3, 2) = z;
    (*V)(3, 3) = 1.0f;
}

void Camera::pitch(float angle)
{
    D3DXMATRIX T;
    D3DXMatrixRotationAxis(&T, &_right, angle);

    // Поворот векторов _up и _look относительно вектора _right
    D3DXVec3TransformCoord(&_up,&_up, &T);
    D3DXVec3TransformCoord(&_look,&_look, &T);
}

void Camera::yaw(float angle)
{
    D3DXMATRIX T;

    // Для наземных объектов выполняем вращение
    // вокруг мировой оси Y (0, 1, 0)
    if(_cameraType == LANDOBJECT)
         D3DXMatrixRotationY(&T, angle);

    // Для летающих объектов выполняем вращение
    // относительно верхнего вектора
    if(_cameraType == AIRCRAFT)
         D3DXMatrixRotationAxis(&T, &_up, angle);

    // Поворот векторов _right и _look относительно
    // вектора _up или оси Y
    D3DXVec3TransformCoord(&_right, &_right, &T);
    D3DXVec3TransformCoord(&_look, &_look, &T);
}

void Camera::roll(float angle)
{
    // Вращение только для летающих объектов
    if(_cameraType == AIRCRAFT)
    {
         D3DXMATRIX T;
         D3DXMatrixRotationAxis(&T, &_look, angle);

         // Поворот векторов _up и _right относительно
         // вектора _look
         D3DXVec3TransformCoord(&_right, &_right, &T);
         D3DXVec3TransformCoord(&_up, &_up, &T);
    }
}

void Camera::walk(float units)
{
    // Для наземных объектов перемещение только в плоскости xz
    if(_cameraType == LANDOBJECT)
         _pos += D3DXVECTOR3(_look.x, 0.0f, _look.z) * units;

    if(_cameraType == AIRCRAFT)
         _pos += _look * units;
}

void Camera::strafe(float units)
{
    // Для наземных объектов перемещение только в плоскости xz
    if(_cameraType == LANDOBJECT)
         _pos += D3DXVECTOR3(_right.x, 0.0f, _right.z) * units;

    if(_cameraType == AIRCRAFT)
         _pos += _right * units;
}

void Camera::fly(float units)
{
    if(_cameraType == AIRCRAFT)
         _pos += _up * units;
}


 
Леон ©   (2007-04-15 18:15) [1]

скорее всего, так:
TCameraType = ( LANDOBJECT, AIRCRAFT );

TCamera = class (TObject)
public
    constructor Create;
    constructor Create(cameraType: TCameraType);
    destructor  Destroy();
    procedure strafe(units: real);
    procedure fly(units: real);
    procedure walk(units: real);
    procedure pitch(angle: real);
    procedure yaw(angle: real);
    procedure roll(angle: real);
    procedure getViewMatrix(var V: D3DXMATRIX);
    procedure setCameraType(cameraType: TCameraType);
    procedure getPosition(var pos: D3DXVECTOR3);
    procedure setPosition(var pos: D3DXVECTOR3);
    procedure getRight(var right: D3DXVECTOR3);
    procedure getUp(var up: D3DXVECTOR3);
    procedure getLook(var look: D3DXVECTOR3);
private
    _cameraType: D3DXVECTOR3;
    _right,
    _up,
    _look,
    _pos : D3DXVECTOR3;
end;

procedure TCamera.getViewMatrix(var V: D3DXMATRIX);
var x,y,z: real;
begin   
    D3DXVec3Normalize(_look, _look);
    D3DXVec3Cross(_up, _look, _right);
    D3DXVec3Normalize(_up, _up);
    D3DXVec3Cross(_right, _up, _look);
    D3DXVec3Normalize(_right, _right);
    x := -D3DXVec3Dot(_right, _pos);
    y := -D3DXVec3Dot(_up, _pos);
    z := -D3DXVec3Dot(_look, _pos);
    V[0, 0] := _right.x;
    V[0, 1] := _up.x;
    V[0, 2] := _look.x;
    V[0, 3] := 0.0;
    V[1, 0] := _right.y;
    V[1, 1] := _up.y;
    V[1, 2] := _look.y;
    V[1, 3] := 0.0;
    V[2, 0] := _right.z;
    V[2, 1] := _up.z;
    V[2, 2] := _look.z;
    V[2, 3] := 0.0;
    V[3, 0] := x;
    V[3, 1] := y;
    V[3, 2] := z;
    V[3, 3] := 1.0;
end;

дальше уж сам...


 
Леон ©   (2007-04-15 18:17) [2]

упс..
вместо private
    _cameraType: D3DXVECTOR3;

следует private
    _cameraType: TCameraType;


 
ElectriC ©   (2007-04-15 19:25) [3]

В процедуре procedure TCamera.getViewMatrix(var V: TD3DXMATRIX) компилятор ругается: "Array type required". В чём проблема?


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

А, всё, нашёл! Нужно было писать V.m[0, 0] и т.д.


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

Подскажите, как перевести на pascal нижеприведённый код:

    if(_cameraType == LANDOBJECT)
         _pos += D3DXVECTOR3(_look.x, 0.0f, _look.z) * units;

    if(_cameraType == AIRCRAFT)
         _pos += _look * units;

Заранее, спасибо!

P.S. Может быть, так:
procedure Walk(units : Single);
begin
  If cameraType = LANDOBJECT then
     _pos := _pos + D3DXVECTOR3(_look.x, 0.0, _look.z) * units;

    If _cameraType = AIRCRAFT then
         _pos := _pos + _look * units;
 end;
end;
Но при этом компилятор ругается:
"Operator not applicable to this operand type" -                                             в строке    _pos := _pos + D3DXVECTOR3(_look.x, 0.0, _look.z) * units
и в строке _pos := _pos + _look * units;


 
Леон ©   (2007-04-16 11:57) [6]

Дело в том что операция * переопределена. Скорее всего в данном случае это умножение вектроа на скаляр (для 100% увереенности нужно видеть реализацию класса D3DXVECTOR3). Поэтому:

if _cameraType = LANDOBJECT then
        _pos := _pos + D3DXVECTOR3(_look.x*units, 0.0f, _look.z*units);


 
Piroxyline ©   (2007-04-21 18:05) [7]

Вот полный, но немного оптимизированный мной перевод самого первого кода. Переводилось прямо в браузере, так что может не работать. Хотя оно и так работать не будет :)


Float = Single;
TCameraType = (LANDOBJECT, AIRCRAFT);
TCamera = class
 private
   _CameraType: TCameraType;
   _Right, _Up, _Look, _Pos: TD3DXVector3;
 public
   constructor Create; overload;
   constructor Create(CameraType: TCameraType); overload;
   destructor Destroy;
   procedure Strafe(Units: Float);
   procedure Fly(Units: Float);
   procedure Walk(Units: Float);
   
   procedure Pitch(Angle: Float);
   procedure Yaw(Angle: Float);
   procedure Roll(Angle: Float);

   procedure GetViewMatrix(out V: TD3DXMATRIX);
   procedure SetCameraType(CameraType: TCameraType);
   procedure GetPosition(out Pos: TD3DXVector3);
   procedure SetPosition(Pos: TD3DXVector3);
   procedure GetRight(out Right: TD3DXVector3);
   procedure GetUp(out Up: TD3DXVector3);
   procedure GetLook(out Look: TD3DXVector3);
end;

procedure TCamera.GetViewMatrix(out V: TD3DXMATRIX);
var
 x, y, z: Float;
begin
 D3DXVec3Normalize(_look, _look);

 D3DXVec3Cross(_up, _look, _right);
 D3DXVec3Normalize(_up, _up);

 D3DXVec3Cross(_right, _up, _look);
 D3DXVec3Normalize(_right, _right);

 x := -D3DXVec3Dot(_right, _pos);
 y := -D3DXVec3Dot(_up, _pos);
 z := -D3DXVec3Dot(_look, _pos);

 V.m[0, 0] := _right.x;
 V.m[0, 1] := _up.x;
 V.m[0, 2] := _look.x;
 V.m[0, 3] := 0.0;

 V.m[1, 0] := _right.y;
 V.m[1, 1] := _up.y;
 V.m[1, 2] := _look.y;
 V.m[1, 3] := 0.0;

 V.m[2, 0] := _right.z;
 V.m[2, 1] := _up.z;
 V.m[2, 2] := _look.z;
 V.m[2, 3] := 0.0;

 V.m[3, 0] := x;
 V.m[3, 1] := y;
 V.m[3, 2] := z;
 V.m[3, 3] := 1.0;
end;

procedure TCamera.Pitch(Angle: Float);
var
 T: TD3DXMatrix;
begin
 D3DXMatrixRotationAxis(T, _right, Angle);
 D3DXVec3TransformCoord(_up, _up, T);
 D3DXVec3TransformCoord(_look, _look, T);
end;

procedure TCamera.Yaw(Angle: Float);
var
 T: TD3DXMatrix;
begin
 if _CameraType = LANDOBJECT then
   D3DXMatrixRotationY(T, Angle)
 else
   D3DXMatrixRotationAxis(T, _up, Angle);

 D3DXVec3TransformCoord(_right, _right, T);
 D3DXVec3TransformCoord(_look, _look, T);
end;

procedure TCamera.Roll(Angle: Float);
var
 T: TD3DXMatrix;
begin
 if CameraType = AIRCRAFT then begin
   D3DXMatrixRotationAxis(T, _look, angle);
   D3DXVec3TransformCoord(_right, _right, T);
   D3DXVec3TransformCoord(_up, _up, T);
 end;
end;

procedure TCamera.Walk(Units: Float);
begin
 if CameraType = LANDOBJECT then
   _pos := D3DXVector3(_pos.x + _look.x * Units, _pos.y, _pos.z + _look.z * Units)
 else
   _pos = D3DXVector3(_pos.x + _look.x * Units, _pos.y + _look.y * Units, _pos.z + _look.z * Units);
end;

procedure TCamera.Strafe(Units: Float);
begin
 if CameraType = LANDOBJECT then
   _pos := D3DXVector3(_right.x + _look.x * Units, _pos.y, _pos.z + _right.z * Units)
 else
   _pos = D3DXVector3(_pos.x + _right.x * Units, _pos.y + _right.y * Units, _right.z + _look.z * Units);
end;

procedure TCamera.Fly(Units: Float);
begin
 if CameraType = AIRCRAFT then
   _pos := D3DXVector3(_right.x + _up.x * Units, _pos.y + _up.y * Units, _pos.z + _up.z * Units);
end;


 
ElectriC ©   (2007-04-22 00:55) [8]

Поглядим)))


 
s1aSh   (2007-04-22 10:50) [9]

Не подскажите, откуда текст на с++? И еще, почему не принимаете DXUT? Я наоборот хочу понять, как оно там устроено (в сэмплах СДК-шных выглядит все довольно симпатично, двигается хорошо). Если знаете, где можно про камеры в DXUT почитать, скажите плизз. А то второй день не могу понять, че к чему (а в хэлпе СДК-шном ни слова про камеру из примеров).

p.s. там у них (в sdk) даже пустая заготовка выполнена через DXUT, а не как в их же туториалах.


 
ElectriC ©   (2007-04-22 21:49) [10]


> И еще, почему не принимаете DXUT?

Да потому что он объёмен, т.б. добавляет уйму КБ к exe"шнику!



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

Текущий архив: 2009.02.01;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.013 c
2-1229425819
Artem
2008-12-16 14:10
2009.02.01
Объектные переменные


2-1229374412
bit
2008-12-15 23:53
2009.02.01
TListView get item


2-1229423666
9899100
2008-12-16 13:34
2009.02.01
Property


2-1229292385
Tatb9na
2008-12-15 01:06
2009.02.01
Файлы Delphi


11-1196957964
Elec3C
2007-12-06 19:19
2009.02.01
Небольшой глюк