/* File material.c Project pazpl5 Author P J Atkin (c) DIVISION Ltd 1993 */ #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; /*}}} */ /* #define debug_mtl 1 */ int resolved=0; /*{{{ void resolve_material ( MATERIAL *m )*/ /* ****************** take a newly loaded material, scour unresolved PATCH list for references to it. if a newly loaded material resolves any currently unresolved PATCHes, do resolving and free up list storage */ void resolve_material ( MATERIAL *m ) { int resolved=0; PAZlist *item, *prev; /*{{{ resolve material from front list*/ item=funresolved_head, prev=item; #if debug_mtl printf ("resolve_material %s\n", m->material_name ); #endif while (item) { PATCH *p=(PATCH *) item->data; prev=item; item=item->next; #if debug_mtl printf ("compare material name %s with unresolved %s\n", m->material_name, p->fmaterial_name ); #endif if (strcmp (m->material_name, p->fmaterial_name) == 0) { /* found it, resolve material */ #if debug_mtl printf ("found material, can resolve patch 0x%x!\n", p ); #endif removePAZitem ( prev, &funresolved_head, &funresolved_tail ); p->fmaterial=m; m->usage_count++; } } /*}}} */ /*{{{ resolve material from back list*/ item=bunresolved_head, prev=item; #if debug_mtl printf ("resolve_material %s\n", m->material_name ); #endif while (item) { PATCH *p=(PATCH *) item->data; prev=item; item=item->next; #if debug_mtl printf ("compare material name %s with unresolved %s\n", m->material_name, p->bmaterial_name ); #endif if (strcmp (m->material_name, p->bmaterial_name) == 0) { /* found it, resolve material */ #if debug_mtl printf ("found material, can resolve patch 0x%x!\n", p ); #endif removePAZitem ( prev, &bunresolved_head, &bunresolved_tail ); p->bmaterial=m; m->usage_count++; } } /*}}} */ /*{{{ resolve texture*/ item=texture_head, prev=item; #if debug_mtl printf ("resolve_material %s\n", m->material_name ); #endif while (item) { TEXTURE *tex=(TEXTURE *) item->data; char *name; prev=item; item=item->next; name=&m->texture_name[0]; #if debug_mtl printf ("compare material 0x%x tex name %s with texture %s\n", m, name, tex->texture_name ); #endif if ((resolved==0) && (strcmp ( name, tex->texture_name) == 0)) { /* found it, resolve material */ #if debug_mtl printf ("found texture %s ! (0x%x)\n", tex->texture_name, (int) tex ); #endif m->tex=tex; resolved=1; } } /*}}} */ /*{{{ add to unresolved texture list?*/ if (resolved==0) { addPAZitem ( m, &unresolved_tex_head, &unresolved_tex_tail ); } /*}}} */ } /*}}} */ /*{{{ 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 ); resolve_material ( m ); } /*}}} */ /*{{{ MATERIAL *createMaterial ( void )*/ 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] =1.0f; m->kd[2] =1.0f; m->ks =0.0f; m->power =0.0f; m->opacity =1.0f; m->tex =NULL; m->ramp_entry =0x0; m->texture_name[0]=(char) 0x0; return m; } /*}}} */ /*{{{ int resolve_texture ( TEXTURE *t )*/ /* ****************** does a newly loaded texture resolve any materials? scour the unresolved textures list, if we match any, patch them up and remove them. */ int resolve_texture ( TEXTURE *t ) { PAZlist *item=unresolved_tex_head; char *name; #if debug_mtl printf ("resolve_texture %s\n", t->texture_name ); #endif while (item) { MATERIAL *m=(MATERIAL *) item->data; PAZlist *prev=item; name=m->texture_name; #if debug_mtl printf ("compare texture name %s with material %s\n", t->texture_name, m->material_name ); #endif if (strcmp (t->texture_name, name) == 0) { #if debug_mtl printf ("found it! setting %s->tex to 0x%x\n", m->material_name, t ); #endif m->tex=t; removePAZitem ( prev, &unresolved_tex_head, &unresolved_tex_tail ); } item=item->next; } return 0; } /*}}} */ /*{{{ 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 ); resolve_texture ( t ); } /*}}} */ /*{{{ int resolve_patch ( PATCH *p )*/ /* ****************** a newly loaded patch references a front and back material. scour the materials list - if the material matches, patch up the patch. if not, add the patch to the unresolved patch list */ int resolve_patch ( PATCH *p ) { PAZlist *item=material_head; int f_ok=0, b_ok=0; #if debug_mtl printf ("resolve_patch %s %s\n", p->fmaterial_name, p->bmaterial_name ); #endif /*{{{ resolve front*/ while (item) { MATERIAL *m=(MATERIAL *) item->data; #if debug_mtl printf ("compare material name %s with material %s\n", p->fmaterial_name, m->material_name ); #endif if (strcmp (p->fmaterial_name, m->material_name) == 0) { #if debug_mtl printf ("found front!\n" ); #endif p->fmaterial=m; f_ok=1; m->usage_count++; if (f_ok && b_ok) return 1; } #if debug_mtl printf ("compare material name %s with material %s\n", p->bmaterial_name, m->material_name ); #endif if (strcmp (p->bmaterial_name, m->material_name) == 0) { #if debug_mtl printf ("found back!\n" ); #endif p->bmaterial=m; b_ok=1; m->usage_count++; if (f_ok && b_ok) return 1; } item=item->next; } /*}}} */ if (f_ok == 0) { #if debug_mtl printf ("didnt find front mtl, adding to unresolved list\n" ); #endif addPAZitem ( p, &funresolved_head, &funresolved_tail ); return 0; } if (b_ok == 0) { #if debug_mtl printf ("didnt find back mtl, adding to unresolved list\n" ); #endif addPAZitem ( p, &bunresolved_head, &bunresolved_tail ); return 0; } } /*}}} */ /*{{{ int resolve_scene ()*/ int resolve_scene () { /* 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 (resolved == 0) { /* */ } resolved=1; } /*}}} */ /*{{{ 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 unresolved f materials\n" );*/ printf ("trace unresolved f materials\n" ); item=funresolved_head; while (item) { p=(PATCH *) item->data; printf ( "unresolved name %s ", p->fmaterial_name ); item=item->next; } /*}}} */ /*{{{ printf ("trace unresolved b materials\n" );*/ printf ("trace unresolved b materials\n" ); item=bunresolved_head; while (item) { p=(PATCH *) item->data; printf ( "unresolved name %s in patch 0x%x (%d)\n", p->bmaterial_name, p, strlen(p->bmaterial_name)); item=item->next; } /*}}} */ /*{{{ 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; } /*}}} */ /*{{{ printf ("trace unresolved textures\n" );*/ printf ("trace unresolved textures\n" ); item=unresolved_tex_head; while (item) { m=(MATERIAL *) item->data; if (m->tex == NULL) printf ( "unresolved texture %s\n", m->texture_name ); item=item->next; } /*}}} */ } /*}}} */