Shader triangles

Click on the filename to display or download the file.

triangles.mi
declare shader 
    geometry "triangles" ( 
	string "name", 
        integer "count" default 100, 
	vector "bbox_min" default -.5 -.5 -.5, 
	vector "bbox_max" default .5 .5 .5, 
	scalar "edge_length_max" default 1, 
        integer "random_seed" default 1955 ) 
    version 1 
    apply geometry 
end declare 

triangles.c
#include "shader.h" 
#include "geoshader.h" 
#include "miaux.h" 
 
struct triangles { 
    miTag name; 
    miInteger count; 
    miVector bbox_min; 
    miVector bbox_max; 
    miScalar edge_length_max; 
    miInteger random_seed; 
}; 
 
DLLEXPORT 
int triangles_version(void) { return 1; } 
 
DLLEXPORT 
miBoolean triangles ( 
    miTag *result, miState *state, struct triangles *params  ) 
{ 
    int vertex_index; 
    miObject *obj; 
    miInteger count = *mi_eval_integer(&params->count); 
    miVector *bbox_min = mi_eval_vector(&params->bbox_min); 
    miVector *bbox_max = mi_eval_vector(&params->bbox_max); 
    miScalar edge_length_max = *mi_eval_scalar(&params->edge_length_max); 
    char* name =  
        miaux_tag_to_string(*mi_eval_tag(&params->name), "::triangles"); 
 
    mi_srandom(*mi_eval_integer(&params->random_seed)); 
 
    obj = mi_api_object_begin(mi_mem_strdup(name)); 
    obj->visible = miTRUE; 
    obj->shadow = 3; 
 
    mi_api_object_group_begin(0.0); 
    for (vertex_index = 0; vertex_index < count * 3; vertex_index += 3) 
        miaux_add_random_triangle( 
            vertex_index, edge_length_max, bbox_min, bbox_max); 
    mi_api_object_group_end(); 
 
    return mi_geoshader_add_result(result, mi_api_object_end()); 
} 

triangles_util.c
char* miaux_tag_to_string(miTag tag, char *default_value) 
{ 
    char *result = default_value; 
    if (tag != 0) { 
	result = (char*)mi_db_access(tag); 
	mi_db_unpin(tag); 
    } 
    return result; 
} 
 
void miaux_add_random_triangle(int index, float edge_length_max, 
			       miVector *bbox_min, miVector *bbox_max) 
{ 
    int vertex_index; 
    float offset_max = edge_length_max / 2.0; 
    float offset_min = -offset_max; 
    float x, y, z; 
 
    miaux_random_point_in_unit_sphere(&x, &y, &z); 
    x = miaux_fit(x, -.5, .5, bbox_min->x, bbox_max->x); 
    y = miaux_fit(y, -.5, .5, bbox_min->y, bbox_max->y); 
    z = miaux_fit(z, -.5, .5, bbox_min->z, bbox_max->z); 
 
    miaux_add_vertex(index, x, y, z); 
    miaux_add_vertex(index + 1,  
		     x + miaux_random_range(offset_min, offset_max), 
		     y + miaux_random_range(offset_min, offset_max), 
		     z + miaux_random_range(offset_min, offset_max)); 
    miaux_add_vertex(index + 2,  
		     x + miaux_random_range(offset_min, offset_max), 
		     y + miaux_random_range(offset_min, offset_max), 
		     z + miaux_random_range(offset_min, offset_max)); 
 
    mi_api_poly_begin_tag(1, 0); 
    for (vertex_index = 0; vertex_index < 3; vertex_index++) 
	mi_api_poly_index_add(index + vertex_index); 
    mi_api_poly_end(); 
} 
 
void miaux_random_point_in_unit_sphere(float *x, float *y, float *z) 
{ 
    do { 
	*x = miaux_random_range(-.5, .5); 
	*y = miaux_random_range(-.5, .5); 
	*z = miaux_random_range(-.5, .5); 
    } while (sqrt((*x * *x) +(*y * *y) + (*z * *z)) >= 0.5); 
} 
 
result->r += miaux_random_range(-red_variance, red_variance); 
    result->r = miaux_clamp(result->r, 0.0, 1.0); 
    result->g += miaux_random_range(-green_variance, green_variance); 
    result->g = miaux_clamp(result->g, 0.0, 1.0); 
    result->b += miaux_random_range(-blue_variance, blue_variance); 
    result->b = miaux_clamp(result->b, 0.0, 1.0); 
} 
 
double miaux_fit( 
    double v, double oldmin, double oldmax, double newmin, double newmax)     
{ 
    return newmin + ((v - oldmin) / (oldmax - oldmin)) * (newmax - newmin); 
} 
 
void miaux_add_vertex(int index, miScalar x, miScalar y, miScalar z) 
{ 
    miVector v; 
    v.x = x; v.y = y; v.z = z; 
    mi_api_vector_xyz_add(&v); 
    mi_api_vertex_add(index); 
} 

22 April 2008 23:40:35