#include "shader.h" #include "miaux.h" int voxel_dataset_version(void) { return 1; } #define MAX_DATASET_SIZE 400*400*400 typedef struct { int width, height, depth; float block[MAX_DATASET_SIZE]; } voxel_data; float voxel_value(voxel_data *voxels, float x, float y, float z) { return voxels->block[ ((int)(z + .5)) * voxels->depth * voxels->height + ((int)(y + .5)) * voxels->height + ((int)(x + .5)) ]; } struct voxel_density { miTag filename_tag; miVector min_point; miVector max_point; miColor color; }; DLLEXPORT int voxel_density_version(void) { return 1; } DLLEXPORT miBoolean voxel_density_init( miState *state, struct voxel_density *params, miBoolean *instance_init_required) { if (!params) { /* Main shader init (not an instance): */ *instance_init_required = miTRUE; } else { /* Instance initialization: */ char* filename = miaux_tag_to_string(*mi_eval_tag(¶ms->filename_tag), NULL); if (filename) { voxel_data *voxels = miaux_user_memory_pointer(state, sizeof(voxel_data)); miaux_read_volume_block( filename, &voxels->width, &voxels->height, &voxels->depth, voxels->block); mi_progress("Voxel dataset: %dx%dx%d", voxels->width, voxels->height, voxels->depth); } } return miTRUE; } DLLEXPORT miBoolean voxel_density_exit(miState *state, void *params) { return miaux_release_user_memory("voxel_density", state, params); } DLLEXPORT miBoolean voxel_density ( miScalar *result, miState *state, struct voxel_density *params ) { miVector *min_point = mi_eval_vector(¶ms->min_point); miVector *max_point = mi_eval_vector(¶ms->max_point); miVector *p = &state->point; if (miaux_point_inside(p, min_point, max_point)) { float x, y, z; voxel_data *voxels = miaux_user_memory_pointer(state, 0); x = miaux_fit(p->x, min_point->x, max_point->x, 0, voxels->width-1); y = miaux_fit(p->y, min_point->y, max_point->y, 0, voxels->height-1); z = miaux_fit(p->z, min_point->z, max_point->z, 0, voxels->depth-1); *result = voxel_value(voxels, x, y, z); } else *result = 0.0; return miTRUE; }