[DirectX] Caméra, Géométrie

Le côté programmation du développement d'un jeu vidéo.

Caméra, Géométrie

Messagepar Gabriel » 29 Déc 2006, 21:23

Bonjour,

Actuellement en plein apprentissage de la librairie graphique DirectX, j'ai pas mal de questions à vous poser concernant la gestion de caméra et la géométrie dans l'espace, donc je vais essayer d'être le plus claire possible, mais je tiens à vous prévenir en premier que je suis qu'un débutant et quand je dis débutant il n' y a pas de niveau plus bas, de plus j'ai un niveau maths très faible et je m'en rend bien compte maintenant :(

Géométrie dans l'espace et Caméra


Code: Tout sélectionner
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity(&matWorld);
g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);


Si j'ai bien compris, si nous ne mettons pas ces lignes de code, nous n’avons aucun espace de géométrie, donc on ne pourra voir aucun objet, c'est ceci qui va définir notre espace ou l'on dessinera nos formes géométriques.
En quelque sorte on crée une boite qui n'a pas de limite et pouvoir y placer nos formes géométriques ?

Code: Tout sélectionner
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH(&matView, Focalisation, &Position, &Orientation);
g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);


Maintenant que notre monde est crée, il faut crée un "humain" qui va explorer ce monde, ou une caméra, c'est le but de cette matrice si j'ai bien compris,

On va créer cette matrice à partir de 3 vecteurs : ou es notre humain, que regarde t il, comment est il penché.

Toujours ça ?

Code: Tout sélectionner
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f);
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);


Maintenant que notre humain est dans notre nouveau monde, on va donner des caractéristiques à ses yeux, ce qui est le but de cette matrice ?
Par exemple : jusqu'ou peut regarder nos yeux ?


Jusqu'ici il n'y avait pas de problème "mathématiques" maintenant commence les problèmes :(, j'ai regardé un peu sur le web les différents type de gestion de caméra, et je ne comprends pas la différence entre toutes, pourquoi certains utilise les quaternions (de plus je ne sais pas ce que c'est), d'autres les vecteurs, d'autres les nombres complexes ...etc. ?

Je ne comprends pas comment on peut utiliser des sinus, cosinus et tangente alors que avec le cercle trigonométrique on a des valeurs être -1 et 1 et qu'on peut bouger la caméra beaucoup plus loin :/

Merci de vos réponses et désolé d'avance des bêtises que j'ai dit dedans.
Avatar de l’utilisateur
Gabriel
 
Messages: 311
Inscription: 25 Fév 2006, 10:15

Messagepar kensai » 30 Déc 2006, 04:03

Salut,
je débute aussi mais j'ai quand même déjà codé un peu la gestion de la caméra. J'utilise les sinus et cosinus en fait ils servent à calculer des coordonnées en fonction de coordonnées polaires.:00000029:

Les coordonnées polaires ont deux variables que sont un angle et une distance depuis l'origine (c'est sur un plan en 2d ça). Avec ça il suffit donc de faire varier l'angle pour faire pivoter une camera !:00000001:

Par exemple si tu veux qu'elle tourne autour d'un point tu définis le target de la caméra aux mêmes coordonnées que ton point et pour les coordonnées de la caméra tu calcules la longueur qui la sépare du point. Je crois qu'il y a même des fonctions de base pour ce genre de calcul mais tu peux très bien le calculer toi même. Sinon tu peux définir une distance fixe pour faciliter la chose ^^.
Une fois que t'as la distance il suffit de définir un angle et comme ça les coordonnées sur x et z sont :
position.X = targetPosition.X + distance * cos(angle)
position.Z = targetPosition.Z + distance * sin(angle)

(moi je dois faire -cos(angle) et -sin(angle) pour que ça marche correctement je sais pas trop pourquoi p-e parce que le monde est défini en left handed :00000013: )

c'est comme un cercle trigonométrique sauf que la distance est maintenant prise en compte et à cela il faut ajouter les coordonnées du point (ici targetPosition) pour avoir la position de la caméra dans l'espace...:00000030:

Bon tout ça c'est pour de la 2d mais ça peut être très facilement étendu à de la 3d, pour cela je calcule d'abord ce que ça donne sur le plan x,z et ensuite je refais les mêmes calculs pour le plan vertical qui passe par l'origine et mon point donc pour obtenir la coordonnée sur Y ..

Voila je te donne ma technique j'espère que tu comprends l'essentiel enfin en tout cas renseigne toi sur les coordonnées polaires et tu arriveras surement à quelque chose.
kensai
Hello World, I'm new !
 
Messages: 15
Inscription: 14 Mar 2006, 12:24
Localisation: Nancy

Messagepar Loulou » 30 Déc 2006, 15:59

Si j'ai bien compris, si nous ne mettons pas ces lignes de code, nous n’avons aucun espace de géométrie, donc on ne pourra voir aucun objet, c'est ceci qui va définir notre espace ou l'on dessinera nos formes géométriques.
En quelque sorte on crée une boite qui n'a pas de limite et pouvoir y placer nos formes géométriques ?

Si tu ne mets pas ces lignes de code, tu auras juste une matrice monde initialisée par défaut, càd soit à l'identité soit n'importe comment (cf. la doc pour savoir ce qui est mis par défaut).
La matrice monde définit un repère, et non pas un espace ou une boîte. En général chaque objet à sa matrice monde (ie. son repère local), qui lui permet d'être placé / orienté / dimensionné différemment dans la scène.

Maintenant que notre monde est crée, il faut crée un "humain" qui va explorer ce monde, ou une caméra, c'est le but de cette matrice si j'ai bien compris

Tu ne crées rien, tu initialises juste une autre matrice à laquelle tu vas donner le rôle de point de vue (ou caméra si tu préfères). Mais comme la matrice monde, ce n'est qu'une matrice par laquelle tes sommets seront multipliés avant d'être affichés, elle ne définit qu'un repère.

On va créer cette matrice à partir de 3 vecteurs : ou es notre humain, que regarde t il, comment est il penché

Voilà

Maintenant que notre humain est dans notre nouveau monde, on va donner des caractéristiques à ses yeux, ce qui est le but de cette matrice ?
Par exemple : jusqu'ou peut regarder nos yeux ?

On peut voir ça comme ça. En gros ça définit la manière dont la scène 3D sera projetée en 2D.

Jusqu'ici il n'y avait pas de problème "mathématiques" maintenant commence les problèmes , j'ai regardé un peu sur le web les différents type de gestion de caméra, et je ne comprends pas la différence entre toutes, pourquoi certains utilise les quaternions (de plus je ne sais pas ce que c'est), d'autres les vecteurs, d'autres les nombres complexes ...etc. ?

Un quaternion est un outil mathématique (pour simplifier) qui permet de représenter n'importe quelle rotation et qui est simple à manipuler. Il peut ensuite être converti en matrice très facilement. Vecteurs et nombres complexes sont aussi des entités mathématiques, chacune ayant son utilité à un endroit ou un autre du code.
Pour cequi est de la caméra, en effet il existe plusieurs manière de la gérer. Certains utilisent les quaternions, d'autres des vecteurs (position, direction, up), etc... l'important étant qu'on arrive toujours à en tirer une matrice qu'on pourra ensuite envoyer à l'API en tant que matrice de vue. Après à toi de choisir la représentation qui te convient le mieux.

Je ne comprends pas comment on peut utiliser des sinus, cosinus et tangente alors que avec le cercle trigonométrique on a des valeurs être -1 et 1 et qu'on peut bouger la caméra beaucoup plus loin :/

Le cercle trigonométrique a un rayon de 1 ; rien n'empêche de multiplier par une distance quelconque pour avoir un rayon plus élevé.

Je pense que tu vas avoir beaucoup de mal si tu n'as pas vu certaines notions mathématiques essentielles. Je te conseillerai bien de lire un bon bouquin, mais là faut vraiment être motivé... :)
Loulou
Hello World, I'm new !
 
Messages: 702
Inscription: 10 Avr 2005, 12:00

Messagepar Gabriel » 03 Jan 2007, 20:13

Je viens vous demander de l'aide, car j'ai un problème vraiment bizarre, je commence à comprendre les vecteurs, les points, les repéres et les matrices alors j'expose mon problème :
J'essaie de tourner autour d'un point que met dans Focalisation, le problème c'est que entre l'angle 90° et 270° je ne vois plus mon triangle alors que le CULLING est désactivé et que mes valeurs sont toujours bonnes :/

donc je vous paste mon code avec une explication :

Code: Tout sélectionner
#include "Application.h"

Camera* camera = new Camera(0, 0, 0);
D3DXVECTOR3 Curseur;
bool keys[256];
int angle = 90;

void SetupMatrices(LPDIRECT3DDEVICE9 &g_pd3dDevice) {
    D3DXMATRIXA16 matWorld;
    D3DXMatrixIdentity(&matWorld);
    g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);

    D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1024/768, 1.0f, 1000.0f);
    g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}

HRESULT InitGeometry(LPDIRECT3DDEVICE9 &g_pd3dDevice, LPDIRECT3DVERTEXBUFFER9 &g_pVB, LPDIRECT3DTEXTURE9 &g_pTexture ) {
   camera->SetFocalisation(0, 0, 0);
   camera->SetPosition(0,0,0);
   camera->RotationY(angle);

   //g_pd3dDevice->CreateVertexBuffer((g_pTextureDesc.Height * g_pTextureDesc.Width) * 4 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL);
   g_pd3dDevice->CreateVertexBuffer(3 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL);

    CUSTOMVERTEX* pVertices;

   /* partie temporaire pour la hm */
    g_pVB->Lock(0, 0, (void**)&pVertices, 0);
   pVertices[0].position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
   pVertices[1].position = D3DXVECTOR3(0.05f, 0.15f, 0.0f);
   pVertices[2].position = D3DXVECTOR3(0.1f, 0.0f, 0.0f);
   
   pVertices[0].color    = 0xFF132327;
   pVertices[1].color    = 0xFF132327;
   pVertices[2].color    = 0xFF132327;
    g_pVB->Unlock();
    return S_OK;
}

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch(msg) {
      case WM_MOUSEMOVE: {
            Curseur.x = LOWORD(lParam);
            Curseur.y = HIWORD(lParam);
            return 0;
        }

      case WM_KEYDOWN:
      {
         keys[wParam] = TRUE;
         return 0;
      }

      case WM_KEYUP:
      {
         keys[wParam] = FALSE;
         return 0;
      }

        case WM_DESTROY:
            PostQuitMessage( 0 );
            return 0;
    }
    return DefWindowProc( hWnd, msg, wParam, lParam );
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT) {
   LPDIRECT3DVERTEXBUFFER9 g_pVB        = NULL;
   LPDIRECT3DTEXTURE9      g_pTexture   = NULL;
   LPDIRECT3D9             g_pD3D       = NULL;
   LPDIRECT3DDEVICE9       g_pd3dDevice = NULL;

    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      L"FrameWork", NULL };

    RegisterClassEx(&wc);
    HWND hWnd = CreateWindow(L"FrameWork", L"Imagerie",
                              WS_OVERLAPPEDWINDOW, 0, 0, 1024, 768,
                              NULL, NULL, wc.hInstance, NULL);

    if(SUCCEEDED(InitD3D(g_pd3dDevice, hWnd, g_pD3D))) {
      InitGeometry(g_pd3dDevice, g_pVB, g_pTexture);
      SetupMatrices(g_pd3dDevice);
        ShowWindow(hWnd, SW_SHOWDEFAULT);
        UpdateWindow(hWnd);

        MSG msg;
        ZeroMemory(&msg, sizeof(msg));
        while(msg.message != WM_QUIT) {
            if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
         else {
            if(keys[VK_RIGHT]) {
                angle++;
               camera->RotationY(angle);
            }
            camera->Focalise(g_pd3dDevice);
                Render(g_pd3dDevice, g_pVB, camera, Curseur);
         }
      }
    }

    UnregisterClass(L"FrameWork", wc.hInstance);
   if( g_pTexture != NULL )
      g_pTexture->Release();
   if( g_pVB != NULL )
        g_pVB->Release();
    if(g_pd3dDevice != NULL)
        g_pd3dDevice->Release();
    if(g_pD3D != NULL)
        g_pD3D->Release();
    return 0;
}


Ceci est mon fichier main.cpp, dedans je gére quand j'appuie sur une touche pour modifier l'angle de rotation.

Code: Tout sélectionner
void Camera::RotationY(float angle) {
    angle = angle / 180.f * D3DX_PI;
   SetPosition(cosf(angle), Position.y, sinf(angle));
}


Positionne la caméra sur le point d'un cercle grâce à un angle

Code: Tout sélectionner
void Camera::Focalise(LPDIRECT3DDEVICE9 &g_pd3dDevice) {
   D3DXVECTOR3 F;
   F.x = Focalisation.x - Position.x;
   F.y = Focalisation.y - Position.y;
   F.z = Focalisation.z - Position.z;

   D3DXVec3Normalize(&F, &F);

   D3DXMATRIXA16 matView;
    D3DXMatrixLookAtLH(&matView, &F, &Position, &Orientation);
    g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
}


Je modifie ma matrice VIEW, donc je dois calculer mon Vecteur Eye qui n'est qu'une soustraction entre le point ou je regarde et la position ou je suis, que je normalise par la suite.

J'ai remarqué que ca disparaissé lors du passage des négatifs au positifs des valeurs du point de la positions et de la focalisation. (qui se fait à 90° et 270°)

Je vous remercie de votre aide, si il vous manque des informations dites le moi :)
Avatar de l’utilisateur
Gabriel
 
Messages: 311
Inscription: 25 Fév 2006, 10:15

Messagepar Gabriel » 04 Jan 2007, 01:17

Bonjour,

c'est pour vous annoncer que le problème est résolu (en même temps j'ai modifié des choses horrible dans mon code, comme l'inversion entre Focalisation et Position, et aussi que Focalisation est un point et non un vecteur ... etc)

Le problème venait de ma matrice Projection, j'avais une Z-value of the near view-plane. trop grosse, alors quand mon triangle tourné et que la valeur etait en dessous de 1.0 tous disparaissait :).
Avatar de l’utilisateur
Gabriel
 
Messages: 311
Inscription: 25 Fév 2006, 10:15


Retourner vers Programmation

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 9 invités

cron