3 Copyright (C) 2003 Nuno Subtil
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 static const char cvsid
[] =
21 "$Id: object.c,v 1.26 2003/11/23 00:06:39 nsubtil Exp $";
34 #include "linked-lists.h"
41 #include "include/file.h"
43 struct ocache_entry
*object_cache
= NULL
;
45 int object_hash_vertex(float vx
[3])
49 if(vx
[X
] >= 0.0 && vx
[Y
] >= 0.0)
52 if(vx
[X
] < 0.0 && vx
[Y
] >= 0.0)
55 if(vx
[X
] < 0.0 && vx
[Y
] < 0.0)
58 if(vx
[X
] >= 0.0 && vx
[Y
] < 0.0)
67 int object_hash_face(struct face_tri
*face
)
71 a
= object_hash_vertex(face
->a
);
72 b
= object_hash_vertex(face
->b
);
73 c
= object_hash_vertex(face
->c
);
75 return (a
+ b
+ c
) / 3;
78 void object_add_face(struct object
*obj
, struct face_tri
*face
)
81 obj
->fc_list
= realloc(obj
->fc_list
, sizeof(struct face_tri
*) * obj
->num_fc
);
82 obj
->fc_list
[obj
->num_fc
- 1] = face
;
86 procura um objecto na lista pelo nome do ficheiro correspondente
88 struct object
*object_cache_find_file(char *fname
, int *n_objs
)
90 struct ocache_entry
*cur
;
95 if(strcmp(cur
->name
, fname
) == 0)
97 *n_objs
= cur
->n_objs
;
107 void object_cache_add_file(char *fname
, struct object
*objs
, int n_objs
)
109 struct ocache_entry
*new;
111 new = malloc(sizeof(struct ocache_entry
));
114 new->n_objs
= n_objs
;
117 LLIST_ADD(struct ocache_entry
, object_cache
, new);
120 int object_face_equal(struct face_tri
*f1
, struct face_tri
*f2
)
122 if(memcmp(f1
->a
, f2
->a
, sizeof(float) * 3) != 0)
125 if(memcmp(f1
->b
, f2
->b
, sizeof(float) * 3) != 0)
128 if(memcmp(f1
->c
, f2
->c
, sizeof(float) * 3) != 0)
131 if(memcmp(f1
->na
, f2
->na
, sizeof(GLfloat
) * 3) != 0)
134 if(memcmp(f1
->nb
, f2
->nb
, sizeof(GLfloat
) * 3) != 0)
137 if(memcmp(f1
->nc
, f2
->nc
, sizeof(GLfloat
) * 3) != 0)
140 if(f1
->color_tag
!= f2
->color_tag
)
146 /* XXX - que coisa lenta! */
147 int object_get_vertex_index(float **vx_list
, int num_vx
, float vec
[3])
151 for(c
= 0; c
< num_vx
; c
++)
152 if(memcmp(vx_list
[c
], vec
, sizeof(float) * 3) == 0)
158 /* XXX - e este então nem se fala */
159 int object_get_face_index(struct face_tri
**fc_list
, int num_fc
, struct face_tri
*fc
)
163 for(c
= 0; c
< num_fc
; c
++)
164 if(object_face_equal(fc_list
[c
], fc
))
173 lista de vértices (3f cada, sem repetições)
175 lista de faces (sem repetições):
176 vértices a, b, c (índices na lista, 4b cada)
177 normais na, nb, nc (3 floats cada)
182 num de faces do objecto
183 lista de índices das faces do objecto na lista de faces (4b cada)
185 XXX - isto é muito lento
187 void object_write_file(char *fname
, struct object
*objs
, int n_objs
)
192 int vx_num
[8], vx_tot
;
193 struct face_tri
**fc_list
[8];
194 int fc_num
[8], fc_tot
;
196 /* gerar lista de vértices */
197 printf("Building vertex list... ");
200 for(c
= 0; c
< 8; c
++)
206 for(c
= 0; c
< n_objs
; c
++)
207 for(d
= 0; d
< objs
[c
].num_fc
; d
++)
211 h
= object_hash_vertex(objs
[c
].fc_list
[d
]->a
);
212 if(object_get_vertex_index(vx_list
[h
], vx_num
[h
], objs
[c
].fc_list
[d
]->a
) == -1)
215 vx_list
[h
] = realloc(vx_list
[h
], vx_num
[h
] * sizeof(float *));
216 vx_list
[h
][vx_num
[h
] - 1] = objs
[c
].fc_list
[d
]->a
;
219 h
= object_hash_vertex(objs
[c
].fc_list
[d
]->b
);
220 if(object_get_vertex_index(vx_list
[h
], vx_num
[h
], objs
[c
].fc_list
[d
]->b
) == -1)
223 vx_list
[h
] = realloc(vx_list
[h
], vx_num
[h
] * sizeof(float *));
224 vx_list
[h
][vx_num
[h
] - 1] = objs
[c
].fc_list
[d
]->b
;
227 h
= object_hash_vertex(objs
[c
].fc_list
[d
]->c
);
228 if(object_get_vertex_index(vx_list
[h
], vx_num
[h
], objs
[c
].fc_list
[d
]->c
) == -1)
231 vx_list
[h
] = realloc(vx_list
[h
], vx_num
[h
] * sizeof(float *));
232 vx_list
[h
][vx_num
[h
] - 1] = objs
[c
].fc_list
[d
]->c
;
238 for(c
= 0; c
< 8; c
++)
241 printf("%d unique vertexes\n", vx_tot
);
243 /* gerar lista de faces */
244 printf("Building face list... ");
247 for(c
= 0; c
< 8; c
++)
253 for(c
= 0; c
< n_objs
; c
++)
254 for(d
= 0; d
< objs
[c
].num_fc
; d
++)
258 h
= object_hash_face(objs
[c
].fc_list
[d
]);
259 if(object_get_face_index(fc_list
[h
], fc_num
[h
], objs
[c
].fc_list
[d
]) == -1)
261 /* face não existe na lista */
263 fc_list
[h
] = realloc(fc_list
[h
], fc_num
[h
] * sizeof(struct fc_tri
*));
264 fc_list
[h
][fc_num
[h
] - 1] = objs
[c
].fc_list
[d
];
269 for(c
= 0; c
< 8; c
++)
272 printf("%d unique faces\n", fc_tot
);
274 fp
= file_open(fname
);
277 printf("object_write_file: parece que %s não dá para a coisa\n", fname
);
282 /* escrever lista de vértices */
283 printf("Writing vertex list...");
286 file_write_values32(&vx_tot
, 1, fp
);
287 for(d
= 0; d
< 8; d
++)
288 for(c
= 0; c
< vx_num
[d
]; c
++)
289 file_write_values32(vx_list
[d
][c
], 3, fp
);
291 /* escrever lista de faces */
292 printf("\nWriting face list...");
295 file_write_values32(&fc_tot
, 1, fp
);
296 for(c
= 0; c
< 8; c
++)
297 for(d
= 0; d
< fc_num
[c
]; d
++)
302 h
[0] = object_hash_vertex(fc_list
[c
][d
]->a
);
303 idx
[0] = object_get_vertex_index(vx_list
[h
[0]], vx_num
[h
[0]], fc_list
[c
][d
]->a
);
304 h
[1] = object_hash_vertex(fc_list
[c
][d
]->b
);
305 idx
[1] = object_get_vertex_index(vx_list
[h
[1]], vx_num
[h
[1]], fc_list
[c
][d
]->b
);
306 h
[2] = object_hash_vertex(fc_list
[c
][d
]->c
);
307 idx
[2] = object_get_vertex_index(vx_list
[h
[2]], vx_num
[h
[2]], fc_list
[c
][d
]->c
);
309 if(idx
[0] == -1 || idx
[1] == -1 || idx
[2] == -1)
311 printf("object_write_file: duh ?!\n");
315 for(e
= 0; e
< h
[0]; e
++)
318 for(e
= 0; e
< h
[1]; e
++)
321 for(e
= 0; e
< h
[2]; e
++)
324 file_write_values32(idx
, 3, fp
);
325 file_write_values32(fc_list
[c
][d
]->na
, 3, fp
);
326 file_write_values32(fc_list
[c
][d
]->nb
, 3, fp
);
327 file_write_values32(fc_list
[c
][d
]->nc
, 3, fp
);
328 file_write_values32(fc_list
[c
][d
]->color
, 4, fp
);
330 tag
= fc_list
[c
][d
]->color_tag
& 0xff;
331 fwrite(&tag
, 1, 1, fp
);
334 printf("\nWriting objects... ");
337 /* escrever objectos */
338 file_write_values32(&n_objs
, 1, fp
);
339 for(c
= 0; c
< n_objs
; c
++)
341 file_write_values32(&objs
[c
].num_fc
, 1, fp
);
342 for(d
= 0; d
< objs
[c
].num_fc
; d
++)
346 h
= object_hash_face(objs
[c
].fc_list
[d
]);
347 i
= object_get_face_index(fc_list
[h
], fc_num
[h
], objs
[c
].fc_list
[d
]);
351 printf("object_write_file: duh-duh!\n");
355 for(e
= 0; e
< h
; e
++)
358 file_write_values32(&i
, 1, fp
);
369 for(c
= 0; c
< 8; c
++)
376 struct object
*object_read_file(char *fname
, int *n_objs
)
382 struct face_tri
*fc_list
;
386 objs
= object_cache_find_file(fname
, n_objs
);
391 fp
= file_open(fname
);
394 printf("object_read_file: adonde 'tá a porcaria do %s ?\n", fname
);
398 /* ler lista de vértices */
399 file_read_values32(&vx_num
, 1, fp
);
400 vx_list
= malloc(sizeof(float *) * vx_num
);
401 for(c
= 0; c
< vx_num
; c
++)
403 vx_list
[c
] = malloc(sizeof(float) * 3);
404 file_read_values32(vx_list
[c
], 3, fp
);
407 /* ler lista de faces */
408 file_read_values32(&fc_num
, 1, fp
);
409 fc_list
= malloc(sizeof(struct face_tri
) * fc_num
);
410 for(c
= 0; c
< fc_num
; c
++)
415 file_read_values32(idx
, 3, fp
);
416 fc_list
[c
].a
= vx_list
[idx
[0]];
417 fc_list
[c
].b
= vx_list
[idx
[1]];
418 fc_list
[c
].c
= vx_list
[idx
[2]];
420 file_read_values32(fc_list
[c
].na
, 3, fp
);
421 file_read_values32(fc_list
[c
].nb
, 3, fp
);
422 file_read_values32(fc_list
[c
].nc
, 3, fp
);
424 file_read_values32(fc_list
[c
].color
, 4, fp
);
426 fread(&tag
, 1, 1, fp
);
427 fc_list
[c
].color_tag
= (int)(tag
& 0xff);
430 /* ler lista de objectos */
431 file_read_values32(n_objs
, 1, fp
);
432 printf("%s: %d objects (%d unique vertexes, %d unique faces)\n",
433 fname
, *n_objs
, vx_num
, fc_num
);
434 objs
= malloc(sizeof(struct object
) * (*n_objs
));
435 for(c
= 0; c
< *n_objs
; c
++)
437 file_read_values32(&objs
[c
].num_fc
, 1, fp
);
438 objs
[c
].fc_list
= malloc(sizeof(struct face_tri
*) * objs
[c
].num_fc
);
440 for(d
= 0; d
< objs
[c
].num_fc
; d
++)
443 struct face_tri
*face
;
445 file_read_values32(&idx
, 1, fp
);
446 face
= &fc_list
[idx
];
448 objs
[c
].fc_list
[d
] = face
;
451 objs
[c
].dlist_color
= -1;
452 objs
[c
].dlist_nocolor
= -1;
454 /* evitar linkar o jogo todo no 3dsconv */
456 render_compile_dlist(&objs
[c
]);
463 object_cache_add_file(fname
, objs
, *n_objs
);
470 liberta todas as display lists na placa gráfica
472 void object_release_dlists(void)
474 struct ocache_entry
*cur
;
481 for(c
= 0; c
< cur
->n_objs
; c
++)
483 if(cur
->objs
[c
].dlist_color
!= -1)
485 glDeleteLists(cur
->objs
[c
].dlist_color
, 1);
486 cur
->objs
[c
].dlist_color
= -1;
489 if(cur
->objs
[c
].dlist_nocolor
!= -1)
491 glDeleteLists(cur
->objs
[c
].dlist_nocolor
, 1);
492 cur
->objs
[c
].dlist_nocolor
= -1;
501 recompila display lists
503 void object_recompile_dlists(void)
505 struct ocache_entry
*cur
;
512 for(c
= 0; c
< cur
->n_objs
; c
++)
513 render_compile_dlist(&cur
->objs
[c
]);