void printST () { int i; char type[9] = "<none> "; printf("SYMBOL TABLE - scope: %d\n", scope); for (i = 0; i <= top; i++) { //fprintf (stderr, "its scope: %d the scope: %d\n", ST[i]->scope, scope); if (ST[i]->scope <= scope) { // only print if visible in current scope int t = ST[i]->type; if (t == Boolean) { strcpy (type, "Boolean"); } else if ( t == Integer) { strcpy (type, "Integer"); } else if (t == Array && ST[i]->arrayBaseT == Integer) { strcpy (type, "Array:Integers"); } else if (t == Array && ST[i]->arrayBaseT == Boolean) { strcpy (type, "Array:Booleans"); } else { strcpy (type, "<none> "); } if (t != Array) { printf ("%3d %-10s\t%-16s scope: %d\n", i,id_name (i), type, ST[i]->scope); } else { printf ("%3d %-10s\t%-16s scope: %d range: %d..%d\n", i, id_name (i), type, ST[i]->scope, ST[i]->aStart, ST[i]->aEnd); } } } }
void check_stmt(tree t) { for( ; t != NULL; t = t->next ) { switch (t->kind) { case If: case Elseif: if( check_expr(t->first) != Boolean ) { print_error("Invalid IF statement.", t); } check_stmt(t->second); check_stmt(t->third); continue; case Else: check_stmt(t->first); continue; case Exit: if(check_expr(t->first) != Boolean) { print_error("exit when must produce a boolean.", t); } continue; case Assign: if(t->first->kind == Obracket | check_expr(t->first) != check_expr(t->second)) { print_error("Invalid assignment statement.", t); } continue; case For: new_scope(); declare_var(id_name(t->first->value), Integer); if(check_expr(t->second->first) != Integer | check_expr(t->second->second) != Integer)//TODO or add a range check print_error("Invalid range.", t->second); check_stmt(t->third); end_scope(); continue; case Declaration:; if(t->second->kind == Array) { for(tree cur = t->first; cur != NULL; cur = cur->next) declare_array(id_name(cur->value), t->second->second->kind); } else { for(tree cur = t->first; cur != NULL; cur = cur->next) declare_var(id_name(cur->value), t->second->kind); } continue; case Declare: new_scope(); check_stmt(t->first); check_stmt(t->second); end_scope(); continue; default: print_error("Token of this type not checked by check_stmt.", t); continue; } } }
std::string ControllerExporter::add_morph_targets(Key *key, Object *ob) { std::string source_id = translate_id(id_name(ob)) + TARGETS_SOURCE_ID_SUFFIX; COLLADASW::IdRefSource source(mSW); source.setId(source_id); source.setArrayId(source_id + ARRAY_ID_SUFFIX); source.setAccessorCount(key->totkey - 1); source.setAccessorStride(1); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); param.push_back("IDREF"); source.prepareToAppendValues(); KeyBlock *kb = (KeyBlock *)key->block.first; //skip the basis kb = kb->next; for (; kb; kb = kb->next) { std::string geom_id = get_geometry_id(ob, false) + "_morph_" + translate_id(kb->name); source.appendValues(geom_id); } source.finish(); return source_id; }
std::string ControllerExporter::add_morph_weights(Key *key, Object *ob) { std::string source_id = translate_id(id_name(ob)) + WEIGHTS_SOURCE_ID_SUFFIX; COLLADASW::FloatSourceF source(mSW); source.setId(source_id); source.setArrayId(source_id + ARRAY_ID_SUFFIX); source.setAccessorCount(key->totkey - 1); source.setAccessorStride(1); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); param.push_back("MORPH_WEIGHT"); source.prepareToAppendValues(); KeyBlock *kb = (KeyBlock *)key->block.first; //skip the basis kb = kb->next; for (; kb; kb = kb->next) { float weight = kb->curval; source.appendValues(weight); } source.finish(); return source_id; }
void CamerasExporter::operator()(Object *ob, Scene *sce) { // TODO: shiftx, shifty, YF_dofdist Camera *cam = (Camera*)ob->data; std::string cam_id(get_camera_id(ob)); std::string cam_name(id_name(cam)); switch (cam->type) { case CAM_PANO: case CAM_PERSP: { COLLADASW::PerspectiveOptic persp(mSW); persp.setXFov(RAD2DEGF(focallength_to_fov(cam->lens, cam->sensor_x)), "xfov"); persp.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch), false, "aspect_ratio"); persp.setZFar(cam->clipend, false, "zfar"); persp.setZNear(cam->clipsta, false, "znear"); COLLADASW::Camera ccam(mSW, &persp, cam_id, cam_name); addCamera(ccam); break; } case CAM_ORTHO: default: { COLLADASW::OrthographicOptic ortho(mSW); ortho.setXMag(cam->ortho_scale, "xmag"); ortho.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch), false, "aspect_ratio"); ortho.setZFar(cam->clipend, false, "zfar"); ortho.setZNear(cam->clipsta, false, "znear"); COLLADASW::Camera ccam(mSW, &ortho, cam_id, cam_name); addCamera(ccam); break; } } }
void SceneExporter::exportScene(Scene *sce) { // <library_visual_scenes> <visual_scene> std::string id_naming = id_name(sce); openVisualScene(translate_id(id_naming), id_naming); exportHierarchy(sce); closeVisualScene(); closeLibrary(); }
void MaterialsExporter::operator()(Material *ma, Object *ob) { std::string name(id_name(ma)); openMaterial(get_material_id(ma), translate_id(name)); std::string efid = translate_id(name) + "-effect"; addInstanceEffect(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, efid)); closeMaterial(); }
//Get proper name for bones std::string AnimationExporter::getObjectBoneName(Object *ob, const FCurve *fcu) { //hard-way to derive the bone name from rna_path. Must find more compact method std::string rna_path = std::string(fcu->rna_path); char *boneName = strtok((char *)rna_path.c_str(), "\""); boneName = strtok(NULL, "\""); if (boneName != NULL) return /*id_name(ob) + "_" +*/ std::string(boneName); else return id_name(ob); }
COLLADASW::ColorOrTexture EffectsExporter::createTexture(Image *ima, std::string& uv_layer_name, COLLADASW::Sampler *sampler /*COLLADASW::Surface *surface*/) { COLLADASW::Texture texture(translate_id(id_name(ima))); texture.setTexcoord(uv_layer_name); //texture.setSurface(*surface); texture.setSampler(*sampler); COLLADASW::ColorOrTexture cot(texture); return cot; }
void ArmatureExporter::write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone) { if (bc_is_root_bone(bone, this->export_settings.get_deform_bones_only())) { std::string joint_id = translate_id(id_name(ob_arm) + "_" + bone->name); ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, joint_id)); } else { for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { write_bone_URLs(ins, ob_arm, child); } } }
void EffectsExporter::exportEffects(Scene *sce) { this->scene = sce; if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) { if (hasEffects(sce)) { MaterialFunctor mf; openLibrary(); mf.forEachMaterialInExportSet<EffectsExporter>(sce, *this, this->export_settings->export_set); closeLibrary(); } } else { std::set<Object *> uv_textured_obs = bc_getUVTexturedObjects(sce, !this->export_settings->active_uv_only); std::set<Image *> uv_images = bc_getUVImages(sce, !this->export_settings->active_uv_only); if (uv_images.size() > 0) { openLibrary(); std::set<Image *>::iterator uv_images_iter; for (uv_images_iter = uv_images.begin(); uv_images_iter != uv_images.end(); uv_images_iter++) { Image *ima = *uv_images_iter; std::string key(id_name(ima)); key = translate_id(key); COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D, key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); sampler.setImageId(key); openEffect(key + "-effect"); COLLADASW::EffectProfile ep(mSW); ep.setProfileType(COLLADASW::EffectProfile::COMMON); ep.setShaderType(COLLADASW::EffectProfile::PHONG); ep.setDiffuse(createTexture(ima, key, &sampler), false, "diffuse"); COLLADASW::ColorOrTexture cot = getcol(0, 0, 0, 1.0f); ep.setSpecular(cot, false, "specular"); ep.openProfile(); ep.addProfileElements(); ep.addExtraTechniques(mSW); ep.closeProfile(); closeEffect(); } closeLibrary(); } } }
// ob should be of type OB_MESH // both args are required void ArmatureExporter::export_controller(Object* ob, Object *ob_arm) { // joint names // joint inverse bind matrices // vertex weights // input: // joint names: ob -> vertex group names // vertex group weights: me->dvert -> groups -> index, weight /* me->dvert: typedef struct MDeformVert { struct MDeformWeight *dw; int totweight; int flag; // flag only in use for weightpaint now } MDeformVert; typedef struct MDeformWeight { int def_nr; float weight; } MDeformWeight; */ Mesh *me = (Mesh*)ob->data; if (!me->dvert) return; std::string controller_name = id_name(ob_arm); std::string controller_id = get_controller_id(ob_arm, ob); openSkin(controller_id, controller_name, COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob))); add_bind_shape_mat(ob); std::string joints_source_id = add_joints_source(ob_arm, &ob->defbase, controller_id); std::string inv_bind_mat_source_id = add_inv_bind_mats_source(ob_arm, &ob->defbase, controller_id); std::string weights_source_id = add_weights_source(me, controller_id); add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id); add_vertex_weights_element(weights_source_id, joints_source_id, me, ob_arm, &ob->defbase); closeSkin(); closeController(); }
void AnimationExporter::dae_baked_animation(std::vector<float> &fra, Object *ob_arm, Bone *bone) { std::string ob_name = id_name(ob_arm); std::string bone_name = bone->name; char anim_id[200]; if (!fra.size()) return; BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(), (char *)translate_id(bone_name).c_str(), "pose_matrix"); openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING); // create input source std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::INPUT, fra, false, anim_id, ""); // create output source std::string output_id; output_id = create_4x4_source(fra, ob_arm, bone, anim_id); // create interpolations source std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, ""); std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX; COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id); std::string empty; sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id)); sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id)); // TODO create in/out tangents source // this input is required sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id)); addSampler(sampler); std::string target = translate_id(bone_name) + "/transform"; addChannel(COLLADABU::URI(empty, sampler_id), target); closeAnimation(); }
void ImagesExporter::operator()(Material *ma, Object *ob) { int a; for (a = 0; a < MAX_MTEX; a++) { MTex *mtex = ma->mtex[a]; if (mtex && mtex->tex && mtex->tex->ima) { Image *image = mtex->tex->ima; std::string name(id_name(image)); name = translate_id(name); char rel[FILE_MAX]; char abs[FILE_MAX]; char src[FILE_MAX]; char dir[FILE_MAX]; BLI_split_dirfile(mfilename, dir, NULL); BKE_rebase_path(abs, sizeof(abs), rel, sizeof(rel), G.main->name, image->name, dir); if (abs[0] != '\0') { // make absolute source path BLI_strncpy(src, image->name, sizeof(src)); BLI_path_abs(src, G.main->name); // make dest directory if it doesn't exist BLI_make_existing_file(abs); if (BLI_copy_fileops(src, abs) != 0) { fprintf(stderr, "Cannot copy image to file's directory. \n"); } } if (find(mImages.begin(), mImages.end(), name) == mImages.end()) { COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(rel)), name, name); /* set name also to mNameNC. This helps other viewers import files exported from Blender better */ img.add(mSW); mImages.push_back(name); } } } }
static void handle_decls (tree t) { int i; if (scope == 1) { for ( i = 0; i < 100; i++) { ST[i] = (STEntry *) malloc( sizeof( STEntry* )); } // init the NoType entry of ST ST[0]->index = 0; ST[0]->type = NoType; } for (; t != NULL; t = t->next) { int type = t->second->kind; tree p; if (type != Integer && type != Boolean && type != Array) { fprintf( stderr, "Bad type in decl\n"); continue; //return; } for (p = t->first; p != NULL; p = p->next) { int pos = p->value; static int test = 0; if (ST[pos]->valid == true || ST[pos] != NULL && scope > 1) { // don't overwrite existing push (ST[pos]); // push possible prev scope entry to stack ST[pos] = (STEntry *) malloc( sizeof( STEntry*)); // new entry here } ST[pos]->index = pos; ST[pos]->type = type; ST[pos]->scope = scope; char *tmp = id_name (p->value); ST[pos]->name = tmp; ST[pos]->valid = true; ST[pos]->typeSize = -1; ST[pos]->addr = -1; if (type == Array) { ST[pos]->aStart = t->second->first->first->value; ST[pos]->aEnd = t->second->first->second->value; ST[pos]->arrayBaseT = t->second->second->kind; } } } // end for t = t->next } // end handle_decls
void printTree (tree t) { if (t == NULL) return; for (; t != NULL; t = t->next) { printf ("%*s%s", indent, "", tokName[t->kind]); switch (t->kind) { case Ident: printf (" %s (%d)\n", id_name(t->value), t->value); break; case IntConst: printf (" %d\n", t->value); break; default: printf ("\n"); indent += 2; printTree (t->first); printTree (t->second); printTree (t->third); indent -= 2; } // end switch } // end for loop } // end printTree()
void ControllerExporter::export_morph_controller(Object *ob, Key *key) { bool use_instantiation = this->export_settings->use_object_instantiation; Mesh *me; me = bc_get_mesh_copy(scene, ob, this->export_settings->export_mesh_type, this->export_settings->apply_modifiers, this->export_settings->triangulate); std::string controller_name = id_name(ob) + "-morph"; std::string controller_id = get_controller_id(key, ob); openMorph(controller_id, controller_name, COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, use_instantiation))); std::string targets_id = add_morph_targets(key, ob); std::string morph_weights_id = add_morph_weights(key, ob); COLLADASW::TargetsElement targets(mSW); COLLADASW::InputList &input = targets.getInputList(); input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::MORPH_TARGET, // constant declared in COLLADASWInputList.h COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, targets_id))); input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::MORPH_WEIGHT, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, morph_weights_id))); targets.add(); BKE_libblock_free_us(G.main, me); //support for animations //can also try the base element and param alternative add_weight_extras(key); closeMorph(); closeController(); }
static int id(int argc, wchar_t **argv) { if (2 < argc) usage(); NTSTATUS Result; if (2 == argc) { if (L'S' == argv[1][0] && L'-' == argv[1][1] && L'1' == argv[1][2] && L'-' == argv[1][3]) Result = id_sid(argv[1]); else { Result = id_uid(argv[1]); if (STATUS_INVALID_PARAMETER == Result) Result = id_name(argv[1]); } } else Result = id_user(); return FspWin32FromNtStatus(Result); }
void MaterialsExporter::exportMaterials(Scene *sce) { if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) { if (hasMaterials(sce)) { openLibrary(); MaterialFunctor mf; mf.forEachMaterialInExportSet<MaterialsExporter>(sce, *this, this->export_settings->export_set); closeLibrary(); } } else { std::set<Image *> uv_images = bc_getUVImages(sce, !this->export_settings->active_uv_only); if (uv_images.size() > 0) { openLibrary(); std::set<Image *>::iterator uv_images_iter; for (uv_images_iter = uv_images.begin(); uv_images_iter != uv_images.end(); uv_images_iter++) { Image *ima = *uv_images_iter; std::string matid(id_name(ima)); openMaterial(get_material_id_from_id(matid), translate_id(matid)); std::string efid = translate_id(matid) + "-effect"; addInstanceEffect(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, efid)); closeMaterial(); } closeLibrary(); } } }
std::string ArmatureExporter::get_controller_id(Object *ob_arm, Object *ob) { return translate_id(id_name(ob_arm)) + "_" + translate_id(id_name(ob)) + SKIN_CONTROLLER_ID_SUFFIX; }
void SceneExporter::writeNodes(Object *ob, Scene *sce) { // Add associated armature first if available bool armature_exported = false; Object *ob_arm = bc_get_assigned_armature(ob); if (ob_arm != NULL) { armature_exported = bc_is_in_Export_set(this->export_settings->export_set, ob_arm); if (armature_exported && bc_is_marked(ob_arm)) { bc_remove_mark(ob_arm); writeNodes(ob_arm, sce); armature_exported = true; } } COLLADASW::Node colladaNode(mSW); colladaNode.setNodeId(translate_id(id_name(ob))); colladaNode.setNodeName(translate_id(id_name(ob))); colladaNode.setType(COLLADASW::Node::NODE); colladaNode.start(); std::list<Object *> child_objects; // list child objects LinkNode *node; for (node=this->export_settings->export_set; node; node=node->next) { // cob - child object Object *cob = (Object *)node->link; if (cob->parent == ob) { switch (cob->type) { case OB_MESH: case OB_CAMERA: case OB_LAMP: case OB_EMPTY: case OB_ARMATURE: if (bc_is_marked(cob)) child_objects.push_back(cob); break; } } } if (ob->type == OB_MESH && armature_exported) // for skinned mesh we write obmat in <bind_shape_matrix> TransformWriter::add_node_transform_identity(colladaNode); else TransformWriter::add_node_transform_ob(colladaNode, ob); // <instance_geometry> if (ob->type == OB_MESH) { bool instance_controller_created = false; if (armature_exported) { instance_controller_created = arm_exporter->add_instance_controller(ob); } if (!instance_controller_created) { COLLADASW::InstanceGeometry instGeom(mSW); instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, this->export_settings->use_object_instantiation))); InstanceWriter::add_material_bindings(instGeom.getBindMaterial(), ob, this->export_settings->active_uv_only); instGeom.add(); } } // <instance_controller> else if (ob->type == OB_ARMATURE) { arm_exporter->add_armature_bones(ob, sce, this, child_objects); } // <instance_camera> else if (ob->type == OB_CAMERA) { COLLADASW::InstanceCamera instCam(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_camera_id(ob))); instCam.add(); } // <instance_light> else if (ob->type == OB_LAMP) { COLLADASW::InstanceLight instLa(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_light_id(ob))); instLa.add(); } // empty object else if (ob->type == OB_EMPTY) { // TODO: handle groups (OB_DUPLIGROUP if ((ob->transflag & OB_DUPLIGROUP) == OB_DUPLIGROUP && ob->dup_group) { GroupObject *go = NULL; Group *gr = ob->dup_group; /* printf("group detected '%s'\n", gr->id.name+2); */ for (go = (GroupObject *)(gr->gobject.first); go; go = go->next) { printf("\t%s\n", go->ob->id.name); } } } if (ob->type == OB_ARMATURE) { colladaNode.end(); } for (std::list<Object *>::iterator i = child_objects.begin(); i != child_objects.end(); ++i) { if (bc_is_marked(*i)) { bc_remove_mark(*i); writeNodes(*i, sce); } } if (ob->type != OB_ARMATURE) { colladaNode.end(); } }
std::string get_morph_id(Object *ob) { return translate_id(id_name(ob)) + "-morph"; }
std::string get_material_id(Material *mat) { return translate_id(id_name(mat)) + "-material"; }
std::string get_camera_id(Object *ob) { return translate_id(id_name(ob)) + "-camera"; }
std::string get_light_id(Object *ob) { return translate_id(id_name(ob)) + "-light"; }
std::string get_geometry_id(Object *ob, bool use_instantiation) { std::string geom_name = (use_instantiation) ? id_name(ob->data) : id_name(ob); return translate_id(geom_name) + "-mesh"; }
std::string get_geometry_id(Object *ob) { return translate_id(id_name(ob->data)) + "-mesh"; }
//convert f-curves to animation curves and write void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformName, bool is_param, Material *ma) { const char *axis_name = NULL; char anim_id[200]; bool has_tangents = false; bool quatRotation = false; if (!strcmp(transformName, "rotation_quaternion") ) { fprintf(stderr, "quaternion rotation curves are not supported. rotation curve will not be exported\n"); quatRotation = true; return; } //axis names for colors else if (!strcmp(transformName, "color") || !strcmp(transformName, "specular_color") || !strcmp(transformName, "diffuse_color") || (!strcmp(transformName, "alpha"))) { const char *axis_names[] = {"R", "G", "B"}; if (fcu->array_index < 3) axis_name = axis_names[fcu->array_index]; } //axis names for transforms else if ((!strcmp(transformName, "location") || !strcmp(transformName, "scale")) || (!strcmp(transformName, "rotation_euler")) || (!strcmp(transformName, "rotation_quaternion"))) { const char *axis_names[] = {"X", "Y", "Z"}; if (fcu->array_index < 3) axis_name = axis_names[fcu->array_index]; } else { /* no axis name. single parameter */ axis_name = ""; } std::string ob_name = std::string("null"); //Create anim Id if (ob->type == OB_ARMATURE) { ob_name = getObjectBoneName(ob, fcu); BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s.%s", (char *)translate_id(ob_name).c_str(), transformName, axis_name); } else { if (ma) ob_name = id_name(ob) + "_material"; else ob_name = id_name(ob); BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(), fcu->rna_path, axis_name); } openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING); // create input source std::string input_id = create_source_from_fcurve(COLLADASW::InputSemantic::INPUT, fcu, anim_id, axis_name); // create output source std::string output_id; //quat rotations are skipped for now, because of complications with determining axis. if (quatRotation) { float *eul = get_eul_source_for_quat(ob); float *eul_axis = (float *)MEM_callocN(sizeof(float) * fcu->totvert, "quat output source values"); for (int i = 0; i < fcu->totvert; i++) { eul_axis[i] = eul[i * 3 + fcu->array_index]; } output_id = create_source_from_array(COLLADASW::InputSemantic::OUTPUT, eul_axis, fcu->totvert, quatRotation, anim_id, axis_name); MEM_freeN(eul); MEM_freeN(eul_axis); } else { output_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUTPUT, fcu, anim_id, axis_name); } // create interpolations source std::string interpolation_id = create_interpolation_source(fcu, anim_id, axis_name, &has_tangents); // handle tangents (if required) std::string intangent_id; std::string outtangent_id; if (has_tangents) { // create in_tangent source intangent_id = create_source_from_fcurve(COLLADASW::InputSemantic::IN_TANGENT, fcu, anim_id, axis_name); // create out_tangent source outtangent_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUT_TANGENT, fcu, anim_id, axis_name); } std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX; COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id); std::string empty; sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id)); sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id)); // this input is required sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id)); if (has_tangents) { sampler.addInput(COLLADASW::InputSemantic::IN_TANGENT, COLLADABU::URI(empty, intangent_id)); sampler.addInput(COLLADASW::InputSemantic::OUT_TANGENT, COLLADABU::URI(empty, outtangent_id)); } addSampler(sampler); std::string target; if (!is_param) target = translate_id(ob_name) + "/" + get_transform_sid(fcu->rna_path, -1, axis_name, true); else { if (ob->type == OB_LAMP) target = get_light_id(ob) + "/" + get_light_param_sid(fcu->rna_path, -1, axis_name, true); if (ob->type == OB_CAMERA) target = get_camera_id(ob) + "/" + get_camera_param_sid(fcu->rna_path, -1, axis_name, true); if (ma) target = translate_id(id_name(ma)) + "-effect" + "/common/" /*profile common is only supported */ + get_transform_sid(fcu->rna_path, -1, axis_name, true); } addChannel(COLLADABU::URI(empty, sampler_id), target); closeAnimation(); }
void EffectsExporter::operator()(Material *ma, Object *ob) { // create a list of indices to textures of type TEX_IMAGE std::vector<int> tex_indices; if (this->export_settings->include_material_textures) createTextureIndices(ma, tex_indices); openEffect(translate_id(id_name(ma)) + "-effect"); COLLADASW::EffectProfile ep(mSW); ep.setProfileType(COLLADASW::EffectProfile::COMMON); ep.openProfile(); // set shader type - one of three blinn, phong or lambert if (ma->spec > 0.0f) { if (ma->spec_shader == MA_SPEC_BLINN) { writeBlinn(ep, ma); } else { // \todo figure out handling of all spec+diff shader combos blender has, for now write phong // for now set phong in case spec shader is not blinn writePhong(ep, ma); } } else { if (ma->diff_shader == MA_DIFF_LAMBERT) { writeLambert(ep, ma); } else { // \todo figure out handling of all spec+diff shader combos blender has, for now write phong writePhong(ep, ma); } } // index of refraction if (ma->mode & MA_RAYTRANSP) { ep.setIndexOfRefraction(ma->ang, false, "index_of_refraction"); } else { ep.setIndexOfRefraction(1.0f, false, "index_of_refraction"); } COLLADASW::ColorOrTexture cot; // transparency if (ma->mode & MA_TRANSP) { // Tod: because we are in A_ONE mode transparency is calculated like this: ep.setTransparency(ma->alpha, false, "transparency"); // cot = getcol(1.0f, 1.0f, 1.0f, 1.0f); // ep.setTransparent(cot); } // emission cot = getcol(ma->emit, ma->emit, ma->emit, 1.0f); ep.setEmission(cot, false, "emission"); // diffuse multiplied by diffuse intensity cot = getcol(ma->r * ma->ref, ma->g * ma->ref, ma->b * ma->ref, 1.0f); ep.setDiffuse(cot, false, "diffuse"); // ambient /* ma->ambX is calculated only on render, so lets do it here manually and not rely on ma->ambX. */ if (this->scene->world) cot = getcol(this->scene->world->ambr * ma->amb, this->scene->world->ambg * ma->amb, this->scene->world->ambb * ma->amb, 1.0f); else cot = getcol(ma->amb, ma->amb, ma->amb, 1.0f); ep.setAmbient(cot, false, "ambient"); // reflective, reflectivity if (ma->mode & MA_RAYMIRROR) { cot = getcol(ma->mirr, ma->mirg, ma->mirb, 1.0f); ep.setReflective(cot); ep.setReflectivity(ma->ray_mirror); } // else { // cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f); // ep.setReflective(cot); // ep.setReflectivity(ma->spec); // } // specular if (ep.getShaderType() != COLLADASW::EffectProfile::LAMBERT) { cot = getcol(ma->specr * ma->spec, ma->specg * ma->spec, ma->specb * ma->spec, 1.0f); ep.setSpecular(cot, false, "specular"); } // XXX make this more readable if possible // create <sampler> and <surface> for each image COLLADASW::Sampler samplers[MAX_MTEX]; //COLLADASW::Surface surfaces[MAX_MTEX]; //void *samp_surf[MAX_MTEX][2]; void *samp_surf[MAX_MTEX][1]; // image to index to samp_surf map // samp_surf[index] stores 2 pointers, sampler and surface std::map<std::string, int> im_samp_map; unsigned int a, b; for (a = 0, b = 0; a < tex_indices.size(); a++) { MTex *t = ma->mtex[tex_indices[a]]; Image *ima = t->tex->ima; // Image not set for texture if (!ima) continue; std::string key(id_name(ima)); key = translate_id(key); // create only one <sampler>/<surface> pair for each unique image if (im_samp_map.find(key) == im_samp_map.end()) { // //<newparam> <surface> <init_from> // COLLADASW::Surface surface(COLLADASW::Surface::SURFACE_TYPE_2D, // key + COLLADASW::Surface::SURFACE_SID_SUFFIX); // COLLADASW::SurfaceInitOption sio(COLLADASW::SurfaceInitOption::INIT_FROM); // sio.setImageReference(key); // surface.setInitOption(sio); // COLLADASW::NewParamSurface surface(mSW); // surface->setParamType(COLLADASW::CSW_SURFACE_TYPE_2D); //<newparam> <sampler> <source> COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D, key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); sampler.setImageId(key); // copy values to arrays since they will live longer samplers[a] = sampler; //surfaces[a] = surface; // store pointers so they can be used later when we create <texture>s samp_surf[b][0] = &samplers[a]; //samp_surf[b][1] = &surfaces[a]; im_samp_map[key] = b; b++; } } std::set<Image *> uv_textures; if (ob->type == OB_MESH && ob->totcol && this->export_settings->include_uv_textures) { bool active_uv_only = this->export_settings->active_uv_only; Mesh *me = (Mesh *) ob->data; int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY); BKE_mesh_tessface_ensure(me); for (int i = 0; i < me->pdata.totlayer; i++) { if (!active_uv_only || active_uv_layer == i) { if (me->pdata.layers[i].type == CD_MTEXPOLY) { MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; MFace *mface = me->mface; for (int j = 0; j < me->totpoly; j++, mface++, txface++) { Material *mat = give_current_material(ob, mface->mat_nr + 1); if (mat != ma) continue; Image *ima = txface->tpage; if (ima == NULL) continue; bool not_in_list = uv_textures.find(ima)==uv_textures.end(); if (not_in_list) { std::string name = id_name(ima); std::string key(name); key = translate_id(key); // create only one <sampler>/<surface> pair for each unique image if (im_samp_map.find(key) == im_samp_map.end()) { //<newparam> <sampler> <source> COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D, key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); sampler.setImageId(key); samplers[a] = sampler; samp_surf[b][0] = &samplers[a]; im_samp_map[key] = b; b++; a++; uv_textures.insert(ima); } } } } } } } // used as fallback when MTex->uvname is "" (this is pretty common) // it is indeed the correct value to use in that case std::string active_uv(getActiveUVLayerName(ob)); // write textures // XXX very slow for (a = 0; a < tex_indices.size(); a++) { MTex *t = ma->mtex[tex_indices[a]]; Image *ima = t->tex->ima; std::string key(id_name(ima)); key = translate_id(key); int i = im_samp_map[key]; std::string uvname = strlen(t->uvname) ? t->uvname : active_uv; COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0]; writeTextures(ep, key, sampler, t, ima, uvname); } std::set<Image *>::iterator uv_t_iter; for (uv_t_iter = uv_textures.begin(); uv_t_iter != uv_textures.end(); uv_t_iter++ ) { Image *ima = *uv_t_iter; std::string key(id_name(ima)); key = translate_id(key); int i = im_samp_map[key]; COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0]; ep.setDiffuse(createTexture(ima, active_uv, sampler), false, "diffuse"); } // performs the actual writing ep.addProfileElements(); bool twoSided = false; if (ob->type == OB_MESH && ob->data) { Mesh *me = (Mesh *)ob->data; if (me->flag & ME_TWOSIDED) twoSided = true; } if (twoSided) ep.addExtraTechniqueParameter("GOOGLEEARTH", "double_sided", 1); ep.addExtraTechniques(mSW); ep.closeProfile(); if (twoSided) mSW->appendTextBlock("<extra><technique profile=\"MAX3D\"><double_sided>1</double_sided></technique></extra>"); closeEffect(); }
std::string ControllerExporter::get_controller_id(Key *key, Object *ob) { return translate_id(id_name(ob)) + MORPH_CONTROLLER_ID_SUFFIX; }