void WriterNodeVisitor::apply3DSMatrixNode(osg::Node &node, const osg::Matrix * m, const char * const prefix) { // Note: Creating a mesh instance with no transform and then copying the matrix doesn't work (matrix seems to be a temporary/computed value) Lib3dsMeshInstanceNode * parent = _cur3dsNode; Lib3dsMeshInstanceNode * node3ds = NULL; if (m) { osg::Vec3 osgScl, osgPos; osg::Quat osgRot, osgSo; m->decompose(osgPos, osgRot, osgScl, osgSo); float pos[3]; float scl[3]; float rot[4]; copyOsgVectorToLib3dsVector(pos, osgPos); copyOsgVectorToLib3dsVector(scl, osgScl); copyOsgQuatToLib3dsQuat(rot, osgRot); node3ds = lib3ds_node_new_mesh_instance(NULL, getUniqueName(node.getName().empty() ? node.className() : node.getName(), true, prefix).c_str(), pos, scl, rot); } else { node3ds = lib3ds_node_new_mesh_instance(NULL, getUniqueName(node.getName().empty() ? node.className() : node.getName(), true, prefix).c_str(), NULL, NULL, NULL); } lib3ds_file_append_node(_file3ds, reinterpret_cast<Lib3dsNode*>(node3ds), reinterpret_cast<Lib3dsNode*>(parent)); _cur3dsNode = node3ds; }
int main(int argc, char **argv) { Lib3dsFile *file = lib3ds_file_new(); file->frames = 360; { Lib3dsMaterial *mat = lib3ds_material_new("c_tex"); lib3ds_file_insert_material(file, mat, -1); strcpy(mat->texture1_map.name, "cube.tga"); mat->texture1_map.percent = 1.0; mat = lib3ds_material_new("c_red"); lib3ds_file_insert_material(file, mat, -1); mat->diffuse[0] = 1.0; mat->diffuse[1] = 0.0; mat->diffuse[2] = 0.0; mat = lib3ds_material_new("c_blue"); lib3ds_file_insert_material(file, mat, -1); mat->diffuse[0] = 0.0; mat->diffuse[1] = 0.0; mat->diffuse[2] = 1.0; } { int i, j; Lib3dsMesh *mesh = lib3ds_mesh_new("cube"); Lib3dsMeshInstanceNode *inst; lib3ds_file_insert_mesh(file, mesh, -1); lib3ds_mesh_resize_vertices(mesh, 8, 1, 0); for (i = 0; i < 8; ++i) { lib3ds_vector_copy(mesh->vertices[i], g_vertices[i]); mesh->texcos[i][0] = g_texcoords[i][0]; mesh->texcos[i][1] = g_texcoords[i][1]; } lib3ds_mesh_resize_faces(mesh, 12); for (i = 0; i < 12; ++i) { for (j = 0; j < 3; ++j) { mesh->faces[i].index[j] = g_indices[i][j]; } } for (i = 0; i < 8; ++i) { mesh->faces[i].material = 0; } for (i = 0; i < 2; ++i) { mesh->faces[8+i].material = 1; } for (i = 0; i < 2; ++i) { mesh->faces[10+i].material = 2; } inst = lib3ds_node_new_mesh_instance(mesh, "01", NULL, NULL, NULL); lib3ds_file_append_node(file, (Lib3dsNode*)inst, NULL); } { Lib3dsCamera *camera; Lib3dsCameraNode *n; Lib3dsTargetNode *t; int i; camera = lib3ds_camera_new("camera01"); lib3ds_file_insert_camera(file, camera, -1); lib3ds_vector_make(camera->position, 0.0, -100, 0.0); lib3ds_vector_make(camera->target, 0.0, 0.0, 0.0); n = lib3ds_node_new_camera(camera); t = lib3ds_node_new_camera_target(camera); lib3ds_file_append_node(file, (Lib3dsNode*)n, NULL); lib3ds_file_append_node(file, (Lib3dsNode*)t, NULL); lib3ds_track_resize(&n->pos_track, 37); for (i = 0; i <= 36; i++) { n->pos_track.keys[i].frame = 10 * i; lib3ds_vector_make(n->pos_track.keys[i].value, (float)(100.0 * cos(2 * M_PI * i / 36.0)), (float)(100.0 * sin(2 * M_PI * i / 36.0)), 50.0 ); } } if (!lib3ds_file_save(file, "cube.3ds")) { fprintf(stderr, "ERROR: Saving 3ds file failed!\n"); } lib3ds_file_free(file); }
// TODO: Build own exporter class void objectExporter::on_buttonBox_accepted() { QString fileName = QFileDialog::getSaveFileName(gloParent, "Save 3ds Object", ".", "3D Object (*.3ds)", 0, 0); QList<trackHandler*> trackList = gloParent->getTrackList(); trackHandler* curTrack = trackList[ui->trackBox->currentIndex()]; trackMesh* mesh = curTrack->mMesh; QVector<float> *vertices = new QVector<float>(); QVector<unsigned int> *indices = new QVector<unsigned int>(); QVector<unsigned int> *borders = new QVector<unsigned int>(); Lib3dsFile *file = lib3ds_file_new(); file->frames = 360; { Lib3dsMaterial* mat = lib3ds_material_new("coaster"); lib3ds_file_insert_material(file, mat, -1); mat->diffuse[0] = curTrack->trackColors[0].red()/255.f; mat->diffuse[1] = curTrack->trackColors[0].green()/255.f; mat->diffuse[2] = curTrack->trackColors[0].blue()/255.f; } { for(int section = 0; section < curTrack->trackData->lSections.size(); ++section) { vertices->clear(); indices->clear(); borders->clear(); mesh->build3ds(section, vertices, indices, borders); float* fvertices = new float[vertices->size()]; for(int i = 0; i < vertices->size()/3; ++i) { fvertices[3*i+0] = vertices->at(3*i+0); fvertices[3*i+1] = -vertices->at(3*i+2); fvertices[3*i+2] = vertices->at(3*i+1); //exportScreen->doFastExport(); } for(int subIndex = 0; subIndex < borders->size()-2; subIndex+= 2) { int fromVIndex = borders->at(subIndex)/3; int toVIndex = borders->at(subIndex+2)/3; int fromIIndex = borders->at(subIndex+1)/3; int toIIndex = borders->at(subIndex+3)/3; int i, j; QString name = QString::number(section).append(QString("_").append(QString::number(subIndex/2))); Lib3dsMesh *mesh = lib3ds_mesh_new(name.toLocal8Bit().data()); Lib3dsMeshInstanceNode *inst; lib3ds_file_insert_mesh(file, mesh, -1); lib3ds_mesh_resize_vertices(mesh, toVIndex-fromVIndex, 1, 0); for (i = 0; i < toVIndex-fromVIndex; ++i) { lib3ds_vector_copy(mesh->vertices[i], &fvertices[(i+fromVIndex)*3]); mesh->texcos[i][0] = 0.f; mesh->texcos[i][1] = 0.f; } lib3ds_mesh_resize_faces(mesh, toIIndex-fromIIndex); for (i = 0; i < toIIndex-fromIIndex; ++i) { for (j = 0; j < 3; ++j) { mesh->faces[i].index[j] = indices->at(3*(i+fromIIndex)+j)-fromVIndex; mesh->faces[i].material = 0; } } inst = lib3ds_node_new_mesh_instance(mesh, name.toLocal8Bit().data(), NULL, NULL, NULL); lib3ds_file_append_node(file, (Lib3dsNode*)inst, NULL); } delete[] fvertices; } } { Lib3dsCamera *camera; Lib3dsCameraNode *n; Lib3dsTargetNode *t; int i; camera = lib3ds_camera_new("camera01"); lib3ds_file_insert_camera(file, camera, -1); lib3ds_vector_make(camera->position, 0.0, -100, 0.0); lib3ds_vector_make(camera->target, 0.0, 0.0, 0.0); n = lib3ds_node_new_camera(camera); t = lib3ds_node_new_camera_target(camera); lib3ds_file_append_node(file, (Lib3dsNode*)n, NULL); lib3ds_file_append_node(file, (Lib3dsNode*)t, NULL); lib3ds_track_resize(&n->pos_track, 37); for (i = 0; i <= 36; i++) { n->pos_track.keys[i].frame = 10 * i; lib3ds_vector_make(n->pos_track.keys[i].value, (float)(100.0 * cos(2 * F_PI * i / 36.0)), (float)(100.0 * sin(2 * F_PI * i / 36.0)), 50.0 ); } } if (!lib3ds_file_save(file, fileName.toLocal8Bit().data())) { qDebug("ERROR: Saving 3ds file failed!\n"); } lib3ds_file_free(file); delete indices; delete vertices; }
void WriterNodeVisitor::buildMesh(osg::Geode & geo, const osg::Matrix & mat, MapIndices & index_vert, bool texcoords, Lib3dsMesh * mesh) { OSG_DEBUG << "Building Mesh" << std::endl; assert(mesh); // Write points assert(index_vert.size() <= MAX_VERTICES); lib3ds_mesh_resize_vertices(mesh, index_vert.size(), texcoords ? 1 : 0, 0); for(MapIndices::iterator it = index_vert.begin(); it != index_vert.end();++it) { osg::Geometry *g = geo.getDrawable( it->first.second )->asGeometry(); const osg::Array * basevecs = g->getVertexArray(); assert(basevecs); if (!basevecs || basevecs->getNumElements()==0) continue; if (basevecs->getType() == osg::Array::Vec3ArrayType) { const osg::Vec3Array & vecs= *static_cast<const osg::Vec3Array *>(basevecs); copyOsgVectorToLib3dsVector(mesh->vertices[it->second], vecs[it->first.first]*mat); } else if (basevecs->getType() == osg::Array::Vec3dArrayType) { // Handle double presision vertices by converting them to float with a warning OSG_NOTICE << "3DS format only supports single precision vertices. Converting double precision to single." << std::endl; const osg::Vec3dArray & vecs= *static_cast<const osg::Vec3dArray *>(basevecs); copyOsgVectorToLib3dsVector(mesh->vertices[it->second], vecs[it->first.first]*mat); } else { OSG_NOTIFY(osg::FATAL) << "Vertex array is not Vec3 or Vec3d. Not implemented" << std::endl; _succeeded = false; return; } } // Write texture coords (Texture 0 only) if (texcoords) { for(MapIndices::iterator it = index_vert.begin(); it != index_vert.end(); ++it) { osg::Geometry *g = geo.getDrawable( it->first.second )->asGeometry(); const osg::Array * texarray = g->getNumTexCoordArrays()>=1 ? g->getTexCoordArray(0) : NULL; if (!texarray || texarray->getNumElements()==0) continue; if (g->getTexCoordArray(0)->getType() != osg::Array::Vec2ArrayType) { OSG_NOTIFY(osg::FATAL) << "Texture coords array is not Vec2. Not implemented" << std::endl; _succeeded = false; return; } const osg::Vec2Array & vecs= *static_cast<const osg::Vec2Array *>(texarray); mesh->texcos[it->second][0] = vecs[it->first.first][0]; mesh->texcos[it->second][1] = vecs[it->first.first][1]; } } lib3ds_file_insert_mesh(_file3ds, mesh, _lastMeshIndex); ++_lastMeshIndex; Lib3dsMeshInstanceNode * node3ds = lib3ds_node_new_mesh_instance(mesh, mesh->name, NULL, NULL, NULL); lib3ds_file_append_node(_file3ds, reinterpret_cast<Lib3dsNode*>(node3ds), reinterpret_cast<Lib3dsNode*>(_cur3dsNode)); }