double miaux_fit( double v, double oldmin, double oldmax, double newmin, double newmax) { return newmin + ((v - oldmin) / (oldmax - oldmin)) * (newmax - newmin); } void miaux_scale_color(miColor *result, miScalar scale) { result->r *= scale; result->g *= scale; result->b *= scale; } void miaux_clamp_color(miColor *result) { result->r = miaux_clamp(result->r, 0.0, 1.0); result->g = miaux_clamp(result->g, 0.0, 1.0); result->b = miaux_clamp(result->b, 0.0, 1.0); result->a = miaux_clamp(result->a, 0.0, 1.0); } double miaux_clamp(double v, double minval, double maxval) { return v < minval ? minval -: v > maxval ? maxval -: v; } double miaux_shadow_breakpoint ( double color, double transparency, double breakpoint ) { if (transparency < breakpoint) return miaux_fit(transparency, 0, breakpoint, 0, color); else return miaux_fit(transparency, breakpoint, 1, color, 1); } void miaux_light_array(miTag **lights, int *light_count, miState *state, int *offset_param, int *count_param, miTag *lights_param) { int array_offset = *mi_eval_integer(offset_param); *light_count = *mi_eval_integer(count_param); *lights = mi_eval_tag(lights_param) + array_offset; } void miaux_set_channels(miColor *c, miScalar new_value) { c->r = c->g = c->b = c->a = new_value; } void miaux_add_diffuse_hair_component( miColor *result, miVector *hair_tangent, miVector *to_light, miColor *diffuse, miColor *light_color) { miScalar diffuse_factor = 1.0 - fabs(mi_vector_dot(hair_tangent, to_light)); miaux_add_diffuse_component(result, diffuse_factor, diffuse, light_color); } void miaux_add_diffuse_component( miColor *result, miScalar light_and_surface_cosine, miColor *diffuse, miColor *light_color) { result->r += light_and_surface_cosine * diffuse->r * light_color->r; result->g += light_and_surface_cosine * diffuse->g * light_color->g; result->b += light_and_surface_cosine * diffuse->b * light_color->b; } void miaux_add_specular_hair_component( miColor *result, miVector *hair_tangent, miVector *to_light, miVector *to_camera, miColor *specular, miColor *light_color) { miScalar light_angle = acos(mi_vector_dot(hair_tangent, to_light)); miScalar view_angle = acos(mi_vector_dot(hair_tangent, to_camera)); miScalar sum = light_angle + view_angle; miScalar specular_factor = fabs(M_PI_2 - fmod(sum, M_PI)) / M_PI_2; result->r += specular_factor * specular->r * light_color->r; result->g += specular_factor * specular->g * light_color->g; result->b += specular_factor * specular->b * light_color->b; } void miaux_add_scaled_color(miColor *result, miColor *color, miScalar scale) { result->r += color->r * scale; result->g += color->g * scale; result->b += color->b * scale; } void miaux_add_transparent_hair_component(miColor *result, miState *state) { miColor background_color; mi_trace_transparent(&background_color, state); if (result->a == 0) { miaux_opacity_set_channels(state, 0.0); miaux_copy_color(result, &background_color); } else { miaux_opacity_set_channels(state, result->a); miaux_blend_colors(result, result, &background_color, result->a); } } void miaux_opacity_set_channels(miState *state, miScalar value) { miColor opacity; miaux_set_channels(&opacity, value); mi_opacity_set(state, &opacity); } void miaux_copy_color(miColor *result, miColor *color) { result->r = color->r; result->g = color->g; result->b = color->b; result->a = color->a; } void miaux_blend_colors(miColor *result, miColor *color1, miColor *color2, miScalar factor) { result->r = miaux_blend(color1->r, color2->r, factor); result->g = miaux_blend(color1->g, color2->g, factor); result->b = miaux_blend(color1->b, color2->b, factor); } double miaux_blend(miScalar a, miScalar b, miScalar factor) { return a * factor + b * (1.0 - factor); }