camera - Algo - Programmation
Marsh Posté le 31-03-2006 à 22:13:28
cheloo ton algo.
une caméra basique possède:
et il me semble que tu as tout ça, sauf que tu mélange les transformations du point avec celles de la caméra.
Marsh Posté le 31-03-2006 à 22:18:53
ça donne:
dessiner(projection(translation(rotation(point))))
Marsh Posté le 01-04-2006 à 02:38:49
Oui c'est vrai il y a une camera dans ce pseudo code, mais elle est fixe.
Pour moi elle est dans les formule de projection.
Elle permet juste de zoomer (avancer & reculer j'imagine, mais je n'ai pas abordé le clipping avec ce genre de routine) ou d'aller à gauche ou droite. Le genre d'algo classique pour afficher un cube et faire une rotation. (ici c'est donc l'objet qui tourne sur l'axe 0,0,0 et pas la camera)
Il n'y a pas de notion de lookat ici, ni de target (etc) ce que j'ai pu voir sur differents tutos. Je rame pour implanter tout çà!
Pour la camera, j'ai essayé d'implanter deja un "fov" meme si ce ne doit pas etre la bonne technique. J'ai donc une map 2D avec un vecteur avec lequel je me balade via mon clavier. J'ai les coordonnées x,y et l'angle.
Enfin bref entre afficher un objet et un monde il y a imperativement la camera à placer. J'aimerai afficher un monde 3D statique (sans rotations d'objet sur leur axe)
En plus j'ai vu qu'un clipping d'objets devient aisé avec une "vraie" camera (genre if z < 0)
Marsh Posté le 01-04-2006 à 09:07:25
puisque tu fait déjà une rotation et une projection, il te reste plus qu a mettre une translation entre les deux, c est pas compliqué c est une addition.
Marsh Posté le 01-04-2006 à 14:58:14
Comme je ne suis jamais été au dela de la simple rotation d'objet, je modifiais directement les vertices pour faire la translation. (addition effectivement, en tout début, avant de passer à la rotation etc)
Mais ici ma rotation est sur un axe fixe. C'est comme si je n'avais pas de camera.
Elle doit être implementée avec tout un tas de vecteurs.
J'essaye de comprendre ce tuto en ce moment
http://www.cubic.org/docs/camera.htm
crossproduct, normalisation: je n'ai rien de ça dans mon pseudo code
Pour l'instant j'ai dev ça:
J'ai franchement besoin d'un coup de pouce.
Up.x = sin(AngleCam)
Up.y = - cos(AngleCam)
Up.z = 0
--> normalize le vecteur
fowardNorm = sqrt( ((Up.x)^2) + ((Up.y)^2) + ((Up.z)^2) )
mais à quoi sert ce fowardNorm? Surement à dev les matrices plus bas, mais on ne vois pas fowardNorm
Donc ca ne doit pas etre bon mon calcul. Je dois avoir un forward.x forward.y forward.z ?
Bref si je comprend deja cette partie, je devrais aborder la suite plus facilement
!1 !2 !3 sont les points x,y,z des objets dans le monde
--> Le crossproduct
Ga = (!2 * Up.z) - (!3 * Up.y)
Gb = (!3 * Up.x) - (!1 * Up.z)
Gc = (!1 * Up.y) - (!2 * Up.x)
normalize_vectorR = sqrt( ((Ga)^2) + ((Gb)^2) + ((Gc)^2) )
Est ce correcte? Que faut il faire ensuite, j'imagine qu'il faut dev les matrices en dessous: dur dur
J'aurais besoin que du stricte minimum, inutile de dev toutes les rotations par exemple: c'est pour obtenir un visuel proche du raycasting, à la wolfenstein
Marsh Posté le 01-04-2006 à 15:45:24
Je connais pas de tutos en ligne.
Mais avant d aborder la 3D, il y certaines propriétes mathématiques que tu doit connaître sur les vecteurs.
La addition des vecteurs, tu la connait, c est simple. Par contre ça se corse avec les multiplications: il y en a 3 possibles. Ensuite il y a la norme d un vecteur, et plus généralement sa distance.
1°) multiplication/division par un nombre
ça c est facile, tu multiplie chacun des composantes par un nombre k et tu obtient un vecteur k fois plus long, si le signe de k est négatif tu obtient un vecteur dans la direction opposée
2°) le produit vectoriel fonctionne avec deux vecteurs, il donne un troisième vecteur perpendiculaire à la fois aux deux autres. Le produit vectoriel est utilisé par exemple pour calculer un vecteur normal à plan définit par trois points.
Ex: une facette [ABC], son vecteur normal <n> est:
<n>=<AB>x<AC>
Les vecteurs normaux sont très utiles pour calculer les illuminations, ou tout simplement pour orienter les facette et ainsi les éliminer lorsquelle ne sont pas orientées vers la caméra.
Un vecteur normal définit aussi un générateur de plan: l ensemble des vecteurs dont le produit vectoriel est propotionel à la normale. Un vecteur + un point te donne un plan.
La longueur du vecteur issu d un produit vectoriel est égal à la multiplication des deux autres longueurs. Ça peut être utile pour déterminer l aire de parallélogrammes.
3°) le produit scalaire. le produit scalaire de deux vecteurs donne un nombre. Ce nombre vérifie la formule:
<a>.<b> = |a|*|b|*cos(a,b)
comme |a|*|b| est positif, le signe du produit scalaire est celui de cos(a,b), c est à dire que si les deux vecteurs originaux sont co-spatiaux (ils pointent dans la même direction) le signe est positif, s ils pointent dans la direction opposée le signe est négatif, s ils sont prependiculaires le produit scalaire est nul (0).
C est très pratique pour déterminer si une facette orientée est face à la caméra:
facette [ABC], camera au point de visualisation V:
<n>=(<AB>x<AC> )*orientation
[ABC] orienté vers la caméra si:
<n>.<VA> < 0
ou <n>.<VB> < 0
ou <n>.<VC> < 0
En conjonction avec la normalisation d un vecteur, tu obtient le cosinus entre deux vecteur:
|a|=|b|=1 => <a>.<b>=cos(a,b)
et c est utile pour déterminer le coefficient d illumination (l illumination d un plan est propotionnel au cosinus entre la normale à un plan et la direction de la lumière).
La longueure d un vecteur <x,y,z> est égale à:
|x,y,z| = sqrt( x²+y²+z² )
Si on divise les coordonnées d un vecteur par la longueure, on obtient un vecteur unitaire, c est à dire de longeure 1:
| <x,y,z>/|x,y,z| | = 1
On peut obtenir un vecteur normal unitaire à un plan [ABC]:
<n>=<AB>x<AC>
<u>=<n>/|n|
qui est très pratique pour pleins de calculs.
Il existe d autres longueure possibles: on les appelle distance d ordre n:
Dn(<x,y,z> )= ( |x^n| + |y^n| + |z^n| ) ^ (1/n)
(note: ici || est la valeur absolue)
La norme ou longeur d un vecteur est sa distance d ordre 2, mais il d autres peuvent être pratique, notamment la distance d ordre 1, appelée aussi distance de manhattan:
D1(<x,y,z> ) = |x|+|y|+|z|
Pour les matrices, une matrice 4x4 peut définir tous les types de transformations simples: rotations, translations, projection, échelle, étirement, homothéties... Une matrice de transformation multipliée par une autre donne une troisième matrice de transformation regroupant les deux premières. Multiplier un vecteur par une matrice de transformation donne un vecteur transformé.
Les transformations simples ont une transformation inverse, pour laquelle un vecteur transformé donne le vecteur originel.
Ça c est la théorie. Dans la pratique le calcul des racines carrées et lent sur les microprocesseurs donc à éviter.
Les cosinus et sinus sont encore plus lents, si bien que parfois une table est précalculée.
Idem pour les matrices, elles ne sont finalement utiles que dans les modeleurs 3D qui permettent de garder en mémoire et de modifier toute une chaîne de transformations.
Pour le raycasting (transformation d une carte 2D en visualisation 3D) tu devrais trouver des algos en vrac sur le net.
Deux types de raycasting: style wolfestein (carte carré), style doom (carte polygonale). Un algo qui ressemble au raycasting est la modélisations par carte 2D de voxels.
> je modifiais directement les vertices pour faire la translation.
- jamais faire ça, ça limite considérablement les possibilités de ta carte (re-calcul de toute la carte), et en plus si tu a des calculs en virgule flottante ça introduit des erreurs cumulatives de calculs.
Marsh Posté le 31-03-2006 à 21:55:43
J'arrive a faire tourner mes triangles dans tous les sens (faces cachées et remplissage) mais je bloque vraiment pour implanter une camera. ("Third-Person Camera" ) Je sais donc juste faire tourner des objets.
Je me perd dans les tutos depuis 2 mois, souvent à cause du langage, ou trop de fonctions imbriquées pour que je comprenne.
Je suis noyé dans l'open gl etc, je cherche un algo basique en "soft", la camera la plus simple possible (evitant le max de matrices, calculs ... Je me contenterais bien d'une vue style raycasting wolfenstein)
Si quelqu'un peut me donner un coup de pouce en pseudo code. Ne serait ce que les premiers trucs à faire pour l'implantation de la camera pour que je puisse demarrer ma routine.
Ce pseudo code dessine juste un point. J'appelerai ce point A(2,-1,-1)
Il passe par la routine de rotation qui ensuite envois le resultat à la projection
pour passer à l'instruction suivante dans le procedure principale: il dessinne le point
ici !1 = 2 !2 = -1 et !3 = -1 (Rotation 2 -1 -1)
Les fonctions sont en degres.
Pour la camera, je connais ses coordonnée x,y dans le "monde"
Car j'ai un autre code, une sorte de FOV 2D (de 60°) avec des blocs de couleurs pour faire du "wall detection"
(un peu comme du raycasting)
Procedure Principale
{
Rotation 2 -1 -1
Dessine un point x2 y2
}
Procedure Rotation
{
x = !1 * cos(angle) + !3 * sin(angle)
y = !2
z = !3 * cos(angle) - !1 * sin(angle)
Projection x y z
}
Procedure Projection
{
zoom = 10
x_offset = 320
y_offset = 200
x2 = 256 * ( x / (z +zoom) ) + x_offset
y2 = 256 * ( y / (z +zoom) ) + y_offset
}