Comment faire pour obtenir les coordonnées du frustum? [D3D] - Programmation
Marsh Posté le 23-03-2002 à 12:33:31
bin t'appliques ta matrice de vue à un tableau de x,y,z qui contiennent les sommets du frustum ?
Marsh Posté le 23-03-2002 à 12:35:13
t'es bien sûr d'avoir compris les repères ? les coordonnées du frustum sont toujours les mêmes dans le repère caméra - pour les chopper dans le repère monde, il faut les transformer par l'inverse de la matrice view.
Marsh Posté le 23-03-2002 à 12:44:20
bin tu calcules l'inverse de la matrice view
c pour tester ton frustum avec tes AABB ?
Marsh Posté le 23-03-2002 à 20:33:43
Oui c'est pour tester mes AABB. Déjà juste pour être sûr que ma base soit bonne, pouvez-vous vérifier si les coordonnées des points du frustum sont justes?
x, y et z représentent la position de la caméra, celle-ci étant dirigée vers l'axe Z positif et avec sa normal vers l'axe Y positif.
Les points 0, 1, 2 et 3 sont la face avant du frustum, les autres les points de la face arrière.
pParent->vPointsOfFrustum[0] = D3DXVECTOR3(-nNearZ * cosf(nFovX / 2) + x,
-nNearZ * cosf(nFovY / 2) + y,
nNearZ + z);
pParent->vPointsOfFrustum[1] = D3DXVECTOR3(nNearZ * cosf(nFovX / 2) + x,
-nNearZ * cosf(nFovY / 2) + y,
nNearZ + z);
pParent->vPointsOfFrustum[2] = D3DXVECTOR3(-nNearZ * cosf(nFovX / 2) + x,
nNearZ * cosf(nFovY / 2) + y,
nNearZ + z);
pParent->vPointsOfFrustum[3] = D3DXVECTOR3(nNearZ * cosf(nFovX / 2) + x,
nNearZ * cosf(nFovY / 2) + y,
nNearZ + z);
pParent->vPointsOfFrustum[4] = D3DXVECTOR3(-nFarZ * cosf(nFovX / 2) + x,
-nFarZ * cosf(nFovY / 2) + y,
nFarZ + z);
pParent->vPointsOfFrustum[5] = D3DXVECTOR3(nFarZ * cosf(nFovX / 2) + x,
-nFarZ * cosf(nFovY / 2) + y,
nFarZ + z);
pParent->vPointsOfFrustum[6] = D3DXVECTOR3(-nFarZ * cosf(nFovX / 2) + x,
nFarZ * cosf(nFovY / 2) + y,
nFarZ + z);
pParent->vPointsOfFrustum[7] = D3DXVECTOR3(nFarZ * cosf(nFovX / 2) + x,
nFarZ * cosf(nFovY / 2) + y,
nFarZ + z);
[jfdsdjhfuetppo]--Message édité par Alload--[/jfdsdjhfuetppo]
Marsh Posté le 25-03-2002 à 10:35:44
ça semble correct, mais en calculant dans des variables intermémdiaires tu peux simpliflier la lecture, et réduire le temps de calcul (là on s'enfout, vu la fréquence d'éxécution de ce code, mais c lourd à la lecture)
nvx=nNearZ*cos(fovx/2);
nvy=nNearZ*cos(fovy/2);
fvx=nFarZ*cos(fovx/2);
fvy=nFarZ*cos(fovy/2);
pi tu mets tes D3DXVECTOR3(-nvx,nvy,nNearZ).... etc.. etc..
pourquoi tu as un +x +y +z, tu déplaces ton frustum de temps en temps ?
a ta place je génèrais les sommets du frustum gentilment pas transformé dans un tableau, puis le tableau est transformé dans un tableau temporaire...
Marsh Posté le 25-03-2002 à 19:11:43
Les x, y et z c'étaient des petites erreurs que j'ai corrigé depuis
Bah mon frustum il marche bien maintenant, du moment que je ne fais que le translater parce que je gère toujours pas les rotations Mais bon, j'y travaille, enfin j'essaie de trouver une méthode quoi
Marsh Posté le 25-03-2002 à 20:03:44
Lors des rotations, j'ai l'impression que ma boite contenant le frustum s'aggrandit de trop. Peut-être que ce n'est qu'une impression, mais je préfèrerais être sûr. Donc si vous pouviez voir en gros ma méthode et me dire si quelque chose cloche:
//Matrice inverse de la matrice de vue actuelle
D3DXMATRIX mInverseView;
D3DXMatrixInverse(&mInverseView, NULL, &pParent->mViewMatrix);
//Nouvelle position du centre de la boite en utilisant la position d'origine
D3DXVECTOR3 vNewFrustumPosition;
D3DXVec3TransformCoord(&vNewFrustumPosition, &pParent->vPosition, &mInverseView);
pParent->pFrustumBox->SetPosition(&vNewFrustumPosition);
//Calcul des nouveaux sommets du frustum en utilsant les sommets d'origne
D3DXVECTOR3 vPoint0, vPoint1, vPoint2, vPoint3, vPoint4, vPoint5, vPoint6, vPoint7;
D3DXVec3TransformCoord(&vPoint0, &pParent->vPointsOfFrustum[0], &mInverseView);
D3DXVec3TransformCoord(&vPoint1, &pParent->vPointsOfFrustum[1], &mInverseView);
D3DXVec3TransformCoord(&vPoint2, &pParent->vPointsOfFrustum[2], &mInverseView);
D3DXVec3TransformCoord(&vPoint3, &pParent->vPointsOfFrustum[3], &mInverseView);
D3DXVec3TransformCoord(&vPoint4, &pParent->vPointsOfFrustum[4], &mInverseView);
D3DXVec3TransformCoord(&vPoint5, &pParent->vPointsOfFrustum[5], &mInverseView);
D3DXVec3TransformCoord(&vPoint6, &pParent->vPointsOfFrustum[6], &mInverseView);
D3DXVec3TransformCoord(&vPoint7, &pParent->vPointsOfFrustum[7], &mInverseView);
//On cherche les points les plus éloignés par rapport
//au centre de la boite sur chaque axe
float temp;
float ex = fabsf(vPoint0.x - vNewFrustumPosition.x);
float ey = fabsf(vPoint0.y - vNewFrustumPosition.y);
float ez = fabsf(vPoint0.z - vNewFrustumPosition.z);
temp = fabsf(vPoint1.x - vNewFrustumPosition.x); if (temp > ex) ex = temp;
temp = fabsf(vPoint1.y - vNewFrustumPosition.y); if (temp > ey) ey = temp;
temp = fabsf(vPoint1.z - vNewFrustumPosition.z); if (temp > ez) ez = temp;
temp = fabsf(vPoint2.x - vNewFrustumPosition.x); if (temp > ex) ex = temp;
temp = fabsf(vPoint2.y - vNewFrustumPosition.y); if (temp > ey) ey = temp;
temp = fabsf(vPoint2.z - vNewFrustumPosition.z); if (temp > ez) ez = temp;
temp = fabsf(vPoint3.x - vNewFrustumPosition.x); if (temp > ex) ex = temp;
temp = fabsf(vPoint3.y - vNewFrustumPosition.y); if (temp > ey) ey = temp;
temp = fabsf(vPoint3.z - vNewFrustumPosition.z); if (temp > ez) ez = temp;
temp = fabsf(vPoint4.x - vNewFrustumPosition.x); if (temp > ex) ex = temp;
temp = fabsf(vPoint4.y - vNewFrustumPosition.y); if (temp > ey) ey = temp;
temp = fabsf(vPoint4.z - vNewFrustumPosition.z); if (temp > ez) ez = temp;
temp = fabsf(vPoint5.x - vNewFrustumPosition.x); if (temp > ex) ex = temp;
temp = fabsf(vPoint5.y - vNewFrustumPosition.y); if (temp > ey) ey = temp;
temp = fabsf(vPoint5.z - vNewFrustumPosition.z); if (temp > ez) ez = temp;
temp = fabsf(vPoint6.x - vNewFrustumPosition.x); if (temp > ex) ex = temp;
temp = fabsf(vPoint6.y - vNewFrustumPosition.y); if (temp > ey) ey = temp;
temp = fabsf(vPoint6.z - vNewFrustumPosition.z); if (temp > ez) ez = temp;
temp = fabsf(vPoint7.x - vNewFrustumPosition.x); if (temp > ex) ex = temp;
temp = fabsf(vPoint7.y - vNewFrustumPosition.y); if (temp > ey) ey = temp;
temp = fabsf(vPoint7.z - vNewFrustumPosition.z); if (temp > ez) ez = temp;
pParent->pFrustumBox->SetExtents(ex, ey, ez);
[jfdsdjhfuetppo]--Message édité par Alload--[/jfdsdjhfuetppo]
Marsh Posté le 25-03-2002 à 22:44:56
Alload a écrit a écrit : Lors des rotations, j'ai l'impression que ma boite contenant le frustum s'aggrandit de trop. Peut-être que ce n'est qu'une impression, mais je préfèrerais être sûr. |
j'ai pas regarde ton code, par contre je peux te dire
que lorsqu'un frustum tourne, son AABB change de taille.
LEGREG
Marsh Posté le 26-03-2002 à 07:04:18
legreg a écrit a écrit : j'ai pas regarde ton code, par contre je peux te dire que lorsqu'un frustum tourne, son AABB change de taille. LEGREG |
Je sais, la dernière partie du code s'occupe de ça, elle compare la distance entre le centre du frustum et chacun des sommets et ce sur chaque axe.
Marsh Posté le 26-03-2002 à 07:05:34
Mais doit quand même avoir un petit problème, j'ai l'impression que le frustum s'aggrandit de trop quand il y a des rotations...
Marsh Posté le 23-03-2002 à 12:23:31
Au départ, c'est pas compliqué d'obtenir les coordonnées des 8 sommets du frustum, mais une fois qu'on a tourné la caméra plusieurs fois et qu'on l'a déplacé dans plusieurs directions c'est une autre affaire...
Quand je veux tourner ma caméra ou la translater, je multiplie la matrice de vue par la matrice du mouvement et j'actualise la matrice de vue. Comment pourrais-je maintenir une trace des 8 sommets du frustum après chaque transformation?