Shader instanced_object_file

Click on the filename to display or download the file.

instanced_object_file.mi
declare shader 
    geometry "instanced_object_file" ( 
        string "name", 
        string "filename",  
	material "material", 
        vector "bbox_min" default -1 -1 -1, 
        vector "bbox_max" default 1 1 1, 
	array vector "positions" ) 
    version 1 
end declare 

instanced_object_file.c
#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(&params->n_positions); 
    miVector *positions = mi_eval_vector(params->positions) +  
        *mi_eval_integer(&params->i_positions); 
 
    if (!(name = miaux_tag_to_string(*mi_eval_tag(&params->name), NULL)) || 
        !(filename = miaux_tag_to_string(*mi_eval_tag(&params->filename), NULL))) 
        return miFALSE; 
 
    object_tag = miaux_object_from_file(name, filename,  
                                        *mi_eval_vector(&params->bbox_min), 
                                        *mi_eval_vector(&params->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(&params->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; 
} 

instanced_object_file_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; 
} 
 
miTag miaux_object_from_file( 
    const char* name, const char* filename,  
    miVector bbox_min, miVector bbox_max) 
{ 
    miObject *obj = mi_api_object_begin(mi_mem_strdup(name)); 
    obj->visible = miTRUE; 
    obj->shadow = 3; 
    obj->bbox_min = bbox_min; 
    obj->bbox_max = bbox_max; 
    mi_api_object_file(mi_mem_strdup(filename)); 
    return mi_api_object_end(); 
} 

22 April 2008 23:40:37