/* material.c */ #include #include "material.h" #include "pools.h" #include "error.h" #include "bsdf.h" #include "splitbsdf.h" #include "patch.h" #ifdef NOPOOLS #define NEWMATERIAL() (MATERIAL *)Alloc(sizeof(MATERIAL)) #define DISPOSEMATERIAL(ptr) Free((char *)ptr, sizeof(MATERIAL)) #else static POOL *materialPool = (POOL *)NULL; #define NEWMATERIAL() (MATERIAL *)NewPoolCell(sizeof(MATERIAL), 0, "materials", &materialPool) #define DISPOSEMATERIAL(ptr) Dispose((char *)ptr, &materialPool) #endif MATERIAL defaultMaterial = { "(default)", (EDF *)NULL, (BSDF *)NULL, 0 /* sided */ }; MATERIAL *MaterialCreate(char *name, EDF *edf, BSDF *bsdf, int sided) { MATERIAL *m; m = NEWMATERIAL(); m->name = Alloc(strlen(name) + 1); sprintf(m->name, "%s", name); m->sided = sided; m->edf = edf; m->bsdf = bsdf; m->radiance_data = (void*)NULL; /* m->bsdf = BsdfCreate(SplitBSDFCreate(brdf, btdf), &SplitBsdfMethods); */ return m; } MATERIAL *MaterialDuplicate(MATERIAL *mat) { MATERIAL *m; m = NEWMATERIAL(); m->name = Alloc(strlen(mat->name) + 1); sprintf(m->name, "%s", mat->name); m->sided = mat->sided; m->edf = EdfDuplicate(mat->edf); m->bsdf = BsdfDuplicate(mat->bsdf); m->radiance_data = (void*)NULL; return m; } void MaterialDestroy(MATERIAL *material) { if (material->name) Free(material->name, strlen(material->name)+1); if (material->edf) EdfDestroy(material->edf); if (material->bsdf) BsdfDestroy(material->bsdf); DISPOSEMATERIAL(material); } void MaterialPrint(FILE *out, MATERIAL *material) { fprintf(out, "material '%s': %s\n", material->name, material->sided ? "SINGLE SIDED" : "TWOSIDED"); if (material->edf) { fprintf(out, "\t"); EdfPrint(out, material->edf); } else fprintf(out, "\tNot a luminaire\n"); if (material->bsdf) { fprintf(out, "\t"); BsdfPrint(out, material->bsdf); } else fprintf(out, "\tNot scattering\n"); } int MaterialShadingFrame(HITREC *hit, VECTOR *X, VECTOR *Y, VECTOR *Z) { int succes = FALSE; if (!HitInitialised(hit)) { Warning("MaterialShadingFrame", "uninitialised hit structure"); return FALSE; } if (hit->material && hit->material->bsdf && hit->material->bsdf->methods->ShadingFrame) { succes = BsdfShadingFrame(hit->material->bsdf, hit, X, Y, Z); } if (!succes && hit->material && hit->material->edf && hit->material->edf->methods->ShadingFrame) { succes = EdfShadingFrame(hit->material->edf, hit, X, Y, Z); } if (!succes && HitUV(hit, &hit->uv)) { /* make default shading frame */ #ifdef NEVER VECTOR N = PatchInterpolatedNormalAtUV(hit->patch, hit->uv.u, hit->uv.v); if (Z) *Z = N; if (X && Y && Z) { double zz = sqrt(1 - Z->z*Z->z); if (zz < EPSILON) { /* horizontal brush direction X */ VECTORSET(*X, 1., 0., 0.); } else { VECTORSET(*X, Z->y/zz, -Z->x/zz, 0.); } VECTORCROSSPRODUCT(*Z, *X, *Y); } #endif /* fprintf(stderr, "MaterialShadingFrame -> PatchShadingFrame\n"); */ PatchInterpolatedFrameAtUV(hit->patch, hit->uv.u, hit->uv.v, X, Y, Z); succes = TRUE; } return succes; }