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(¶ms->count);
miVector *bbox_min = mi_eval_vector(¶ms->bbox_min);
miVector *bbox_max = mi_eval_vector(¶ms->bbox_max);
miScalar edge_length_max = *mi_eval_scalar(¶ms->edge_length_max);
char* name =
miaux_tag_to_string(*mi_eval_tag(¶ms->name), "::triangles");
mi_srandom(*mi_eval_integer(¶ms->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