1

Salut tout le monde;
Ben voilà, le titre dit tout. J'ai un rotozoom, dont le facteur K d'horizon est calculé en fonction de la ligne de l'écran que je suis en train de balayer... maintenant j'aimerais pouvoir trouver les positions d'un sprite (dont je connais X et Z) sur mon écran en tenant compte du rotozoom.
(Comparable au placement des coureurs sur la piste de Mario Kart)...
Malheureusement, je ne trouve rien sur internet et je croche. Quelqu'un pourrait-il m'aider en m'indiquant la marche à suivre pour trouver la formule SVP?
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

2

Tu connais la position de la caméra, son orientation, et la position du sprite ?
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

3

Oui. Je connais la position x,y,z,alpha de la caméra (je préfère ne pas utiliser y car il est fixe) et le x,z,alpha du sprite.
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

4

Tu projètes la position de l'objet dans le repère dont l'origine est la caméra, orienté d'un angle alpha par rapport au repère "monde", puis tu projètes cette nouvelle position du sprite (relative à la caméra) dans le repère "écran", sachant que l'écran est perpendiculaire à l'axe z (ou y, ça dépend de tes conventions).
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

5

Heu... désolé mais tu ne pourrais pas "vulgariser" stp un peu tes explications parce qu'on n'a certainement pas le même niveau en maths. wink
Et puis je n'arrive pas à "projeter" mon point sur l'axe Z puisque je n'arrive pas à partir d'une distance Z de la caméra à retrouver le point y sur l'écran 2D puisqu'il faut appliquer l'inverse du facteur K (et c'est mon problème).
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

6

Voici la source de mon rotozoom. Il est peut-être incorrect... void RotoPiste(OBJET *obj, int x1, int y1, double x1p, double y1p, double facteur, double t)          {      int centrex,centrey,dmax, min_x,max_x,min_y,max_y;      register int x, y, l=obj->largeur, h=obj->hauteur;      register double cosTf,sinTf, xp, yp;      double fact, cosT, sinT;      int taille;      register unsigned char *sprite=obj->sprite;      register unsigned int lr=obj->largeur;      cosT = cos(t)/facteur;      sinT = sin(t)/facteur;      centrex=x1;      centrey=y1;      min_x=max(centrex-dmax,0);      max_x=min(centrex+dmax,CLIP_X1-CLIP_X0-1);      min_y=max(centrey-dmax,0);      max_y=min(centrey+dmax,CLIP_Y1-CLIP_Y0-1);      taille=max_y-min_y;      max_y=320;      for (y=min_y;y<max_y;y++)          {           fact=(float)max_y/(y-min_y);           if (fact==0.0)                continue;           cosTf=cosT*fact;           sinTf=sinT*fact;           xp = (min_x-x1) * cosTf + (y-y1) * sinTf + x1p + 0.25;           yp = (y-y1) * cosTf - (min_x-x1) * sinTf + y1p + 0.25;           for (x = min_x; x <= max_x; x++)           {                if (xp>=0 && xp<l && yp>=0 && yp<h)          {                     DessPixInvMasque(x,y,SpriteGetPix(sprite,(int)xp,(int)yp,lr));                }                xp += cosTf;                yp -= sinTf;           }      } }
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

7

Tu utilises des nombre à virgule flottante ?
C'est possible de beaucoup optimiser si tu passes en virgule fixe (avec un décalage de 16 bits par exemple).

Sinon, pour mon explication :
La caméra et l'objet à afficher ont une position par rapport à un repère qu'on appellera le repère monde.
L'idée est de considérer la caméra elle-même comme un repère, d'obtenir les coordonnées de l'objet dans ce repère et de les projeter à l'écran, car l'écran est lié à la caméra (il y a peut-être plus simple, c'est juste une idée).
Je te fais un dessin.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

8

Alors, voici comment résumer la situation :
mondeverscam.png
Ton but est de connaître les coordonnées p.x' et p.z', je les ai représentés en pointillés rouges.
Il faut donc projeter le vecteur p (en bleu) successivement sur z' et x'.
it scalaire (en supposant que z' et x' sont des vecteurs unitaires) : p.z' = p.x*z'.x + p.z*z'.z p.x' = p.x*x'.x + p.z*x'.zTu peux réaliser cette opération en utilisant le produfacilement les composantes de p dans le repère monde (p.x et p.z) : p = objet - cameraTu peux connaitre Où objet est la position de l'objet dans le repère monde, et camera, celle de la caméra.
Et tu peux déterminer les composantes des vecteurs z' et x' dans le repère monde en utilisant des jolies fonctions trigonométriques.
ou sens horaire), tu auras ces formules là :x'.x = cos alpha x'.z = -sin alpha z'.x = sin alpha z'.z = cos alphaEn supposant que tes rotations se font dans le sens non trigonométrique (a, voici les formules dont tu auras besoin :p.x' = p.x*sin alpha + p.z*cos alpha p.z' = p.x*cos alpha - p.z*sin alphaDonc au final, pour avoir les coordonnée de ton objet dans le repère camérEnsuite, pour projeter ça à l'écran, ce n'est pas compliqué, tu devrais savoir le faire je suppose, mais si tu ne sais pas, demande moi, je te ferai un autre shéma smile
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

9

Merci beaucoup.
Par contre j'avais *à peu près* trouvé la même chose mais je ne pouvais pas le prouver avec les formules mathématiques comme toi.
Non, justement le problème est le fait de reporter (projeter) ces positions à l'écran... je n'arrive pas à calculer Z à partir de mon facteur K (sans compter que X n'est pas exact dans tous les cas non-plus, mais c'est parce que je ne le multiplie pas par K) sachant que je sais que mon objet est à distZ pixels de ma caméra (chez toi p.z') mais je ne sais pas comment trouver combien ça correspond sur l'écran. Note, dans ma source, il y a:
fact=(float)max_y/(y-min_y);
C'est comme ça que je calcule le facteur K.
Merci beaucoup encore.
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

10

Et tu disais quoi ?
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

11

A peu près la même chose que sur le post 8 que j'ai édité et complété grâce à tes explications. wink
Là tu vois:
rotozoom1.png
(je suis temporairement passé sur PC pour pouvoir déboguer) la caméra fixe le point 0,0 (entouré en rouge) mais je n'arrive pas à calculer ses positions (je peux en hackant par débogage puisque ces points sont constants (0.5*largeur, 0.7125*hauteur)
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

12

Comment as-tu réussi à obtenir des formules compliquées sans procéder par étapes ? confus
Juste un détail, parce que je ne suis pas sûr que nos repères soient les mêmes : les axes x et z sont horizontaux et l'axe y est vertical. Et dans le repère caméra, l'axe z correspond à la direction dans laquelle est orientée la caméra.

Bon, pour la projection, c'est tout con, un gamin de 4ème peut faire ça (ou 3ème, je ne sais plus, enfin, j'utilise le théorème de Thalès). Je te fais un shéma...
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

13

Oui merci smile
Ben si on a un plan plat (2D) les coordonnées sont X et Z (au lieu de x et y en 2D). Le Y c'est la dimension supplémentaire, c'est-à-dire la hauteur wink
Et le théorème de thalès ne suffira certainement pas (tu oublies le facteur K?)
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

14

Bon, le shéma est un peu moche : camversecran.pngJ'explicite certaines choses :
Objet est l'objet que tu veux afficher à l'écran, dont les coordonnées (o.x et o.z) sont exprimées dans le repère caméra (elles correspondent aux p.x' et p.z' de toute à l'heure).
dov est la distance entre la caméra et l'écran. On l'appelle la distance focale. Si l'écran fait 160 pixels de largeur (sur 89 par exemple), et que le champ de vision de la caméra couvre 90° degrés, la distance entre l'écran et la caméra est de 80 (donc dov=80 dans ce cas).
On cherche à déterminer o.x' qui correspondra à la coordonnée x du point, à l'écran (en supposant que le point de coordonnées (0;0) est au centre de l'écran eet pas en haut à gauche, mais on peut remédier ça en ajoutant LCD_WIDTH/2 à o.x').
Donc, on connaît o.z, o.x et dov.
llèle à l'axe x de la caméra, donc on a, d'après le théorème de Thalès : dov/o.z=o.x'/o.xL'écran est paraov/o.zD'où :o.x' = o.x*d
Le principe est le même pour y. Il faut avoir o.y dans le repère caméra (= la composante y de l'objet dans le repère monde moins la composante y de la caméra [toujours dans le repère monde]).
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

15

Vraiment désolé mais... euh... X je l'avais déjà (il me reste encore à trouver le facteur K de la ligne sur laquelle il se trouve). Mon problème c'est Y.
En fait ce n'est certainement pas si compliqué que ça. Je vais essayer de l'exposer simplement:
Pour dessiner mon rotozoom, je prends x et y sur toutes les valeurs de l'écran. Je calcule xp, yp et k en fonction de x et y. K est fonction de y.
Maintenant j'ai le cas inverse: j'ai xp et yp. Je pourrais trouver x et y mais je reste bloqué avec K car je ne le connais pas à l'avance... car il me faudrait savoir à l'avance sur quelle ligne de l'écran le sprite se trouve, mais ça je ne sais pas non-plus. Je vais essayer un monstre solve... Ben non. Ca me donne pas le résultat. sad
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

16

Je ne sais pas à quoi correspond ton facteur K, donc je ne peux pas t'aider, mais avec ce que je viens de t'écrire plus haut, tu devrais être capable de déterminer y.
Fais un shéma comme le mien, et tu trouveras tout de suite.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

17

En fait j'ai fait une connerie en Y. J'ai mis HAUT/2 (HAUT est la hauteur de l'écran avec ma librairie) sauf que j'ai ouvert une fenêtre graphique 138 pixels plus bas jusqu'au fond (la fenêtre du rotozoom, celle des infos du compteur sont sur la première, du haut jusqu'au 138). Donc le voy chez moi était en fait HAUT/2 (càd (138+320)/2) alors que ça aurait du être 320/2. Tout s'explique #ouf#
En fait je vais prendre voy=320 (hauteur maximale de mon rotozoom), c'est une bonne idée?
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741