double miaux_max(double a, double b) { return a > b ? a -: b; } void miaux_init_bbox(miObject *obj) { obj->bbox_min.x = miHUGE_SCALAR; obj->bbox_min.y = miHUGE_SCALAR; obj->bbox_min.z = miHUGE_SCALAR; obj->bbox_max.x = -miHUGE_SCALAR; obj->bbox_max.y = -miHUGE_SCALAR; obj->bbox_max.z = -miHUGE_SCALAR; } void miaux_adjust_bbox(miObject *obj, miVector *v, miScalar extra) { miVector v_extra, vmin, vmax; miaux_set_vector(&v_extra, extra, extra, extra); mi_vector_sub(&vmin, v, &v_extra); mi_vector_add(&vmax, v, &v_extra); mi_vector_min(&obj->bbox_min, &obj->bbox_min, &vmin); mi_vector_max(&obj->bbox_max, &obj->bbox_max, &vmax); } void miaux_set_vector(miVector *v, double x, double y, double z) { v->x = x; v->y = y; v->z = z; } void miaux_describe_bbox(miObject *obj) { mi_progress("Object bbox: %f,%f,%f %f,%f,%f", obj->bbox_min.x, obj->bbox_min.y, obj->bbox_min.z, obj->bbox_max.x, obj->bbox_max.y, obj->bbox_max.z); } void miaux_define_hair_object( miTag name_tag, miaux_bbox_function bbox_function, void *params, miTag *geoshader_result, miApi_object_callback callback) { miTag tag; miObject *obj; char *name = miaux_tag_to_string(name_tag, "::hair"); obj = mi_api_object_begin(mi_mem_strdup(name)); obj->visible = miTRUE; obj->shadow = obj->reflection = obj->refraction = 3; bbox_function(obj, params); if (geoshader_result != NULL && callback != NULL) { mi_api_object_callback(callback, params); tag = mi_api_object_end(); mi_geoshader_add_result(geoshader_result, tag); obj = (miObject *)mi_scene_edit(tag); obj->geo.placeholder_list.type = miOBJECT_HAIR; mi_scene_edit_end(tag); } } 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_append_hair_data( miScalar **scalar_array, miVector *v, miScalar position, miScalar root_radius, miColor *root, miScalar tip_radius, miColor *tip ) { (*scalar_array)[0] = v->x; (*scalar_array)[1] = v->y; (*scalar_array)[2] = v->z; (*scalar_array)[3] = miaux_fit(position, 0, 1, root_radius, tip_radius); (*scalar_array)[4] = miaux_fit(position, 0, 1, root->r, tip->r); (*scalar_array)[5] = miaux_fit(position, 0, 1, root->g, tip->g); (*scalar_array)[6] = miaux_fit(position, 0, 1, root->b, tip->b); (*scalar_array)[7] = miaux_fit(position, 0, 1, root->a, tip->a); *scalar_array += 8; } double miaux_fit( double v, double oldmin, double oldmax, double newmin, double newmax) { return newmin + ((v - oldmin) / (oldmax - oldmin)) * (newmax - newmin); }