#include "shader.h" #include "geoshader.h" #include "miaux.h" typedef struct { miTag name; miInteger count; miScalar radius; miVector bbox_min; miVector bbox_max; miScalar y_offset_max; miScalar z_offset_max; miInteger approximation; miInteger degree; miInteger random_seed; } hair_geo_row_t; DLLEXPORT int hair_geo_row_version(void) { return 1; } void hair_geo_row_bbox(miObject *obj, void* params) { hair_geo_row_t *p = (hair_geo_row_t*)params; obj->bbox_min = p->bbox_min; obj->bbox_max = p->bbox_max; } miBoolean hair_geo_row_callback(miTag tag, void *ptr); DLLEXPORT miBoolean hair_geo_row ( miTag *result, miState *state, hair_geo_row_t *params ) { hair_geo_row_t *p = (hair_geo_row_t*) mi_mem_allocate(sizeof(hair_geo_row_t)); p->name = *mi_eval_tag(¶ms->name); p->count = *mi_eval_integer(¶ms->count); p->radius = *mi_eval_scalar(¶ms->radius); p->bbox_min = *mi_eval_vector(¶ms->bbox_min); p->bbox_max = *mi_eval_vector(¶ms->bbox_max); p->y_offset_max = *mi_eval_scalar(¶ms->y_offset_max); p->z_offset_max = *mi_eval_scalar(¶ms->z_offset_max); p->approximation = *mi_eval_integer(¶ms->approximation); p->degree = *mi_eval_integer(¶ms->degree); p->random_seed = *mi_eval_integer(¶ms->random_seed); miaux_define_hair_object( p->name, hair_geo_row_bbox, p, result, hair_geo_row_callback); return miTRUE; } miBoolean hair_geo_row_callback(miTag tag, void *ptr) { miHair_list *hair_list; miGeoIndex *harray; miScalar *hair_scalars; int i, h, per_hair_data_count, vertex_count, vertex_size, per_hair_scalar_count, total_scalar_count; hair_geo_row_t *p = (hair_geo_row_t *)ptr; miScalar x, y_offset, z_offset, yoff_max = p->y_offset_max, zoff_max = p->z_offset_max; mi_api_incremental(miTRUE); miaux_define_hair_object(p->name, hair_geo_row_bbox, p, NULL, NULL); hair_list = mi_api_hair_begin(); hair_list->approx = p->approximation; hair_list->degree = p->degree; mi_api_hair_info(0, 'r', 1); mi_api_hair_info(0, 't', 1); per_hair_data_count = 2; /* Radius and random value */ vertex_count = 4; vertex_size = 3; per_hair_scalar_count = vertex_count * vertex_size + per_hair_data_count; total_scalar_count = p->count * per_hair_scalar_count; hair_scalars = mi_api_hair_scalars_begin(total_scalar_count); mi_srandom(p->random_seed); for (i = 0; i < p->count; i++) { x = miaux_random_range(p->bbox_min.x, p->bbox_max.x); y_offset = miaux_random_range(-yoff_max, yoff_max); z_offset = miaux_random_range(-zoff_max, zoff_max); *hair_scalars++ = p->radius; *hair_scalars++ = miaux_random_range(0.0, 1.0); *hair_scalars++ = x; *hair_scalars++ = p->bbox_min.y + yoff_max + y_offset; *hair_scalars++ = p->bbox_min.z + zoff_max + z_offset; *hair_scalars++ = x; *hair_scalars++ = p->bbox_max.y - yoff_max + y_offset; *hair_scalars++ = p->bbox_min.z + zoff_max + z_offset; *hair_scalars++ = x; *hair_scalars++ = p->bbox_max.y - yoff_max + y_offset; *hair_scalars++ = p->bbox_max.z - zoff_max + z_offset; *hair_scalars++ = x; *hair_scalars++ = p->bbox_min.y + yoff_max + y_offset; *hair_scalars++ = p->bbox_max.z - zoff_max + z_offset; } mi_api_hair_scalars_end(total_scalar_count); harray = mi_api_hair_hairs_begin(p->count + 1); for (h=0; h < p->count + 1; h++) harray[h] = h * per_hair_scalar_count; mi_api_hair_hairs_end(); mi_api_hair_end(); mi_api_object_end(); return miTRUE; }