1 /*
2 Copyright (C) 2003 Cedric Cellier, Dominique Lavault
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <assert.h>
21 #include <math.h>
22 #include <string.h>
23 #include "geom.h"
24 #include "csg.h"
25 #include "opengl.h"
26 #include "main.h"
27 #include "log.h"
28 #include "memspool.h"
29 #include "system.h"
30
31 #ifndef M_PI
32 #define M_PI 3.14159265358979323846
33 #endif
34
geom_b_box_union(b_box * dest_bb,b_box * bb1,b_box * bb2)35 void geom_b_box_union(b_box *dest_bb, b_box *bb1, b_box *bb2)
36 {
37 int i;
38 /* resulting b_box encloses both */
39 if (bb1->vide) {
40 if (bb2->vide) {
41 dest_bb->vide=1;
42 return;
43 } else {
44 memcpy(dest_bb, bb2, sizeof(*dest_bb));
45 return;
46 }
47 }
48 if (bb2->vide) {
49 memcpy(dest_bb, bb1, sizeof(*dest_bb));
50 return;
51 }
52 memcpy(dest_bb, bb1, sizeof(*dest_bb));
53 for (i=0; i<3; i++) {
54 if (dest_bb->p_min[i]>bb2->p_min[i]) dest_bb->p_min[i] = bb2->p_min[i];
55 if (dest_bb->p_max[i]<bb2->p_max[i]) dest_bb->p_max[i] = bb2->p_max[i];
56 }
57 }
58
geom_b_box_intersection(b_box * dest_bb,b_box * bb1,b_box * bb2)59 void geom_b_box_intersection(b_box *dest_bb, b_box *bb1, b_box *bb2)
60 {
61 int i;
62 /* resulting b_box is the intersection of both */
63 if (bb1->vide || bb2->vide) {
64 dest_bb->vide = 1;
65 return;
66 }
67 for (i=0; i<3; i++) {
68 if (bb1->p_min[i]>bb2->p_min[i]) {
69 dest_bb->p_min[i] = bb1->p_min[i];
70 } else {
71 dest_bb->p_min[i] = bb2->p_min[i];
72 }
73 if (bb1->p_max[i]<bb2->p_max[i]) {
74 dest_bb->p_max[i] = bb1->p_max[i];
75 } else {
76 dest_bb->p_max[i] = bb2->p_max[i];
77 }
78 if (dest_bb->p_min[i]>dest_bb->p_max[i]) {
79 dest_bb->vide = 1;
80 return;
81 }
82 }
83 dest_bb->vide = 0;
84 }
85
geom_get_b_box(csg_node * node,b_box * dest_bb)86 void geom_get_b_box(csg_node *node, b_box *dest_bb)
87 {
88 GLfloat pos[16];
89 GLfloat size;
90 GLfloat corner[7];
91 unsigned i, j;
92 // assert(node->type==CSG_PRIM);
93 if (node->type!=CSG_PRIM) {
94 csg_print_tree(node);
95 gltv_log_fatal("Assertion node->type==CSG_PRIM failed. type=%d on :", node->type);
96 }
97 memcpy(pos, node->u.prim.m->pos->c, sizeof(pos));
98 size = node->u.prim.m->prim->size_x;
99 pos[0] *= size;
100 pos[1] *= size;
101 pos[2] *= size;
102 size = node->u.prim.m->prim->size_y;
103 pos[4] *= size;
104 pos[5] *= size;
105 pos[6] *= size;
106 size = node->u.prim.m->prim->size_z;
107 pos[8] *= size;
108 pos[9] *= size;
109 pos[10] *= size;
110 for (i=0; i<3; i++) {
111 dest_bb->p_min[i] = -pos[0+i] -pos[4+i] -pos[8+i] +pos[12+i];
112 dest_bb->p_max[i] = dest_bb->p_min[i];
113 }
114 for (i=0; i<3; i++) {
115 corner[0] = +pos[0+i] -pos[4+i] -pos[8+i] +pos[12+i];
116 corner[1] = +pos[0+i] +pos[4+i] -pos[8+i] +pos[12+i];
117 corner[2] = -pos[0+i] +pos[4+i] -pos[8+i] +pos[12+i];
118 corner[3] = -pos[0+i] -pos[4+i] +pos[8+i] +pos[12+i];
119 corner[4] = +pos[0+i] -pos[4+i] +pos[8+i] +pos[12+i];
120 corner[5] = +pos[0+i] +pos[4+i] +pos[8+i] +pos[12+i];
121 corner[6] = -pos[0+i] +pos[4+i] +pos[8+i] +pos[12+i];
122 for (j=0; j<7; j++) {
123 if (dest_bb->p_min[i]>corner[j]) dest_bb->p_min[i] = corner[j];
124 if (dest_bb->p_max[i]<corner[j]) dest_bb->p_max[i] = corner[j];
125 }
126 }
127 dest_bb->vide = 0;
128 }
129
130 GLfloat *current_modelview=NULL, *current_projection=NULL;
131
geom_set_current_modelview(GLfloat * pos)132 void geom_set_current_modelview(GLfloat *pos)
133 {
134 current_modelview = pos;
135 }
geom_set_current_projection(GLfloat * proj)136 void geom_set_current_projection(GLfloat *proj)
137 {
138 current_projection = proj;
139 }
140
geom_matrix_mult(GLfloat * res,GLfloat * a,GLfloat * b)141 void geom_matrix_mult(GLfloat *res, GLfloat *a, GLfloat *b) {
142 unsigned i,j,k;
143 /* the hurry man strikes back */
144 for (i=0; i<4; i++) {
145 for (j=0; j<4; j++) {
146 res[(j<<2)+i] = 0;
147 for (k=0; k<4; k++) {
148 res[(j<<2)+i] += a[i+(k<<2)]*b[(j<<2)+k];
149 }
150 }
151 }
152 }
153
geom_matrix_transp_ortho(GLfloat * res,GLfloat * m)154 void geom_matrix_transp_ortho(GLfloat *res, GLfloat *m)
155 {
156 unsigned i,j;
157 for (i=0; i<3; i++) {
158 for (j=0; j<3; j++) {
159 res[(i<<2)+j] = m[(j<<2)+i];
160 }
161 res[(i<<2)+3] = 0.;
162 }
163 for (i=0; i<3; i++) {
164 res[12+i] = 0.;
165 for (j=0; j<3; j++) {
166 res[12+i] -= m[12+i]*res[(j<<2)+i];
167 }
168 }
169 res[15] = 1;
170 }
171
geom_set_identity(GLfloat * mat)172 void geom_set_identity(GLfloat *mat)
173 {
174 unsigned i,j;
175 for (i=0; i<4; i++) {
176 for (j=0; j<4; j++) {
177 mat[(i<<2)+j] = (i==j?1:0);
178 }
179 }
180 }
181
geom_get_2d(GLfloat x,GLfloat y,GLfloat z,GLdouble * x2d,GLdouble * y2d,GLdouble * z2d)182 int geom_get_2d(GLfloat x, GLfloat y, GLfloat z, GLdouble *x2d, GLdouble *y2d, GLdouble *z2d)
183 {
184 /* computes projection of a 3d point given current modelview and projection - returns 0 on error */
185 /* the method of the hurry man : convert to double and use gluProject */
186 GLint viewport[4] = { 0,0 };
187 GLdouble modelview[16];
188 GLdouble projection[16];
189 unsigned i;
190 assert(current_modelview!=NULL && current_projection!=NULL);
191 viewport[2] = glut_fenLong;
192 viewport[3] = glut_fenHaut;
193 for (i=0; i<16; i++) {
194 modelview[i] = current_modelview[i];
195 projection[i] = current_projection[i];
196 }
197 return GL_TRUE == gluProject(x,y,z, modelview, projection, viewport, x2d,y2d,z2d);
198 }
199
geom_get_b_box_2d(b_box * box3d,b_box_2d * box2d)200 void geom_get_b_box_2d(b_box *box3d, b_box_2d *box2d)
201 {
202 /* computes the 2d bounding box from a 3d bounding box, the current camera and current projection */
203 GLdouble x[8], y[8], z;
204 unsigned i;
205 if (box3d->vide) {
206 box2d->vide=1;
207 return;
208 }
209 i = geom_get_2d(box3d->p_min[0], box3d->p_min[1], box3d->p_min[2], &x[0], &y[0], &z);
210 i += geom_get_2d(box3d->p_min[0], box3d->p_min[1], box3d->p_max[2], &x[1], &y[1], &z);
211 i += geom_get_2d(box3d->p_min[0], box3d->p_max[1], box3d->p_min[2], &x[2], &y[2], &z);
212 i += geom_get_2d(box3d->p_min[0], box3d->p_max[1], box3d->p_max[2], &x[3], &y[3], &z);
213 i += geom_get_2d(box3d->p_max[0], box3d->p_min[1], box3d->p_min[2], &x[4], &y[4], &z);
214 i += geom_get_2d(box3d->p_max[0], box3d->p_min[1], box3d->p_max[2], &x[5], &y[5], &z);
215 i += geom_get_2d(box3d->p_max[0], box3d->p_max[1], box3d->p_min[2], &x[6], &y[6], &z);
216 i += geom_get_2d(box3d->p_max[0], box3d->p_max[1], box3d->p_max[2], &x[7], &y[7], &z);
217 if (8!=i) gltv_log_fatal("geom_get_b_box_2_d: invalid coordinates");
218 box2d->xmin = box2d->xmax = x[0];
219 box2d->ymin = box2d->ymax = y[0];
220 for (i=1; i<8; i++) {
221 if (x[i]<box2d->xmin) box2d->xmin=x[i];
222 if (y[i]<box2d->ymin) box2d->ymin=y[i];
223 if (x[i]>box2d->xmax) box2d->xmax=x[i];
224 if (y[i]>box2d->ymax) box2d->ymax=y[i];
225 }
226 if (box2d->xmax>=glut_fenLong) box2d->xmax = glut_fenLong;
227 if (box2d->ymax>=glut_fenHaut) box2d->ymax = glut_fenHaut;
228 if (box2d->xmin<=0) box2d->xmin=0;
229 if (box2d->ymin<=0) box2d->ymin=0;
230 if (box2d->xmin>=box2d->xmax || box2d->ymin>=box2d->ymax) {
231 box2d->vide=1;
232 } else {
233 box2d->vide = 0;
234 }
235 // gltv_log_warning(GLTV_LOG_MUSTSEE, "box2d : %d %d - %d %d - %d\n", box2d->xmin, box2d->ymin, box2d->xmax, box2d->ymax, (int)box2d->vide);
236 }
237
geom_b_box_intersects(b_box * bb1,b_box * bb2)238 int geom_b_box_intersects(b_box *bb1, b_box *bb2)
239 {
240 /* tels wether 2 b_box have an intersection */
241 b_box inter;
242 geom_b_box_intersection(&inter, bb1, bb2);
243 return !inter.vide;
244 }
245
geom_rapproche(GLfloat * a,GLfloat * b,float ratio)246 void geom_rapproche(GLfloat *a, GLfloat *b, float ratio) {
247 float d;
248 unsigned i;
249 for (i=0; i<3; i++) {
250 d = (b[i] - a[i])*ratio;
251 a[i] += d;
252 }
253 }
254
geom_scalaire(GLfloat * a,GLfloat * b)255 float geom_scalaire(GLfloat *a, GLfloat *b)
256 {
257 return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
258 }
259
geom_norme(GLfloat * a)260 float geom_norme(GLfloat *a)
261 {
262 return sqrt(geom_scalaire(a,a));
263 }
264
geom_normalise(GLfloat * a)265 void geom_normalise(GLfloat *a)
266 {
267 double n = geom_norme(a);
268 if (0!=n) {
269 a[0] /= n;
270 a[1] /= n;
271 a[2] /= n;
272 }
273 }
274
geom_orthogonalise(GLfloat * a,GLfloat * b)275 void geom_orthogonalise(GLfloat *a, GLfloat *b)
276 {
277 double d = geom_scalaire(a,b);
278 if (0!=d) {
279 d /= geom_scalaire(b,b);
280 a[0] -= d*b[0];
281 a[1] -= d*b[1];
282 a[2] -= d*b[2];
283 }
284 }
285
geom_vectoriel(GLfloat * a,GLfloat * b,GLfloat * c)286 void geom_vectoriel(GLfloat *a, GLfloat *b, GLfloat *c)
287 {
288 c[0] = a[1]*b[2]-a[2]*b[1];
289 c[1] = a[2]*b[0]-a[0]*b[2];
290 c[2] = a[0]*b[1]-a[1]*b[0];
291 }
292
geom_position_approche(GLfloat * now,GLfloat * target,float ratio)293 void geom_position_approche(GLfloat *now, GLfloat *target, float ratio)
294 {
295 /* translation */
296 geom_rapproche(now+12, target+12, ratio);
297 /* axis */
298 /* begin with z */
299 geom_rapproche(now+8, target+8, ratio);
300 geom_rapproche(now+4, target+4, ratio);
301 geom_normalise(now+4);
302 geom_orthogonalise(now+8, now+4);
303 geom_normalise(now+8);
304 geom_vectoriel(now+4, now+8, now+0);
305 }
306
geom_is_Pt_in_2DTriangle(struct Point2D * P,struct Point2D * p0,struct Point2D * p1,struct Point2D * p2)307 int geom_is_Pt_in_2DTriangle(struct Point2D * P, struct Point2D * p0, struct Point2D * p1, struct Point2D * p2)
308 {
309 struct Point2D V[4];
310 int i=0, cn = 0; // the crossing number counter
311
312 V[i++] =* p0;
313 V[i++] =* p1;
314 V[i++] =* p2;
315 V[i++] =* p0;
316 // loop through all edges of the polygon
317 for (i=0; i<3; i++) { // edge from V[i] to V[i+1]
318 if (((V[i].y <= P->y) && (V[i+1].y > P->y)) // an upward crossing
319 || ((V[i].y > P->y) && (V[i+1].y <= P->y))) { // a downward crossing
320 // compute the actual edge-ray intersect x-coordinate
321 float vt = (float)(P->y - V[i].y) / (V[i+1].y - V[i].y);
322 if (P->x < V[i].x + vt * (V[i+1].x - V[i].x)) // P->x < intersect
323 ++cn; // a valid crossing of y=P->y right of P->x
324 }
325 }
326 return (cn&1); // 0 if even (out), and 1 if odd (in)
327 }
328
geom_get_3d(GLdouble x,GLdouble y,GLdouble z,GLdouble * x3d,GLdouble * y3d,GLdouble * z3d)329 int geom_get_3d(GLdouble x, GLdouble y, GLdouble z, GLdouble *x3d, GLdouble *y3d, GLdouble *z3d)
330 {
331 GLint viewport[4] = { 0,0 };
332 GLdouble modelview[16];
333 GLdouble projection[16];
334 unsigned i;
335 assert(current_modelview!=NULL && current_projection!=NULL);
336 viewport[2] = glut_fenLong;
337 viewport[3] = glut_fenHaut;
338 for (i=0; i<16; i++) {
339 modelview[i] = current_modelview[i];
340 projection[i] = current_projection[i];
341 }
342 return GL_TRUE == gluUnProject(x,y,z, modelview, projection, viewport, x3d,y3d,z3d);
343 }
344
geom_prim_clicked(primitive * prim)345 int geom_prim_clicked(primitive *prim)
346 {
347 unsigned cptPts, cptPoly, nbPts, nbFaces;
348 GLfloat* points;
349 GLuint* faces;
350 GLdouble dummy;
351 int o, ret=0;
352 struct Point2D *pts2D, p_mouseClickCoordinates;
353 p_mouseClickCoordinates.x = (glut_mouse_x+1)*.5*glut_fenLong;
354 p_mouseClickCoordinates.y = (1-glut_mouse_y)*.5*glut_fenHaut;
355 if (prim->nb_points_light) {
356 nbPts = prim->nb_points_light;
357 nbFaces = prim->nb_faces_light;
358 points = prim->points_light;
359 faces = prim->faces_light;
360 } else {
361 nbPts = prim->nb_points;
362 nbFaces = prim->nb_faces;
363 points = prim->points;
364 faces = prim->faces;
365 }
366 pts2D = gltv_memspool_alloc(sizeof(*pts2D)*nbPts);
367 for (o=0, cptPts=0; cptPts<nbPts; cptPts++, o+=3) {
368 geom_get_2d(points[o],points[o+1],points[o+2], &pts2D[cptPts].x,&pts2D[cptPts].y,&dummy);
369 }
370 /* glBegin(GL_LINES);
371 glColor3f(1,1,0);
372 glVertex3f(0, 0, -1.0001);
373 glVertex3f(p_mouseClickCoordinates.x, p_mouseClickCoordinates.y, -1.0001);
374 glEnd();*/
375 for (cptPoly=0; cptPoly<nbFaces; cptPoly++) {
376 /* glBegin(GL_LINES);
377 glColor3f(1,0,1);
378 glVertex3f(pts2D[faces[cptPoly*3+0]].x, pts2D[faces[cptPoly*3+0]].y, -1.0001);
379 glVertex3f(pts2D[faces[cptPoly*3+1]].x, pts2D[faces[cptPoly*3+1]].y, -1.0001);
380 glVertex3f(pts2D[faces[cptPoly*3+0]].x, pts2D[faces[cptPoly*3+0]].y, -1.0001);
381 glVertex3f(pts2D[faces[cptPoly*3+2]].x, pts2D[faces[cptPoly*3+2]].y, -1.0001);
382 glEnd();*/
383 if (geom_is_Pt_in_2DTriangle(&p_mouseClickCoordinates, &pts2D[faces[cptPoly*3+0]],&pts2D[faces[cptPoly*3+1]],&pts2D[faces[cptPoly*3+2]])) {
384 ret = 1;
385 break;
386 }
387 }
388 gltv_memspool_unregister(pts2D);
389 return ret;
390 }
391
geom_prim_depth(primitive * prim)392 GLfloat geom_prim_depth(primitive *prim)
393 {
394 /* as center is at (0,0,0), easy calculus (check that prims are still centered) */
395 return current_modelview[14]; /* :-p */
396 }
397
geom_clic_position(position * pos,GLfloat * z)398 mesh *geom_clic_position(position *pos, GLfloat *z)
399 {
400 /* go throught all meshes of this position, computing
401 * the position of every meshes, and look for a clicked mesh.
402 * Return NULL if none found, or mesh
403 */
404 GLfloat m[16], zz, *old_current;
405 unsigned s;
406 mesh *clicked = NULL, *oo;
407 geom_matrix_mult(m, current_modelview, pos->c);
408 old_current = current_modelview;
409 geom_set_current_modelview(m);
410 /* glPushMatrix();
411 glLoadIdentity();*/
412 for (s=0; s<pos->nb_sons; s++) {
413 oo = geom_clic_position(pos->sons[s], &zz);
414 if (oo!=NULL && (clicked==NULL || zz>*z)) {
415 clicked = oo;
416 *z = zz;
417 }
418 }
419 for (s=0; s<pos->nb_meshes; s++) {
420 if (geom_prim_clicked(pos->meshes[s]->prim)) {
421 zz = geom_prim_depth(pos->meshes[s]->prim);
422 if (clicked==NULL || zz>*z) {
423 clicked = pos->meshes[s];
424 *z = zz;
425 }
426 }
427 }
428
429 geom_set_current_modelview(old_current);
430 // glPopMatrix();
431 return clicked;
432 }
433
geom_get_pos_diff(GLfloat * dest,GLfloat * m1,GLfloat * m2)434 static void geom_get_pos_diff(GLfloat *dest, GLfloat *m1, GLfloat *m2)
435 {
436 static GLfloat m1T[16];
437 geom_matrix_transp_ortho(m1T, m1);
438 geom_matrix_mult(dest, m1T, m2);
439 }
440
geom_axes_match(GLfloat * v1,GLfloat * v2)441 static int geom_axes_match(GLfloat *v1, GLfloat *v2)
442 {
443 unsigned i;
444 gltv_log_warning(GLTV_LOG_DEBUG, "\t\t\tdo (%f,%f,%f) matches (%f,%f,%f)?", v1[0],v1[1],v1[2],v2[0],v2[1],v2[2]);
445 for (i=0; i<3; i++) {
446 if (fabs(v1[i]-v2[i])>.1) return 0;
447 }
448 return 1;
449 }
450
geom_axes_unsigmatch(GLfloat * v1,GLfloat * v2)451 static int geom_axes_unsigmatch(GLfloat *v1, GLfloat *v2)
452 {
453 unsigned i;
454 gltv_log_warning(GLTV_LOG_DEBUG, "\t\t\tdo (%f,%f,%f) matches +/-(%f,%f,%f)?", v1[0],v1[1],v1[2],v2[0],v2[1],v2[2]);
455 for (i=0; i<3; i++) {
456 if (fabs(fabs(v1[i])-fabs(v2[i]))>.1) return 0;
457 }
458 for (i=0; i<3; i++) {
459 if (fabs(v1[i]+v2[i])>.1) return 1;
460 }
461 return -1;
462 }
463
geom_pos_are_equivalent(GLfloat * m1,GLfloat * m2,unsigned sym2)464 static int geom_pos_are_equivalent(GLfloat *m1, GLfloat *m2, unsigned sym2)
465 {
466 /* Ts should be equals */
467 gltv_log_warning(GLTV_LOG_DEBUG, "\t\tT match ?");
468 if (!geom_axes_match(m1+12,m2+12)) {
469 gltv_log_warning(GLTV_LOG_DEBUG, "\t\tno");
470 return 0;
471 }
472 gltv_log_warning(GLTV_LOG_DEBUG, "\t\tyes\n\t\tsym = %u", sym2);
473 /* We dont handle every possible symmetry because we lack the time */
474 if (0==sym2) {
475 return geom_axes_match(m1, m2) && geom_axes_match(m1+4, m2+4) && geom_axes_match(m1+8, m2+8);
476 } else if (ROT_X_45+ROT_Y_45+ROT_Z_45==sym2) {
477 return 1;
478 } else if (ROT_X_45==sym2) {
479 return geom_axes_match(m1, m2);
480 } else if (ROT_Y_45==sym2) {
481 return geom_axes_match(m1+4, m2+4);
482 } else if (ROT_Z_45==sym2) {
483 return geom_axes_match(m1+8, m2+8);
484 } else if (ROT_X_45+ROT_Y_90+ROT_Z_90==sym2) {
485 return geom_axes_unsigmatch(m1, m2);
486 } else if (ROT_X_90+ROT_Y_45+ROT_Z_90==sym2) {
487 return geom_axes_unsigmatch(m1+4, m2+4);
488 } else if (ROT_X_90+ROT_Y_90+ROT_Z_45==sym2) {
489 return geom_axes_unsigmatch(m1+8, m2+8);
490 } else if (ROT_X_90==sym2) {
491 return geom_axes_match(m1, m2) && (geom_axes_unsigmatch(m1+4,m2+4)*geom_axes_unsigmatch(m1+8,m2+8))==1;
492 } else if (ROT_Y_90==sym2) {
493 return geom_axes_match(m1+4, m2+4) && (geom_axes_unsigmatch(m1,m2)*geom_axes_unsigmatch(m1+8,m2+8))==1;
494 } else if (ROT_Z_90==sym2) {
495 return geom_axes_match(m1+8, m2+8) && (geom_axes_unsigmatch(m1+4,m2+4)*geom_axes_unsigmatch(m1,m2))==1;
496 } else {
497 gltv_log_fatal("symmetry not handled for now : %u", sym2);
498 }
499 }
500
geom_pos_is_equivalent(mesh ** m,GLfloat (* pos)[16],unsigned nb_pos)501 int geom_pos_is_equivalent(mesh **m, GLfloat (*pos)[16], unsigned nb_pos)
502 {
503 static GLfloat diff[2][16];
504 unsigned p;
505 GLfloat s[2];
506 char k[2];
507 static GLfloat posInit[16];
508 if (nb_pos<2) return 1;
509 posInit[12] = m[0]->pos->c[12];
510 posInit[13] = m[0]->pos->c[13];
511 posInit[14] = m[0]->pos->c[14];
512 posInit[15] = 1.;
513 gltv_log_warning(GLTV_LOG_DEBUG, "Are positions equivalents ?");
514 /* TODO : au lieu de prendre le premier mesh comme r�f�rence, prendre celui qui � le moins de symetrie ... imagine que ce soit une sphere le premier mesh ! */
515 for (s[0]=-1; s[0]<=1; s[0]+=2) {
516 for (s[1]=-1; s[1]<=1; s[1]+=2) {
517 for (k[0]=0; k[0]<3; k[0]++) {
518 for (k[1]=0; k[1]<3; k[1]++) {
519 unsigned i,j;
520 if (k[0]==k[1]) continue;
521 for (i=0; i<2; i++) {
522 for (j=0; j<3; j++) {
523 if (k[i]==j) posInit[(i<<2)+j] = s[i];
524 else posInit[(i<<2)+j] = 0;
525 }
526 geom_vectoriel(posInit, posInit+4, posInit+8);
527 if (geom_pos_are_equivalent(m[0]->pos->c, posInit, m[0]->prim->symmetry)) {
528 for (p=0; p<nb_pos; p++) {
529 geom_get_pos_diff(diff[0], posInit, m[p]->pos->c);
530 geom_get_pos_diff(diff[1], &pos[0][0], &pos[p][0]);
531 gltv_log_warning(GLTV_LOG_DEBUG, "\tpositions of prim %u for prim 0 equivalents ?", p);
532 if (!geom_pos_are_equivalent(diff[0], diff[1], m[p]->prim->symmetry)) {
533 gltv_log_warning(GLTV_LOG_DEBUG, "\tno");
534 break;
535 }
536 gltv_log_warning(GLTV_LOG_DEBUG, "\tyes");
537 }
538 if (p==nb_pos) return 1;
539 }
540 }
541 }
542 }
543 }
544 }
545 return 0;
546 }
547