Aller au contenu

C++ : soustraction qui tourne mal


serik

Messages recommandés

Voilà le bout de code incriminé, du moins la partie étrange.

float * vertex1 = vertices[face[0]];
		  float * vertex2 = vertices[face[1]];
		  float * vertex3 = vertices[face[2]];
		  cout << "\nfaces : " << face[0] << " " << face[1] << " " << face[2];
		  cout << "\n v1(" << vertex1[0] << "," << vertex1[1] << "," << vertex1[2] << ")";
		  cout << "\n v2(" << vertex2[0] << "," << vertex2[1] << "," << vertex2[2] << ")";
		  cout << "\n v3(" << vertex3[0] << "," << vertex3[1] << "," << vertex3[2] << ")";
		  float w = vertex1[1] - vertex2[1];
		  cout << "\ncalc result : " << w;
		  float a = vertex1[1];
		  float b = vertex2[1];
		  cout << "\na : " << a << " b : " << b;
		  float c = a - b;
		  cout << "\nc : " << c;
		  cout << "\na : " << a << " b : " << b;			  
		  float v[3] = {vertex3[0]-vertex2[0],vertex3[1]-vertex2[1],vertex3[2]-vertex2[2]};
		  float u[3] = {vertex1[0] - vertex2[0],w,vertex1[2]-vertex2[2]};

Le code sert à caluler deux vecteurs u et v afin de calculer leur produit vectoriel par la suite.

Sur les 8 faces d'un cube, il y en a une seule qui pose problème.

Sur un mesh de 800 polygones, à vue d'oeil je dirai qu'il y en a entre 20 et 50.

le problème est, sur la composante y.

Ainsi dans un cube simple (défini avec des sommets qui ne prennent pour valeur que 1 ou -1. Le résultat de la 'une soustraction de -1 - (-1) fait 9.53674e-007! si dans le bout de code au dessus je cast les float en int, alors la soustraction se passe correctement.

Il est vraiment étrange que le problème n'apparaisse que sur 1 face... c'est à se demander si c'est pas l'ALU qui bug.

Cela se produit pour la composante y de u et de v, que lorsque les valeurs soustraites sont -1. Sur le mesh de 800 polygones il m'est malheureusement très dur de savoir quelles valeurs plantent.

Le code en entier :

void Obj::calculPolygonalNormals(){
 for (unsigned int i=0; i<count_faces; i++){
		  int * face = faces[i];
		  float * vertex1 = vertices[face[0]];
		  float * vertex2 = vertices[face[1]];
		  float * vertex3 = vertices[face[2]];
		  cout << "\nfaces : " << face[0] << " " << face[1] << " " << face[2];
		  cout << "\n v1(" << vertex1[0] << "," << vertex1[1] << "," << vertex1[2] << ")";
		  cout << "\n v2(" << vertex2[0] << "," << vertex2[1] << "," << vertex2[2] << ")";
		  cout << "\n v3(" << vertex3[0] << "," << vertex3[1] << "," << vertex3[2] << ")";
		  float w = vertex1[1] - vertex2[1];
		  cout << "\ncalc result : " << w;
		  float a = vertex1[1];
		  float b = vertex2[1];
		  cout << "\na : " << a << " b : " << b;
		  float c = a - b;
		  cout << "\nc : " << c;
		  cout << "\na : " << a << " b : " << b;			  
		  float v[3] = {vertex3[0]-vertex2[0],vertex3[1]-vertex2[1],vertex3[2]-vertex2[2]};
		  float u[3] = {vertex1[0] - vertex2[0],w,vertex1[2]-vertex2[2]};

		  cout << "\nu(" << u[0] << "," << u[1] << "," << u[2] << ") v(" << v[0] << "," << v[1] << "," << v[2] << ")";
		  cout << "\n v1(" << vertex1[0] << "," << vertex1[1] << "," << vertex1[2] << ")";
		  cout << "\n v2(" << vertex2[0] << "," << vertex2[1] << "," << vertex2[2] << ")";
		  cout << "\n v3(" << vertex3[0] << "," << vertex3[1] << "," << vertex3[2] << ")";
		  normales[i][0] = u[1]*v[2] - u[2]*v[1];
		  normales[i][1] = u[2]*v[0] - u[0]*v[2];
		  normales[i][2] = u[0]*v[1] - u[1]*v[0];
		  cout << "\nx : " << normales[i][0] << " y : " << normales[i][1] << " z : " << normales[i][2];
		  double norme = sqrt(normales[i][0]*normales[i][0]+normales[i][1]*normales[i][1]+normales[i][2]*normales[i][2]);
		  normales[i][0]/=norme;
		  normales[i][1]/=norme;
		  normales[i][2]/=norme;
		  cout << "\nx : " << normales[i][0] << " y : " << normales[i][1] << " z : " << normales[i][2];
 }
}

Merci à tous ceux qui prendront le temps de m'aider!!!

Lien vers le commentaire
Partager sur d’autres sites

Il semblerait que ce soit du à un arrondi, car le float b fait 1.0000001.

Mais comment se fait-il alors, que sur la face suivante il y ait la même soustraction, et que cette fois la valeur enregistrée par atof soit bien de -1.00000000, et que la soustraction se passe bien?

C'est à y perdre la tête...

Lien vers le commentaire
Partager sur d’autres sites

Pour les polygones qui s'affichent mals, il s'agissait que de l'oublie de l'activation du depth-test, je pensais qu'il était activé par défaut. En gros maintenant mes mesh apparaissent corectement, reste la précision relative des float.

Le bout de code :

	if (strncmp(line, "v ", 2) == 0){
	   cout << ".";
	   float x = atof(&line[2]);
	   char * next_float = strchr(&line[3], ' ');
	   float y = atof(next_float+1);
	   next_float = strchr(next_float+1, ' ');
	   float z = atof(next_float+1);
	   cout << "x : " << x << " y : " << y << " z : " << z << "\n";
	   obj->addVertex(x,y,z);
	   continue;
	}

Un exemple de données que je lui donne, le cube (fichier wavefront normal) :

# Blender v242 OBJ File: raie.blend
# www.blender3d.org
mtllib simpleCube.mtl
o Cube_Cube
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000001 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
usemtl Material
s off
f 1 2 3 4
f 5 8 7 6
f 1 5 6 2
f 2 6 7 3
f 3 7 8 4
f 5 1 4 8

Lien vers le commentaire
Partager sur d’autres sites

ben dans ton fichier, t'as bien -1.000001 (sixième ligne) :francais:

Où alors j'ai rien compris :yes:

là j'suis sur l'cul, parce que j'avais vu que blender avait fait des valeurs ganre 0.999999 au lieu de 1, mais j'avais pas vu celui là.

Merci beaucoup cher ami.

Et si t'as une idée pourquoi blender fait cet arrondi (ouvrir juste blender et sauvegarder la scène par défaut en wavefront)...

Lien vers le commentaire
Partager sur d’autres sites

sans doute qu'il plasse certains point par calcul sur d'autre point (genre une rotation) et que ça merdouille un peu. Cela dit, es-tu vraiment à 10e-6 de précision près ? car si ce n'est pas le cas, tu peux essayer de tronquer la partie qui ne t'intéresse pas :francais:

en fait y'a aucune rotation de faite, juste en ajoutant un cube. y'a juste un truc qui me fait peur c'est que tout le reste du mesh construit à partir du cube aura la même erreur. Ca va m'obliger à encadrer les valeurs pour tester une égalité.

Sous blender, l'ajout d'un cube donne ça :

# Blender v242 OBJ File: raie.blend
# www.blender3d.org
mtllib simpleCube2.mtl
o Cube_Cube.001
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 0.999999 1.000000
v 0.999999 -1.000001 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
usemtl (null)
usemtl (null)
s off
f 1 2 3 4
f 5 8 7 6
f 1 5 6 2
f 2 6 7 3
f 3 7 8 4
f 5 1 4 8

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...