Annonce

>>> Bienvenue sur codelab! >>> Première visite ? >>> quelques mots sur codelab //// une carte des membres//// (apéros) codelab


#1 2013-02-22 18:06:55 Rotation caméra scène 3D

Marty
membre
Date d'inscription: 2012-04-27
Messages: 143

Rotation caméra scène 3D



Bonjour à toutes et à tous.

J'avance dans ma prise en main de Processing.
J'ai commencé un projet pour mettre mes connaissances à l'épreuve. J'avais déja posté une question ici : http://codelab.fr/4018#p21462

J'avance donc et j'arrive à une deuxième étape : me déplacer autour de l'objet. La c'est plus un problème de mathématiques (trigonométrie) que de programmation auquel je me confronte.

J'ai simplifié le code du post cité ci dessus pour n'avoir qu'un cube au centre de ma fenêtre, ça me permet de me concentrer sur la problématique de la caméra. J'affiche donc un cube. La sphère au milieu du cube matérialise le centre de la scène. C'est ici que je place le cube et le point fixé par ma caméra.

Je souhaite pouvoir bouger la caméra dans l'espace avec la souris :

- avec un gauche droit et déplacement horizontal : je tourne autour du cube de droite à gauche.
- avec un gauche droit et déplacement vertical : je tourne autour du cube de haut en bas.
- avec un clic droit et déplacement vertical : je zoome et dézoome.

voila ce que j'obtiens :

int cubeSize = 150;

int winSizeX = 640;
int winSizeY = 480;

//center
int cx = winSizeX/2;
int cy = winSizeY/2;
int cz = -cubeSize/2;

//camera positions
float camEyeX = 0;
float camEyeY = 0;
float camEyeZ = 0;
float viewX = cx;
float viewY = cy;
float viewZ = cz;
float camUpX = 0;
float camUpY = 1;
float camUpZ = 0;

//Polar coordinates
float theta = 90;      
float phi = 0;       
float rho = 200;   //distance from cam to point of view

void setup(){
size(winSizeX,winSizeY, P3D);
lights();
}

void draw(){
  background(0);
  stroke(255);
  noFill();
  updateCamPosition();
  camera(camEyeX,camEyeY,camEyeZ,viewX,viewY,viewZ,camUpX,camUpY,camUpZ);
  translate(cx,cy,cz);
  sphere(2);
  box(cubeSize);
}

void updateCamPosition(){

    camEyeX = rho * sin(radians(theta)) * sin(radians(phi));
    camEyeY = rho * cos(radians(theta));
    camEyeZ = rho * sin(radians(theta)) * cos(radians(phi));
    
}


void mouseDragged(){
  if (mouseButton == LEFT){
    theta = theta + (pmouseY - mouseY);
    phi = phi - (pmouseX - mouseX);
  }
  
  if (mouseButton == RIGHT){
    rho = rho - (pmouseY - mouseY);    
  }
}

Mais au final les déplacement sont très chaotiques !
Je dois avoir un pb dans la gestion des coordonnées mais je ne trouve pas la faille.
Si quelqu'un peut me venir en aide ?

PS : au cours de mes "révisions" de trigo, je m'apperçois que la norme concernant les coordonnées polaires à un axe Z vers le haut. Est-ce le cas dans Processing ?

Dernière modification par Marty (2013-02-22 18:09:03)

Hors ligne

 

#2 2013-02-23 08:37:57 Re : Rotation caméra scène 3D

cgiles
membre
Lieu: Est de la France
Date d'inscription: 2005-05-25
Messages: 329

Re: Rotation caméra scène 3D



Moi quand je veux me déplacer en caméra  3d, j'ai recours a ça : http://gdsstudios.com/processing/libraries/ocd/
C'est une librairie qui gère le déplacement de la caméra 3d, très utile

Dernière modification par cgiles (2013-02-23 08:38:19)

Hors ligne

 

#3 2013-02-23 12:04:39 Re : Rotation caméra scène 3D

Marty
membre
Date d'inscription: 2012-04-27
Messages: 143

Re: Rotation caméra scène 3D



Merci pour l'info,

J'ai déja scruté des solutions via des librairies. Il existe aussi PEasyCam qui fait le boulot.

Mais la comme je débute j'aimerais essayer de construire quelque chose en passant le moins possible par les librairies externes histoire de savoir ce que je fais. Une fois que je "maitriserai" quelques règles je pourais me passer de réinventer la roue...

Dans l'exemple donné je pense avoir bon mais ca marche pas comme escompté...

Hors ligne

 

#4 2013-02-23 12:46:18 Re : Rotation caméra scène 3D

Marty
membre
Date d'inscription: 2012-04-27
Messages: 143

Re: Rotation caméra scène 3D



Bon j'ai repéré le problème, il s'agit d'un problème de repère d'origine.
Dans mon premier post je décale l'origine par un translate() pour me positionner au milieu de la fenêtre et c'est cela qui semble coincer. Si je dessine tout au point de coordonnées (0,0,0) cela fonctionne.

PS : au passage j'ai corrigé les calculs des coordonnées de rotation de la caméra pour les faire correspondre à un axe XY dans le plan de l'écran et Z en profondeur. Les calculs que j'ai trouvé sont habituellement faits pour un repère YZX.

Le code est donc maintenant comme suit. Si quelqu'un peut m'expliquer l'erreur commise sur le translate() ?

int cubeSize = 150;

int winSizeX = 640;
int winSizeY = 480;

//center
int cx = winSizeX/2;
int cy = winSizeY/2;
int cz = -cubeSize/2;

//camera positions
float camEyeX = 0;
float camEyeY = 0;
float camEyeZ = 0;
float viewX = 0;
float viewY = 0;
float viewZ = 0;
float camUpX = 0;
float camUpY = 1;
float camUpZ = 0;

//Polar coordinates
float theta = 90;      
float phi = 0;       
float rho = 350;   //distance from cam to point of view

void setup(){
size(winSizeX,winSizeY, P3D);
}

void draw(){
  background(0);
  stroke(255);
  noFill();
  updateCamPosition();
  camera(camEyeX,camEyeY,camEyeZ,viewX,viewY,viewZ,camUpX,camUpY,camUpZ);
  //translate(cx,cy,cz);
  sphere(2);
  box(cubeSize);
}

void updateCamPosition(){

    camEyeX = rho * cos(radians(theta)) * cos(radians(phi));
    camEyeY = rho * sin(radians(theta));
    camEyeZ = rho * cos(radians(theta)) * sin(radians(phi));
    
}

void mouseDragged(){
  if (mouseButton == LEFT){
    theta = theta + (pmouseY - mouseY);
    phi = phi - (pmouseX - mouseX);
  }
  
  if (mouseButton == RIGHT){
    rho = rho - (pmouseY - mouseY);    
  }
}

Hors ligne

 

#5 2013-02-24 11:00:36 Re : Rotation caméra scène 3D

Mushussu
membre
Lieu: Orléans
Date d'inscription: 2012-05-24
Messages: 802

Re: Rotation caméra scène 3D



Voici une tentative d'explication :

int cubeSize = 150;

int winSizeX = 640;
int winSizeY = 480;

//center
int cx = winSizeX/2;
int cy = winSizeY/2;
int cz = 0;

//camera positions
float camEyeX = 0;
float camEyeY = 0;
float camEyeZ = 0;
float viewX = cx;
float viewY = cy;
float viewZ = cz;
float camUpX = 0;
float camUpY = 1;
float camUpZ = 0;

//Polar coordinates
float theta = 90;      
float phi = 0;       
float rho = 350;   //distance from cam to point of view

void setup() {
  size(winSizeX, winSizeY, P3D);
}

void draw() {
  background(0);
  stroke(255);
  noFill();
  updateCamPosition();
  camera(camEyeX, camEyeY, camEyeZ, viewX, viewY, viewZ, camUpX, camUpY, camUpZ);
  translate(cx, cy, cz);
  sphere(2);
  box(cubeSize);
}

void updateCamPosition() {
  camEyeX = rho * cos(radians(theta)) * cos(radians(phi)) + cx;
  camEyeY = rho * sin(radians(theta)) + cy;
  camEyeZ = rho * cos(radians(theta)) * sin(radians(phi));
}

void mouseDragged() {
  if (mouseButton == LEFT) {
    theta = theta + (pmouseY - mouseY);
    phi = phi - (pmouseX - mouseX);
  }

  if (mouseButton == RIGHT) {
    rho = rho - (pmouseY - mouseY);
  }
}

Mettre la coordonnée cz du centre à 0
Pointer la caméra sur le centre
Remettre le translate de l'objet
Translater la caméra dans le calcul des nouvelles coordonnées de celle-ci. En fait, le calcul des cooordonnées s'effectuaient autour du point zéro

Dis moi si cela fonctionne car un bug pour la version Mac m'empêche de tourner et de zoomer.

Dernière modification par Mushussu (2013-02-24 11:02:57)

Hors ligne

 

#6 2013-02-24 12:38:50 Re : Rotation caméra scène 3D

Marty
membre
Date d'inscription: 2012-04-27
Messages: 143

Re: Rotation caméra scène 3D



Merci Mushussu,

ça fonctionne effecivement, mais je ne comprend pas pourquoi dans mon exemple les coordonnées s'effectuent autour du point zéro ?

Le point de vue de la caméra est bien fixée à cx, cy, cz du coup la rotation de la caméra devrait se faire autour de ce point non ?

Dernière modification par Marty (2013-02-24 16:00:12)

Hors ligne

 

#7 2013-02-24 15:25:22 Re : Rotation caméra scène 3D

Mushussu
membre
Lieu: Orléans
Date d'inscription: 2012-05-24
Messages: 802

Re: Rotation caméra scène 3D



En fait tu entres dans la fonction caméra ses coordonnées en premier par rapport au point zéro. Donc comme les objet 3D ont comme origine le point zéro tout se passait bien.

Imagine une caméra réelle dans une pièce avec un rail de travelling circulaire. Si l'objet est au centre du cercle et que la caméra vise l'objet. Alors la caméra tournera autour de l'objet comme souhaité. Mais si l'objet est en dehors du cercle, bien que la caméra vise l'objet tu ne pourras pas tourner autour de l'objet. Il faut réaliser un changement d'origine.

Hors ligne

 

#8 2013-02-24 19:38:32 Re : Rotation caméra scène 3D

Marty
membre
Date d'inscription: 2012-04-27
Messages: 143

Re: Rotation caméra scène 3D



ok je vois mieux maintenant.
Du coup moi je faisais une translation pour mettre mon objet au centre de l'écran... mais avec une caméra cela devient inutile non ?

Ok donc pour cette problématique j'ai saisi. Maintenant ce n'était qu'un prototype simple pour "pratiquer" un peu la caméra. L'étape suivante c'est de remplacer le cube qui ne sera non pas un cube simple, mais composite : un cube formé par un ensemble de spheres (64 au total) qui me fera dont un cube de 4x4x4 sphères (cf mon premier post dans ce fil qui renvoie vers un autre post qui explique cela).

Par choix (la position des sphères doit correspondre à un modèle physique représenté aujourd'hui par un cube de leds mais qui sera à terme une structure plus importante), je construit le cube en commençant par la sphère en bas à gauche sur le plan le plus proche de la caméra, le comptage commence sur la profondeur (axe Z), puis en X et enfin en Y. (j'espère que tout cela est relativement clair !)

Le tout est construit à partir de l'origine (0,0,0).
Si je suis tes indications il faut donc décaler l'origine du point de vue de la caméra vers le centre de la structure et déplacer aussi la caméra en conséquence ?

petite illustration de ce que ça commence à donner ci-dessous".

A noter :
- pour des questions de performances de ma carte graphique j'ai remplacé les sphères par des cubes
- les cubes colorés représentent la face avant du cube avec le cube blanc = premier cube en bas à gauche quand on regarde le cube de face.
- pour m'aider visuellement j'ai représenté les axes : X (vert), Y (bleu), Z (rouge)

PS : déja je note un pb de placement de la caméra...

Led[] ledCube = new Led[64];

int cubeSize = 150;

int wWidth = 640;
int wHeight = 480;

//center
//int cx = wWidth/2;
//int cy = wHeight/2;
//int cz = -cubeSize/2;

//camera positions
float camEyeX = 0;
float camEyeY = 0;
float camEyeZ = 0;
float viewX = 0;
float viewY = 0;
float viewZ = 0;
float camUpX = 0;
float camUpY = 1;
float camUpZ = 0;

//Polar coordinates
float theta = 90;      
float phi = 0;       
float rho = 300;   //distance from cam to point of view

void setup(){
    int c = 0;
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
      for (int k = 0; k < 4; k++) {
        ledCube[c] = new Led(j, -i, -k, false, 120);
        c++;
      }
    }
  }
  size(wWidth,wHeight, P3D);
}

void draw(){
  background(0);
  pointLight(150,255,255,200,200,200);
  noLights();
  noStroke();
  noSmooth();
  fill(160);
  drawAxis();
  updateCamPosition();
  camera(camEyeX,camEyeY,camEyeZ,viewX,viewY,viewZ,camUpX,camUpY,camUpZ);
  drawCube();
}

class Led {
  int x;
  int y;
  int z;
  boolean isOn;
  color bColor;

  Led (int xPos, int yPos, int zPos, boolean state, color col) {
    x = xPos;
    y = yPos;
    z = zPos;
    isOn = state;
    bColor = col;
  }
  void display() {
    pushMatrix();
    translate(x * (cubeSize / 3), y * (cubeSize / 3), z * (cubeSize / 3));
    fill(bColor);
    box(3);
    popMatrix();
  }
}

void drawAxis(){
  stroke(0,255,0);
  line(0,0,0,100,0,0);
  stroke(0,0,255);
  line(0,0,0,0,100,0);
  stroke(255,0,0);
  line(0,0,0,0,0,-100);
  noStroke();
}

void drawCube() {
   for (int i = 0; i < 64; i++) {
    switch (i) {
     case 0 : ledCube[i].bColor = color(255,255,255); break;
     case 12 : ledCube[i].bColor = color(255,0,0); break;
     case 48 : ledCube[i].bColor = color(0,255,0); break;
     case 60 : ledCube[i].bColor = color(0,0,255); break;
    }
    ledCube[i].display();
  } 
}

void updateCamPosition(){
    camEyeX = rho * cos(radians(theta)) * cos(radians(phi));
    camEyeY = rho * sin(radians(theta));
    camEyeZ = rho * cos(radians(theta)) * sin(radians(phi));
    
      //Prevent flipping if camera moves past top or bottom of cube
      if ((theta > 90.0 && theta < 270.0) || (theta < -90.0 && theta > -270.0))
    {
      camUpY = -1.0;
    }
    else
    {
      camUpY = 1.0;
    }
}

void mouseDragged(){
  if (mouseButton == LEFT){
    theta = theta + (pmouseY - mouseY);
    phi = phi - (pmouseX - mouseX);
  }
  if (mouseButton == RIGHT){
    rho = rho - (pmouseY - mouseY);    
  }
}

Dernière modification par Marty (2013-02-24 19:41:52)

Hors ligne

 

#9 2013-02-24 20:12:02 Re : Rotation caméra scène 3D

Mushussu
membre
Lieu: Orléans
Date d'inscription: 2012-05-24
Messages: 802

Re: Rotation caméra scène 3D



Oui, ou bien centrer la structure autour du point zéro :

void display() {
    pushMatrix();
    translate(x * (cubeSize / 3) - cubeSize / 2, y * (cubeSize / 3) + cubeSize / 2, z * (cubeSize / 3) + cubeSize / 2);
    fill(bColor);
    box(3);
    popMatrix();
  }

Hors ligne

 

#10 2013-02-24 21:44:03 Re : Rotation caméra scène 3D

Marty
membre
Date d'inscription: 2012-04-27
Messages: 143

Re: Rotation caméra scène 3D



Je vois.

Pour une solution de changement d'axe plutôt que centrer la structure ça te semble juste ?

void draw() {

  background(0);
  pointLight(150, 255, 255, 200, 200, 200);
  noLights();
  noStroke();
  noSmooth();
  fill(160);
  drawAxis();
  updateCamPosition();
  camera(camEyeX, camEyeY, camEyeZ, viewX, viewY, viewZ, camUpX, camUpY, camUpZ);
  translate(-(cubeSize / 2), (cubeSize / 2), (cubeSize / 2));
  drawCube();
}

Par contre dans mon idée j'étais censé avoir comme point de vue de départ la face avec les angles matérialisés en couleur (plan XY). J'ai décidément un problème de repère dans l'espace !!

Et aussi pourquoi l'écran reste noir tant qu'il n'y a aucun mouvement de caméra ? Je n'arrive pas à corriger ça

Merci encore pour tes conseils...

Hors ligne

 

#11 2013-02-24 21:58:39 Re : Rotation caméra scène 3D

Mushussu
membre
Lieu: Orléans
Date d'inscription: 2012-05-24
Messages: 802

Re: Rotation caméra scène 3D



Il n'y a pas de bonne méthode pour centrer autour du point zéro, il y a celle que tu trouves la plus adéquate à ton projet.

Pour le départ, il faut changer l'initialisation des angles :

//Polar coordinates
float theta = 0;      
float phi = 90;       
float rho = 300;   //distance from cam to point of view

En plus cela règle le problème d'affichage du départ.

Hors ligne

 

#12 2013-02-24 22:15:37 Re : Rotation caméra scène 3D

Marty
membre
Date d'inscription: 2012-04-27
Messages: 143

Re: Rotation caméra scène 3D



Oui évidement, c'était trop simple pour le voir wink
En fait je pensais à un pb d'affichage, mais c'est simplement la caméra qui pointait dans le vide...

Merci encore pour le temps que tu as pris et pour tes conseils.

...étape suivante... !

Hors ligne

 

#13 2013-02-26 06:50:21 Re : Rotation caméra scène 3D

Mushussu
membre
Lieu: Orléans
Date d'inscription: 2012-05-24
Messages: 802

Re: Rotation caméra scène 3D



Correction de bug, lorsque theta = 90 il y a une absence de rendu :

//Polar coordinates
float theta = 0.01;      
float phi = 90;       
float rho = 300;   //distance from cam to point of view

Hors ligne

 

#14 2013-02-26 09:26:33 Re : Rotation caméra scène 3D

Marty
membre
Date d'inscription: 2012-04-27
Messages: 143

Re: Rotation caméra scène 3D



Ah oui ! donc en fait c'était bien un bug !
Mais ça doit être un bug dans mon code, je doute que ce soit processing...

Hors ligne

 

#15 2013-02-28 17:56:44 Re : Rotation caméra scène 3D

cgiles
membre
Lieu: Est de la France
Date d'inscription: 2005-05-25
Messages: 329

Re: Rotation caméra scène 3D



Je regardais votre code et je me suis dit que ça pourrait vous intéresser : http://wiki.processing.org/w/Wheel_mouse
c'est pour utiliser la roulette de la souris dans processing, et ainsi libéré le clic droit, pour une réinitialisation de la cam ou un mouvement de travelling...

Hors ligne

 

fil rss de cette discussion : rss

Pied de page des forums

Powered by FluxBB

codelab, graphisme & code : emoc / 2008-2025