Click on the filename to display or download the file.
hair_geo_datafile.mi
declare shader
geometry "hair_geo_datafile" (
string "name",
scalar "radius" default .1,
string "particle_filename" )
version 1
apply material
end declare
hair_geo_datafile.c
#include "shader.h"
#include "geoshader.h"
#include "miaux.h"
miBoolean hair_geo_datafile_callback(miTag tag, void *ptr);
typedef struct {
miTag name;
miScalar radius;
miTag particle_filename;
} hair_geo_datafile_t;
DLLEXPORT
int hair_geo_datafile_version(void) { return 1; }
void hair_geo_datafile_bbox(miObject *obj, void* params)
{
hair_geo_datafile_t *hairdata = (hair_geo_datafile_t*)params;
char* particle_filename;
particle_filename =
miaux_tag_to_string(hairdata->particle_filename, NULL);
if (particle_filename == NULL)
mi_fatal("Particle filename required for hair_geo_datafile.");
miaux_hair_data_file_bounding_box(
particle_filename,
&obj->bbox_min.x, &obj->bbox_min.y, &obj->bbox_min.z,
&obj->bbox_max.x, &obj->bbox_max.y, &obj->bbox_max.z);
}
DLLEXPORT
miBoolean hair_geo_datafile (
miTag *result, miState *state, hair_geo_datafile_t *params )
{
hair_geo_datafile_t *hairdata =
(hair_geo_datafile_t*)mi_mem_allocate(sizeof(hair_geo_datafile_t));
hairdata->radius = *mi_eval_scalar(¶ms->radius);
hairdata->particle_filename = *mi_eval_tag(¶ms->particle_filename);
miaux_define_hair_object(
hairdata->name, hair_geo_datafile_bbox, hairdata, result,
hair_geo_datafile_callback);
return miTRUE;
}
miBoolean hair_geo_datafile_callback(miTag tag, void *ptr)
{
miHair_list *hair;
hair_geo_datafile_t *hairdata = (hair_geo_datafile_t *)ptr;
mi_api_incremental(miTRUE);
miaux_define_hair_object(
hairdata->name, hair_geo_datafile_bbox, hairdata, NULL, NULL);
hair = mi_api_hair_begin();
hair->approx = hair->degree = 1;
miaux_read_hair_data_file(
miaux_tag_to_string(hairdata->particle_filename, NULL),
hairdata->radius);
mi_api_hair_end();
mi_api_object_end();
return miTRUE;
}
hair_geo_datafile_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_hair_data_file_bounding_box(
char* filename,
float *xmin, float *ymin, float *zmin,
float *xmax, float *ymax, float *zmax)
{
int hair_count, data_count;
FILE* fp = fopen(filename, "r");
fscanf(fp, "%d %d ", &hair_count, &data_count); /* Ignore. */
fscanf(fp, "%f %f %f %f %f %f ", xmin, ymin, zmin, xmax, ymax, zmax);
fclose(fp);
}
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);
}
}
void miaux_read_hair_data_file(char* filename, miScalar radius)
{
int vertex_count, total_vertex_count, hair_scalar_size, vertex_total = 0,
index_array_size, v, *hair_indices, *hi, hair_count, per_hair_scalars;
float xmin, ymin, zmin, xmax, ymax, zmax, age;
miScalar coord, *hair_scalars;
miGeoIndex *harray;
FILE *fp;
fp = fopen(filename, "r");
fscanf(fp, "%d %d ", &hair_count, &total_vertex_count);
fscanf(fp, "%f %f %f %f %f %f ",
&xmin, &ymin, &zmin, &xmax, &ymax, &zmax);
mi_progress("particle bounding box: %f %f %f %f %f %f ",
xmin, ymin, zmin, xmax, ymax, zmax);
per_hair_scalars = 2;
mi_api_hair_info(0, 'r', 1);
mi_api_hair_info(0, 't', 1);
hair_scalar_size = hair_count * per_hair_scalars + total_vertex_count * 3;
hair_scalars = mi_api_hair_scalars_begin(hair_scalar_size);
index_array_size = 1 + hair_count;
hi = hair_indices = (int*)mi_mem_allocate(sizeof(int) * index_array_size);
*hi++ = 0;
vertex_total = 0;
while (!feof(fp)) {
*hair_scalars++ = radius;
fscanf(fp, "%f ", &age);
*hair_scalars++ = age;
fscanf(fp, "%d ", &vertex_count);
for (v = 0; v < vertex_count * 3; v++) {
fscanf(fp, "%f ", &coord);
*hair_scalars++ = coord;
}
vertex_total += vertex_count * 3 + per_hair_scalars;
*hi++ = vertex_total;
}
mi_api_hair_scalars_end(hair_scalar_size);
harray = mi_api_hair_hairs_begin(index_array_size);
memcpy(harray, hair_indices, index_array_size * sizeof(int));
mi_api_hair_hairs_end();
}
22 April 2008 23:40:45