/* File material.c Project pazpl5 Author P J Atkin (c) DIVISION Ltd 1993 */ #include #include #include #include "pazpl5.h" /*{{{ some PAZlists used in here*/ /* list of currently resolved materials */ static PAZlist *material_head=NULL, *material_tail=NULL; /* list of PATCHES containing unresolved front materials */ static PAZlist *funresolved_head=NULL, *funresolved_tail=NULL; /* list of PATCHES containing unresolved back materials */ static PAZlist *bunresolved_head=NULL, *bunresolved_tail=NULL; /* list of currently resolved textures */ static PAZlist *texture_head=NULL, *texture_tail=NULL; /* list of MATERIALs containing unresolved textures */ static PAZlist *unresolved_tex_head=NULL, *unresolved_tex_tail=NULL; /*}}} */ extern OBJLIST sceneGeometry; /* #define debug_mtl 1 */ int scene_resolved=0; /*{{{ void add_material ( MATERIAL *m )*/ /* ****************** append a new material to list, and attempt to resolve PATCH list */ void add_material ( MATERIAL *m ) { #if debug_mtl printf ("adding material %s\n", m->material_name ); #endif addPAZitem ( m, &material_head, &material_tail ); scene_resolved=0; } /*}}} */ /*{{{ MATERIAL *create_material ()*/ MATERIAL *create_material () { MATERIAL *m=(MATERIAL *) malloc(sizeof(MATERIAL)); if (m==NULL) return NULL; #if debug_mtl printf ("create_material\n" ); #endif m->usage_count=0; m->material_name[0]=(char) 0x0; m->triangle_fn=NULL; m->pxpl5codeword=0x0; m->kd[0] =1.0f; m->kd[1] =0.0f; m->kd[2] =0.0f; m->ks =0.0f; m->power =0.0f; m->opacity =1.0f; m->tex =NULL; m->ramp_entry =0x0; strcpy ( m->material_name, "DEFAULT" ); strcpy ( m->texture_name, "DEFAULT" ); return m; } /*}}} */ /*{{{ void delete_material ( MATERIAL *m)*/ void delete_material ( MATERIAL *m) { PAZlist *mtl_item; MATERIAL *check; if ((mtl_item=findPAZitem( m, &material_head, &material_tail)) != NULL) { check=removePAZitem ( mtl_item, &material_head, &material_tail ); if (m == check) free(m); scene_resolved=0; } else { /* this was never exported ! */ free(m); } } /*}}} */ /*{{{ void add_texture ( TEXTURE *t )*/ /* ****************** append a new texture to list, and attempt to resolve MATERIAL list */ void add_texture ( TEXTURE *t ) { #if debug_mtl printf ("adding texture %s\n", t->texture_name ); #endif addPAZitem ( t, &texture_head, &texture_tail ); scene_resolved=0; } /*}}} */ /*{{{ void trace_materials ()*/ /* ****************** debug, trace materials */ void trace_materials () { PAZlist *item; PATCH *p; MATERIAL *m, *mtl; TEXTURE *t; /*{{{ printf ("trace materials\n" );*/ printf ("trace materials\n" ); for (item=material_head; item; item=item->next ) { mtl=(MATERIAL *) item->data; printf ( "material name %s\n", mtl->material_name ); } /*}}} */ /*{{{ printf ("trace textures\n" );*/ printf ("trace textures\n" ); item=texture_head; while (item) { t=(TEXTURE *) item->data; printf ( "texture %s\n", t->texture_name ); item=item->next; } /*}}} */ } /*}}} */ /*{{{ int resolve_scene ( SCENE *s )*/ int resolve_scene ( SCENE *s ) { /* this is the UTTERLY brute force scene material / texture resolver */ /* first all materials are resolved to their respective textures */ /* then all patch / pmeshes are resolved to their respective materials */ if (scene_resolved == 0) { OBJECT *obj; PAZlist *m=material_head; /* trace_materials(); */ while (m) { /*{{{ resolve this material*/ PAZlist *t=texture_head; MATERIAL *mtl=(MATERIAL *) m->data; int resolved=0; mtl->tex=NULL; while (resolved==0) { if (t==NULL) { /* printf ("couldnt find texture %s, nulling\n", mtl->texture_name ); */ mtl->tex=0; resolved=1; } else { TEXTURE *tex=(TEXTURE *) t->data; if (strcmp(mtl->texture_name, tex->texture_name) == 0) { resolved=1; mtl->tex=tex; } else t=t->next; } } /*}}} */ m=m->next; } for (obj=sceneGeometry.head; obj; obj=obj->next ) { LOD *l; PATCH *p; for (l=obj->head; l; l=l->next ) { for (p=l->head; p; p=p->next ) { int f_resolved=0, b_resolved=0; p->fmaterial=NULL; p->bmaterial=NULL; m=material_head; while ((f_resolved==0)||(b_resolved==0)) { /*{{{ resolve this patch*/ MATERIAL *mtl=m->data; /* printf ("fpatch %s bpatch %s mtl %s\n", p->fmaterial_name, p->bmaterial_name, mtl->material_name ); */ if (strcmp(mtl->material_name, p->fmaterial_name) == 0) { f_resolved=1; /* printf ("front resolved\n" ); */ p->fmaterial=mtl; } if (strcmp(mtl->material_name, p->bmaterial_name) == 0) { b_resolved=1; /* printf ("back resolved\n" ); */ p->bmaterial=mtl; } /*}}} */ m=m->next; if (m==NULL) { if (f_resolved==0) p->fmaterial=NULL; if (b_resolved==0) p->bmaterial=NULL; f_resolved=1; b_resolved=1; } } } } } } scene_resolved=1; } /*}}} */