#include #include #include "shader.h" #include "geoshader.h" #include "miaux.h" struct instanced_object_file { miTag name; miTag filename; miTag material; miVector bbox_min; miVector bbox_max; int i_positions; int n_positions; miVector positions[1]; }; DLLEXPORT int instanced_object_file_version(void) { return 1; } DLLEXPORT miBoolean instanced_object_file ( miTag *result, miState *state, struct instanced_object_file *params ) { int i; static int instance_index; /* Geometry shaders are single-threaded. */ char *filename, *name, instance_name[1024]; miInstance *instance; miTag object_tag, instance_tag; int position_count = *mi_eval_integer(¶ms->n_positions); miVector *positions = mi_eval_vector(params->positions) + *mi_eval_integer(¶ms->i_positions); if (!(name = miaux_tag_to_string(*mi_eval_tag(¶ms->name), NULL)) || !(filename = miaux_tag_to_string(*mi_eval_tag(¶ms->filename), NULL))) return miFALSE; object_tag = miaux_object_from_file(name, filename, *mi_eval_vector(¶ms->bbox_min), *mi_eval_vector(¶ms->bbox_max)); for (i = 0; i < position_count; i++, positions++) { miMatrix matrix; miTag material_tag; sprintf(instance_name, "%s-%d", name, instance_index++); if (!(instance = mi_api_instance_begin(mi_mem_strdup(instance_name)))) return miFALSE; mi_matrix_ident(matrix); matrix[12] = positions->x; matrix[13] = positions->y; matrix[14] = positions->z; mi_matrix_copy(instance->tf.local_to_global, matrix); mi_matrix_invert(instance->tf.global_to_local, instance->tf.local_to_global); material_tag = *mi_eval_tag(¶ms->material); if (material_tag) instance->material = mi_phen_clone(state, material_tag); instance_tag = mi_api_instance_end(0, object_tag, 0); if (instance_tag == miNULLTAG || mi_geoshader_add_result(result, instance_tag) == miFALSE) return miFALSE; } return miTRUE; }