int c_hmaterial( int argc, char **argv )
C_MATERIAL *c_getmaterial( char *name )
extern char *c_cmname
extern C_MATERIAL *c_cmaterial
mg_ehand[MG_E_MATERIAL] = c_hmaterial; /* support "m" entity */ mg_ehand[MG_E_ED] = c_hmaterial; /* support "ed" entity */ mg_ehand[MG_E_IR] = c_hmaterial; /* support "ir" entity */ mg_ehand[MG_E_RD] = c_hmaterial; /* support "rd" entity */ mg_ehand[MG_E_RS] = c_hmaterial; /* support "rs" entity */ mg_ehand[MG_E_SIDES] = c_hmaterial; /* support "sides" entity */ mg_ehand[MG_E_TD] = c_hmaterial; /* support "td" entity */ mg_ehand[MG_E_TS] = c_hmaterial; /* support "ts" entity */ /* other entity handler assignments... */ mg_init(); /* initialize parser */Any of the above entities besides m may be unsupported, but the parser will not attempt to include their effect into other members, e.g. an unsupported rs component will not be added back into the rd member. It is therefore safer to support all of the relevant material entities and make final approximations from the complete C_MATERIAL structure.
The c_getmaterial function takes the name of a defined material and returns a pointer to its C_MATERIAL structure, defined in "parser.h" as:
#define C_1SIDEDTHICK 0.005 /* assumed thickness of 1-sided mat. */ typedef struct { int clock; /* incremented each change -- resettable */ int sided; /* 1 if surface is 1-sided, 0 for 2-sided */ float nr, ni; /* index of refraction, real and imaginary */ float rd; /* diffuse reflectance */ C_COLOR rd_c; /* diffuse reflectance color */ float td; /* diffuse transmittance */ C_COLOR td_c; /* diffuse transmittance color */ float ed; /* diffuse emittance */ C_COLOR ed_c; /* diffuse emittance color */ float rs; /* specular reflectance */ C_COLOR rs_c; /* specular reflectance color */ float rs_a; /* specular reflectance roughness */ float ts; /* specular transmittance */ C_COLOR ts_c; /* specular transmittance color */ float ts_a; /* specular transmittance roughness */ } C_MATERIAL; /* material context */The clock member will be incremented each time the value gets changed by a material field entity, and may be reset by the calling program if desired. This is a convenient way to keep track of whether or not a material has changed since its last use.
All reflectance and transmittance values correspond to normal incidence, and may vary as a function of angle depending on the index of refraction. A solid object is normally represented with a one-sided material. A two-sided material is most appropriate for thin surfaces, though it may be used also when the surface normal orientations in a model are unreliable.
If a transparent or translucent surface is one-sided, then the absorption will change as a function of distance through the material, and a single value for diffuse or specular transmittance is ambiguous. We therefore define a standard thickness, C_1SIDEDTHICK, which is the object thickness to which the given values correspond, so that one may compute the isotropic absorptance of the material.
It is possible but not recommended to alter the contents of the material structure returned by c_getmaterial. Normally, this routine is never called directly, since there are no entities that access materials by name other than m.
The global variable c_cmname points to the name of the current material, or NULL if it is unnamed. The variable c_cmaterial points to the current material value, which should never be NULL.
The c_getmaterial function returns NULL if the specified material name is undefined, at which point the calling function should return an MG_EUNDEF error.