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_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_mock_specular_component( miColor *result, miState *state, miVector *direction_toward_light, miColor *specular_color, miColor *cutoff, miColor *light_color) { miScalar lightdir_offset, r_scale, g_scale, b_scale; miColor attenuated_specular = {0,0,0,0}; lightdir_offset = mi_vector_dot(&state->normal, direction_toward_light); r_scale = miaux_sinusoid_fit_clamp(lightdir_offset, cutoff->r, 1.0, 0, 1); g_scale = miaux_sinusoid_fit_clamp(lightdir_offset, cutoff->g, 1.0, 0, 1); b_scale = miaux_sinusoid_fit_clamp(lightdir_offset, cutoff->b, 1.0, 0, 1); miaux_scale_channels(&attenuated_specular, specular_color, r_scale, g_scale, b_scale); miaux_multiply_colors(light_color, light_color, &attenuated_specular); miaux_add_color(result, light_color); } double miaux_sinusoid_fit_clamp( double v, double oldmin, double oldmax, double newmin, double newmax) { return miaux_fit(sin(miaux_fit_clamp(v, oldmin, oldmax, -M_PI_2, M_PI_2)), -1, 1, newmin, newmax); } double miaux_fit( double v, double oldmin, double oldmax, double newmin, double newmax) { return newmin + ((v - oldmin) / (oldmax - oldmin)) * (newmax - newmin); } double miaux_fit_clamp( double v, double oldmin, double oldmax, double newmin, double newmax) { if (oldmin > oldmax) { double temp = oldmin; oldmin = oldmax; oldmax = oldmin; temp = newmin; newmin = newmax; newmax = newmin; } if (v < oldmin) return newmin; else if (v > oldmax) return newmax; else return miaux_fit(v, oldmin, oldmax, newmin, newmax); } void miaux_scale_channels(miColor *result, miColor* color, miScalar r_scale, miScalar g_scale, miScalar b_scale) { result->r = color->r * r_scale; result->g = color->g * g_scale; result->b = color->b * b_scale; } void miaux_multiply_colors(miColor *result, miColor *x, miColor *y) { result->r = x->r * y->r; result->g = x->g * y->g; result->b = x->b * y->b; } void miaux_add_color(miColor *result, miColor *c) { result->r += c->r; result->g += c->g; result->b += c->b; result->a += c->a; } 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; }