Форум: "Игры";
Текущий архив: 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