Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.01.2011, 11:53   #1
Celestia
Пользователь
 
Регистрация: 03.11.2010
Сообщений: 68
Восклицание WASD + мышка. DirectX + Delphi.

Здравствуйте!
Если у кого есть, поделитесь пожалуйста примером реализации перемещения камеры в трёхмерном пространстве "WASD + мышка", ну как в FPS
Пока разбираюсь с матрицами но мало что выходит

Использую DirectX9 + Delphi 2007

Спасибо

зы: прикрепляю example с простым выводом куба, я его использую как основу для опытов.
Вложения
Тип файла: rar Example.rar (194.4 Кб, 27 просмотров)
Celestia вне форума Ответить с цитированием
Старый 24.01.2011, 15:14   #2
k3rn3l
Пользователь
 
Регистрация: 09.01.2011
Сообщений: 16
По умолчанию

На DirectX не знаю, а на OpenGL вот:

Код:

TCamera = object

    Eye         : TVector3f;
    View        : TVector3f;
    Up          : TVector3f;
    XAngle      : GLFloat;  //  Angles of camera must obtain
    YAngle      : GLFloat;  //  in(rounded) 90..270, 180 view to center
    MinAngle    : GLFloat;  //  WARNING!!! MaxAngle and MinAngle must be
    MaxAngle    : GLFloat;  //  in 269.9..90.1
    Width       : Integer;
    Height      : Integer;
    X           : Integer;
    Y           : Integer;
    Inverted    : Bool;
    Sensitivity : GLFloat;  // Speed must be in 0..1 of Real
    SpeedRun    : Single;
    Radian      : GLFloat;
    constructor Create;         // Default camera parametres
    procedure SetCameraByMouse(Form:TForm);
    procedure CalcView;         // Calculate view vector
    procedure InvCalcView;      // Calculate inverted by Y axis view vector
    procedure Look;            // Look with camera
    procedure MoveCamera( Speed: Single );
    procedure StrafeCamera( Speed: Single );

 end;

-----------------------------

constructor TCamera.Create;
begin
  Inverted    := False;
  XAngle      := 180;
  YAngle      := 0;
  MinAngle    := 90.1;
  MaxAngle    := 269.9;       
  Eye[0]      := 0;
  Eye[1]      := 0;
  Eye[2]      := 0;
  View[0]     := 0;
  View[1]     := 0;
  View[2]     := 0;
  Up[0]       := 0;
  Up[1]       := 1;
  Up[2]       := 0;
  Sensitivity := 0.2;
  Radian      := 0.017453292519943295769236907684886;
  SpeedRun    := 0.2;
end;

{----------------------------------------------------------------------------}
{---      Set camera by mouse                                             ---}
{----------------------------------------------------------------------------}
procedure TCamera.SetCameraByMouse(Form:TForm);
var
  p     : TPoint;
  mX, mY: Integer;
begin
  mX:= Form.left + (Form.width shr 1);
  mY:= Form.top + (Form.height shr 1);

  GetCursorPos( p );
  SetCursorPos( mX, mY );
  
  X := p.X;
  Y := p.Y;

  XAngle:= XAngle + (Y - mY)*Sensitivity;
  YAngle:= YAngle - (mX - X)*Sensitivity;

  if XAngle >= MaxAngle then XAngle:= MaxAngle;
  if XAngle <= MinAngle then XAngle:= MinAngle;
end;



{----------------------------------------------------------------------------}
{---    Calculate camera view vector                                      ---}
{----------------------------------------------------------------------------}
procedure TCamera.CalcView;
var
  R: GLFloat;
begin
  R     := Cos( XAngle * Radian );
  View[0]:= Eye[0] + Sin( -YAngle * Radian ) * R;
  View[1]:= Eye[1] + Sin( XAngle * Radian );
  View[2]:= Eye[2] + Cos( -YAngle * Radian ) * R;
end;

{----------------------------------------------------------------------------}
{---    Calculate camera view vector inverted                             ---}
{----------------------------------------------------------------------------}
procedure TCamera.InvCalcView;
var
  R: GLFloat;
begin
  R     := Cos( XAngle * Radian );
  View[0]:= Eye[0] + Sin( -YAngle * Radian ) * R;
  View[1]:= Eye[1] + Sin( -XAngle * Radian );
  View[2]:= Eye[2] + Cos( -YAngle * Radian ) * R;
end;

{----------------------------------------------------------------------------}
{---    Look around scene with camera                                     ---}
{----------------------------------------------------------------------------}
procedure TCamera.Look;
begin
  if(Inverted)then
    InvCalcView
  else
    CalcView;
  gluLookAt(  Eye[0],   Eye[1],  Eye[2],
             View[0],  View[1], View[2],
               Up[0],    Up[1],   Up[2] );
end;


{=======================================================================}


{----------------------------------------------------------------------------}
{---    Move camera forward and backward                                  ---}
{----------------------------------------------------------------------------}
procedure TCamera.MoveCamera( Speed: Single );
var V: TVector3f;
begin
  V   := VectorSubtract( View, Eye );
  Eye := VectorAdd( Eye,  VectorMult( V, Speed ) );
  View:= VectorAdd( View, VectorMult( V, Speed ) );
end;

{----------------------------------------------------------------------------}
{---    Move camera to left and to right                                  ---}
{----------------------------------------------------------------------------}
procedure TCamera.StrafeCamera( Speed: Single );
var
  Cross : TVector3f;
begin
  Cross := VectorCrossProduct( Up, VectorSubtract( View, Eye ) );

  Eye[0] := Eye[0] + Cross[0] * Speed;
  Eye[2] := Eye[2] + Cross[2] * Speed;

  View[0]:= View[0] + Cross[0] * Speed;
  View[2]:= View[2] + Cross[2] * Speed;
end;
k3rn3l вне форума Ответить с цитированием
Старый 24.01.2011, 15:14   #3
k3rn3l
Пользователь
 
Регистрация: 09.01.2011
Сообщений: 16
По умолчанию

Обработка клавиш

Код:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var keys: TKeyboardState;
begin
  If Key = VK_ESCAPE then Close;

  GetKeyboardState(keys);


   If (Keys[ord('W')] and 128) = 128
    then
      camera.MoveCamera(camera.SpeedRun);


   If (Keys[ord('S')] and 128) = 128
    then
      camera.MoveCamera(-camera.SpeedRun);


   If (Keys[ord('D')] and 128) = 128
    then
      camera.StrafeCamera(-camera.SpeedRun);

   If (Keys[ord('A')] and 128) = 128
    then
      camera.StrafeCamera(camera.SpeedRun);

   formPaint(Sender);
end;
Если будешь делать через OnMouseMove не забудь добавить PeekMessage, а то SetCursorPos будет постоянно вызывать OnMouseMove

Код:

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var Msg:TMsg;
begin
  camera.SetCameraByMouse(Form1);
  while PeekMessage(Msg, Handle, WM_MOUSEFIRST, WM_MOUSELAST,
     PM_REMOVE or PM_NOYIELD) do;

  formPaint(Sender);

end;

Последний раз редактировалось k3rn3l; 24.01.2011 в 15:25.
k3rn3l вне форума Ответить с цитированием
Старый 29.01.2011, 04:20   #4
Heymdall
 
Регистрация: 19.01.2011
Сообщений: 3
По умолчанию Ку

У вас всё есть в методе TMainForm.SetupCamera :

FD3DDevice.SetTransform(D3DTS_VIEW, ViewMatrix);

вот этот метод задает направление взгляда камеры,
это видовая матрица.
задавайте изменение видовой матрицы в каждом кадре а не только в начале как настройка сцены, в метод TMainForm.RenderScene
например сразу после метода
FD3DDevice.SetTransform(D3DTS_WORLD , WorldMatrix);
мировая матрица у вас в каждом кадре задается,
а видовая нет.

изменяя ViewMatrix вы можете вертеть камерой вокруг сцены меняя вектор Eye в вашем примере :

// Вектор, определяющий положение глаз наблюдателя
Eye.x := 0; Eye.y := 0; Eye.z := -5;
// Строим левостороннюю матрицу вида
D3DXMatrixLookAtLH(ViewMatrix, Eye, At, Up);

данный "глаз" Eye.x := 0; Eye.y := 0; Eye.z := -5;
говорит, что камера смотрит из точки (0,0,-5) в точку (0,0,0) т.к. At.x := 0; At.y := 0; At.z := 0;

меняйте Eye и At в зависимости от мыши и/или клавиатуры и задавайте видовую матрицу в кадре, вроде всё.

матричные операции для кручения верчения объектами, это отдельная песня, объект может выть например составным, части которого движутся относительно друг друга, например модель поршня-шатуна-коленчатого вала, тут даже поступательное движения переходит во вращательное.
у меня нет тех модулей или не все, что указаны в строке
uses , но кажется у вас задано вращение вокруг Глобальных осей X, Y, Z объекты же всё норовят вращаться как бы сами по себе, вокруг собственных осей координат а не вокруг глобальных...
в любом случае задача нетривиальная.
Heymdall вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Delphi 7(10), windows 7 и DirectX ImmortalAlexSan Общие вопросы Delphi 7 05.09.2010 20:44
Delphi&DirectX insolent Общие вопросы Delphi 9 29.07.2010 11:28
Книга DirectX и Delphi.... Jupiter Свободное общение 8 22.08.2009 19:26
picking directX(Delphi) Mell12345678 Gamedev - cоздание игр: Unity, OpenGL, DirectX 0 04.06.2009 10:31
New Project: DirectX and Delphi Kostia Gamedev - cоздание игр: Unity, OpenGL, DirectX 12 04.05.2008 04:27