IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

Calcul de normal par vertice


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    ed_
    ed_ est déconnecté
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 3
    Par défaut Calcul de normal par vertice
    Bonjour à tous,

    je suis nouveau sur ce forum et je découvre pas mal d'information, j'ai un petit probème à vous soumettre.

    J'importe un objet au format WAVEFront OBJ, je calcule moi même les normales de chaque triangle, et à partir de ça j'essaie de récupérer les normales pour chaques vertices.

    A l'affichage il semblerait que ça se passe mal.
    [img=http://img369.imageshack.us/img369/2921/bugcalculnormal0hz.th.jpg]

    Je vous soumets un peu de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
     
    void Objet3D::initPointNorm()
    {
    	// le triangle a traité
    	for(int iT=0;iT<nbTri;++iT)
    	{
    		// les points du triangles à traiter
    		for(int kP = 0; kP<3; ++kP)
    		{		
    			float cp = 0.;
     
    			// initialisation avant de sommer (par précaution)
    			tri_[iT].setNormPoint(kP, Vector3D(0.,0.,0.) );
     
    			// on parcours les autres triangles
    			for(int jT=0; jT<nbTri; ++jT)
    			{				
    				// les points du triangle comparé
    				for(int lP=0; lP<3; ++lP)
    				{
    					// si le point est dans le triangle comparé
    					if(tri_[jT].cherchPoint(tri_[iT].getPoint(kP),lP))
    					{
    						cp ++;
    						// on somme la norme
    						tri_[iT].setNormPoint(kP, tri_[iT].getNormPoint(kP) + tri_[jT].getNorm() );
    					}
    				}
     
    			}
     
    			if(cp > 0) // on a trouver des normales
    			{
    				// on divise la norme par le nombre de point (cp)
    				//cp = 1 / cp;
    				//tri_[iT].setNormPoint(kP, tri_[iT].getNormPoint(kP) * cp );
     
    				tri_[iT].setNormPoint(kP, tri_[iT].getNormPoint(kP).Normalise());				
     
    			}			
    		}
    	}
    	smooth = true;
    }
     
    ...
     
    void Objet3D::drawSolid() const
    {
     
    	// Activation de la texture
    	glBindTexture(GL_TEXTURE_2D, texID);
     
    	for( int i = 0 ; i<nbTri; ++i)
    	{
    		if(smooth)
    		{
    			glBegin (GL_TRIANGLES);
     
    			glNormal3f(tri_[i].getNormPoint(0).xyz(0),tri_[i].getNormPoint(0).xyz(1),tri_[i].getNormPoint(0).xyz(2));
    			glVertex3f(tri_[i].getPoint(0).xyz(0),tri_[i].getPoint(0).xyz(1),tri_[i].getPoint(0).xyz(2));
     
    			glNormal3f(tri_[i].getNormPoint(0).xyz(1),tri_[i].getNormPoint(1).xyz(1),tri_[i].getNormPoint(1).xyz(2));
    			glVertex3f(tri_[i].getPoint(1).xyz(0),tri_[i].getPoint(1).xyz(1),tri_[i].getPoint(1).xyz(2));
     
    			glNormal3f(tri_[i].getNormPoint(0).xyz(2),tri_[i].getNormPoint(2).xyz(1),tri_[i].getNormPoint(2).xyz(2));
    			glVertex3f(tri_[i].getPoint(2).xyz(0),tri_[i].getPoint(2).xyz(1),tri_[i].getPoint(2).xyz(2));
    		glEnd();
    		}
    		else
    		{
              ....
     
    }
    En gros j'utilise la méthode expliquée quelque part sur flipcode.com, je somme les normales des triangles auquel appartient le sommet, puis soit je divise soit je normalise, ça revient au même.

    Voilà j'aimerais savoir comment régler le problème, pour une certaine orientation de la caméra ça a l'aire de fonctionner.
    Merci d'avance !

  2. #2
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    L'idée c'est ca, mais ton algorithme merde quelque part !
    J'arrive pas à le lire, c trop long, et c en C ! Je hais le c, le c++ ...
    Je te conseille de refaire cette fonction de zéro, comme je l'ai dit, l'idée est correcte, le problème vient de son implementation.

  3. #3
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 580
    Par défaut
    Dis moi, tes points sont-ils indexés pour la génération de tes triangles ?

    si ce n'est pas le cas c'est trop galère

    par contre si c'est le cas comme je le pense, je t'invite à parcourir tes points un par un et à regarder à quels triangles ils appartiennent :

    - tu parcours d'abord tes triangles pour calculer leur normale respective et la mettre dans un tableau si tu veux éviter de devoir la recalculer à chaque fois
    - ensuite tu parcours tous tes points et pour chaque point : tu prépares une valeur temporaire à 0 et un vecteur temporaire à 0, et tu regardes à quels triangles le point est utilisé
    - à chaque fois que le point fait partie d'un triangle tu ajoute la normale du triangle au vecteur temporaire et tu incrémente ta valeur temporaire
    - une fois que tu as regardé toutes les faces tu divise le vecteur temporaire par la valeur temporaire et tu obtiens la normale de ton point

    si tu veux tu peux éviter d'utiliser la valeur temporaire et tu normalise simplement le vecteur temporaire dans la dernière étape
    personnellement je préfère cette méthode afin de m'assurer que la normale est bien... normalisée, de longueur = 1 donc
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  4. #4
    ed_
    ed_ est déconnecté
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 3
    Par défaut
    Oui maintenant que j'y réfléchis, j'ai bétement copié chaque point et les ai attribués à un triangle (un meme point se retrouve plusieurs fois, pour un triangle différent ... ) , au lieu de conserver la liste de points et les index comme c'est organisé dans le fichier obj .

    Mon "algo", dans l'idée, c'est ce que tu me décris shenron666, va falloir que je revoie l'implémentation de mes points (et la méthode au passage) .

    Ce que j'ai du mal à comprendre c'est que je calcule plusieurs fois la même normale pour un point, mais logiquement à part faire perdre du temps à l'initialisation, à l'affichage un point aura plusieurs normales déclarées mais elles seront identiques donc à priori ca devrait pas poser de soucis à l'affichage, nan ?

    Merci en tout cas pour vos réponses.

  5. #5
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    Je ne te comprends plus ed_ ! comment ca, calculer plusieurs normales pour chaque point, et ... ?
    Cet algorithme calcule les normales per vertex, qui depend des normales de toutes les faces qui le touchent.
    on aurait pu associer à chaque vertex la normale de la face qui le contient, c'est plus simple, mais c'est très moche ! t'as qu'a essayer !

  6. #6
    ed_
    ed_ est déconnecté
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2005
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 3
    Par défaut
    Pour expliquer ce que je voulais dire :
    On prend un point p,
    il appartient à plusieurs triangles,
    "vas y que je te .. op la boom.." il est stocké plusieurs fois (en fait pour chaque triangle) .
    Et par conséquent, quand je calcule la normale pour chaque point, reprenons ce point là, cette normale se retrouvera à différents endroits dans ma structure, elle aurait été calculée plusieurs fois, et aura en théorie la même valeur, et sera envoyée par glNormal3f plusieurs fois avec des origines différentes (suivant le triangle de l'objet).

    Bref tout ça c'est pas très économique, mais en théorie ca devrait pas poser de soucis.., je vais revoir l'implémentation de mon objet dès que j'en aurais le courage, et je vais revoir l'algorithme au passage on sait jamais.

    Merci en tout cas !

  7. #7
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    Je te conseillerais plutôt (comme tout le monde) de stocker tous les vertices dans un tableau, et de modéliser chaque triangle comme trois entiers : des indices dans le tableau des vertices ! c'est la meilleure méthode pour procéder, je pense !

Discussions similaires

  1. Calculs de normals par sommets.
    Par Clad3 dans le forum OpenGL
    Réponses: 3
    Dernier message: 07/11/2007, 11h23
  2. Réponses: 5
    Dernier message: 29/12/2005, 10h31
  3. Réponses: 4
    Dernier message: 28/09/2005, 09h19
  4. Problème dans le calcul des normales moyennes,
    Par MaxPayne dans le forum OpenGL
    Réponses: 1
    Dernier message: 12/04/2005, 17h50
  5. problème de calcul des normales par sommet
    Par captainSeb dans le forum OpenGL
    Réponses: 2
    Dernier message: 21/01/2005, 13h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo