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

Вниз

Класс камеры 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.049 c
11-1197050289
Jon
2007-12-07 20:58
2009.02.01
TrayIcon PopupEx


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


2-1229431664
Zilog
2008-12-16 15:47
2009.02.01
Как правильно сделать паузу по времени?


2-1229844333
Krasava
2008-12-21 10:25
2009.02.01
А как мне вызвать метод?


2-1229791230
Programmer
2008-12-20 19:40
2009.02.01
Обновление программы, написанной на Делфи самой программой





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский