void* miaux_user_memory_pointer(miState *state, int allocation_size) { void **user_pointer; mi_query(miQ_FUNC_USERPTR, state, 0, &user_pointer); if (allocation_size > 0) { *user_pointer = mi_mem_allocate(allocation_size); } return *user_pointer; } void miaux_piecewise_color_sinusoid( miColor result[], int result_count, int key_count, miColor key_values[]) { int key, i; for (key = 1; key < key_count; key++) { int start = (int)(key_values[key-1].a * result_count); int end = (int)(key_values[key].a * result_count) - 1; for (i = start; i <= end; i++) { result[i].r = miaux_sinusoid_fit( i, start, end, key_values[key-1].r, key_values[key].r); result[i].g = miaux_sinusoid_fit( i, start, end, key_values[key-1].g, key_values[key].g); result[i].b = miaux_sinusoid_fit( i, start, end, key_values[key-1].b, key_values[key].b); } } } double miaux_sinusoid_fit( double v, double oldmin, double oldmax, double newmin, double newmax) { return miaux_fit(sin(miaux_fit(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); } miBoolean miaux_release_user_memory(char* shader_name, miState *state, void *params) { if (params != NULL) { /* Shader instance exit */ void **user_pointer; if (!mi_query(miQ_FUNC_USERPTR, state, 0, &user_pointer)) mi_fatal("Could not get user pointer in shader exit function %s_exit", shader_name); mi_mem_release(*user_pointer); } return miTRUE; } void miaux_interpolated_color_lookup(miColor* result, miColor lookup_table[], int table_size, miScalar t) { int lower_index = (int)(t * table_size); miColor lower_value = lookup_table[lower_index]; int upper_index = lower_index + 1; miColor upper_value = lookup_table[upper_index]; result->r = miaux_fit(t * table_size, lower_index, upper_index, lower_value.r, upper_value.r); result->g = miaux_fit(t * table_size, lower_index, upper_index, lower_value.g, upper_value.g); result->b = miaux_fit(t * table_size, lower_index, upper_index, lower_value.b, upper_value.b); } float miaux_altitude(miState *state) { miVector ray; mi_vector_to_world(state, &ray, &state->dir); mi_vector_normalize(&ray); return miaux_fit(asin(ray.y), -M_PI_2, M_PI_2, 0.0, 1.0); }