//creates <source> for texcoords void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) { #if 0 int totfaces = dm->getNumFaces(dm); MFace *mfaces = dm->getFaceArray(dm); #endif int totfaces = me->totface; MFace *mfaces = me->mface; int totuv = 0; int i; // count totuv for (i = 0; i < totfaces; i++) { MFace *f = &mfaces[i]; if (f->v4 == 0) { totuv+=3; } else { totuv+=4; } } int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); // write <source> for each layer // each <source> will get id like meshName + "map-channel-1" for (int a = 0; a < num_layers; a++) { MTFace *tface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a); // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, a); COLLADASW::FloatSourceF source(mSW); std::string layer_id = makeTexcoordSourceId(geom_id, a); source.setId(layer_id); source.setArrayId(layer_id + ARRAY_ID_SUFFIX); source.setAccessorCount(totuv); source.setAccessorStride(2); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); param.push_back("S"); param.push_back("T"); source.prepareToAppendValues(); for (i = 0; i < totfaces; i++) { MFace *f = &mfaces[i]; for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { source.appendValues(tface[i].uv[j][0], tface[i].uv[j][1]); } } source.finish(); } }
//creates <source> for texcoords void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) { int totpoly = me->totpoly; int totuv = me->totloop; MPoly *mpolys = me->mpoly; int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); // write <source> for each layer // each <source> will get id like meshName + "map-channel-1" int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); for (int a = 0; a < num_layers; a++) { if (!this->export_settings->active_uv_only || a == active_uv_index) { MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a); COLLADASW::FloatSourceF source(mSW); std::string layer_id = makeTexcoordSourceId(geom_id, a, this->export_settings->active_uv_only); source.setId(layer_id); source.setArrayId(layer_id + ARRAY_ID_SUFFIX); source.setAccessorCount(totuv); source.setAccessorStride(2); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); param.push_back("S"); param.push_back("T"); source.prepareToAppendValues(); for (int index = 0; index < totpoly; index++) { MPoly *mpoly = mpolys+index; MLoopUV *mloop = mloops+mpoly->loopstart; for (int j = 0; j < mpoly->totloop; j++) { source.appendValues(mloop[j].uv[0], mloop[j].uv[1]); } } source.finish(); } } }
// powerful because it handles both cases when there is material and when there's not void GeometryExporter::createPolylist(short material_index, bool has_uvs, bool has_color, Object *ob, std::string& geom_id, std::vector<Face>& norind) { Mesh *me = (Mesh*)ob->data; MFace *mfaces = me->mface; int totfaces = me->totface; // <vcount> int i; int faces_in_polylist = 0; std::vector<unsigned long> vcount_list; // count faces with this material for (i = 0; i < totfaces; i++) { MFace *f = &mfaces[i]; if (f->mat_nr == material_index) { faces_in_polylist++; if (f->v4 == 0) { vcount_list.push_back(3); } else { vcount_list.push_back(4); } } } // no faces using this material if (faces_in_polylist == 0) { fprintf(stderr, "%s: no faces use material %d\n", id_name(ob).c_str(), material_index); return; } Material *ma = ob->totcol ? give_current_material(ob, material_index + 1) : NULL; COLLADASW::Polylist polylist(mSW); // sets count attribute in <polylist> polylist.setCount(faces_in_polylist); // sets material name if (ma) { std::ostringstream ostr; ostr << translate_id(id_name(ma)) << material_index+1; polylist.setMaterial(ostr.str()); } COLLADASW::InputList &til = polylist.getInputList(); // creates <input> in <polylist> for vertices COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0); // creates <input> in <polylist> for normals COLLADASW::Input input2(COLLADASW::InputSemantic::NORMAL, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL), 1); til.push_back(input1); til.push_back(input2); // if mesh has uv coords writes <input> for TEXCOORD int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); for (i = 0; i < num_layers; i++) { // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i); COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD, makeUrl(makeTexcoordSourceId(geom_id, i)), 2, // offset always 2, this is only until we have optimized UV sets i // set number equals UV map index ); til.push_back(input3); } if (has_color) { COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::COLOR), has_uvs ? 3 : 2); til.push_back(input4); } // sets <vcount> polylist.setVCountList(vcount_list); // performs the actual writing polylist.prepareToAppendValues(); // <p> int texindex = 0; for (i = 0; i < totfaces; i++) { MFace *f = &mfaces[i]; if (f->mat_nr == material_index) { unsigned int *v = &f->v1; unsigned int *n = &norind[i].v1; for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { polylist.appendValues(v[j]); polylist.appendValues(n[j]); if (has_uvs) polylist.appendValues(texindex + j); if (has_color) polylist.appendValues(texindex + j); } } texindex += 3; if (f->v4 != 0) texindex++; } polylist.finish(); }
// powerful because it handles both cases when there is material and when there's not void GeometryExporter::createPolylist(short material_index, bool has_uvs, bool has_color, Object *ob, Mesh *me, std::string& geom_id, std::vector<BCPolygonNormalsIndices>& norind) { MPoly *mpolys = me->mpoly; MLoop *mloops = me->mloop; int totpolys = me->totpoly; // <vcount> int i; int faces_in_polylist = 0; std::vector<unsigned long> vcount_list; // count faces with this material for (i = 0; i < totpolys; i++) { MPoly *p = &mpolys[i]; if (p->mat_nr == material_index) { faces_in_polylist++; vcount_list.push_back(p->totloop); } } // no faces using this material if (faces_in_polylist == 0) { fprintf(stderr, "%s: material with index %d is not used.\n", id_name(ob).c_str(), material_index); return; } Material *ma = ob->totcol ? give_current_material(ob, material_index + 1) : NULL; COLLADASW::Polylist polylist(mSW); // sets count attribute in <polylist> polylist.setCount(faces_in_polylist); // sets material name if (ma) { std::string material_id = get_material_id(ma); std::ostringstream ostr; ostr << translate_id(material_id); polylist.setMaterial(ostr.str()); } COLLADASW::InputList &til = polylist.getInputList(); // creates <input> in <polylist> for vertices COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0); // creates <input> in <polylist> for normals COLLADASW::Input input2(COLLADASW::InputSemantic::NORMAL, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL), 1); til.push_back(input1); til.push_back(input2); // if mesh has uv coords writes <input> for TEXCOORD int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE)-1; for (i = 0; i < num_layers; i++) { if (!this->export_settings->active_uv_only || i == active_uv_index) { // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i); COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD, makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings->active_uv_only)), 2, // this is only until we have optimized UV sets (this->export_settings->active_uv_only) ? 0 : i // only_active_uv exported -> we have only one set ); til.push_back(input3); } } int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); if (totlayer_mcol > 0) { int map_index = 0; for (int a = 0; a < totlayer_mcol; a++) { char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a); COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR, makeUrl(makeVertexColorSourceId(geom_id, layer_name)), (has_uvs) ? 3 : 2, // all color layers have same index order map_index // set number equals color map index ); til.push_back(input4); map_index++; } } // sets <vcount> polylist.setVCountList(vcount_list); // performs the actual writing polylist.prepareToAppendValues(); // <p> int texindex = 0; for (i = 0; i < totpolys; i++) { MPoly *p = &mpolys[i]; int loop_count = p->totloop; if (p->mat_nr == material_index) { MLoop *l = &mloops[p->loopstart]; BCPolygonNormalsIndices normal_indices = norind[i]; for (int j = 0; j < loop_count; j++) { polylist.appendValues(l[j].v); polylist.appendValues(normal_indices[j]); if (has_uvs) polylist.appendValues(texindex + j); if (has_color) polylist.appendValues(texindex + j); } } texindex += loop_count; } polylist.finish(); }