static Lib3dsBool named_object_read(Lib3dsFile *file, FILE *f) { Lib3dsChunk c; char name[64]; Lib3dsWord chunk; if (!lib3ds_chunk_read_start(&c, LIB3DS_NAMED_OBJECT, f)) { return(LIB3DS_FALSE); } if (!lib3ds_string_read(name, 64, f)) { return(LIB3DS_FALSE); } lib3ds_chunk_dump_info(" NAME=%s", name); lib3ds_chunk_read_tell(&c, f); while ((chunk=lib3ds_chunk_read_next(&c, f))!=0) { switch (chunk) { case LIB3DS_N_TRI_OBJECT: { Lib3dsMesh *mesh; mesh=lib3ds_mesh_new(name); if (!mesh) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_mesh_read(mesh, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_mesh(file, mesh); } break; case LIB3DS_N_CAMERA: { Lib3dsCamera *camera; camera=lib3ds_camera_new(name); if (!camera) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_camera_read(camera, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_camera(file, camera); } break; case LIB3DS_N_DIRECT_LIGHT: { Lib3dsLight *light; light=lib3ds_light_new(name); if (!light) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_light_read(light, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_light(file, light); } break; default: lib3ds_chunk_unknown(chunk); } } lib3ds_chunk_read_end(&c, f); return(LIB3DS_TRUE); }
Lib3dsMesh* GLC_WorldTo3ds::create3dsMeshFromGLC_Mesh(GLC_Mesh* pMesh, const QString& meshName) { // Create empty 3ds mesh with the given name Lib3dsMesh* p3dsMesh= lib3ds_mesh_new(meshName.toLocal8Bit().data()); const int stride= 3; GLfloatVector vertice= pMesh->positionVector(); const uint pointsCount= vertice.count() / stride; // Add points to the 3DS mesh lib3ds_mesh_new_point_list(p3dsMesh, pointsCount); for (uint i= 0; i < pointsCount; ++i) { Lib3dsPoint point; point.pos[0]= vertice[i * 3]; point.pos[1]= vertice[i * 3 + 1]; point.pos[2]= vertice[i * 3 + 2]; p3dsMesh->pointL[i]= point; } // Add texel to the 3DS mesh GLfloatVector texelVector= pMesh->texelVector(); if(!texelVector.isEmpty()) { lib3ds_mesh_new_texel_list(p3dsMesh, pointsCount); for (uint i= 0; i < pointsCount; ++i) { p3dsMesh->texelL[i][0]= texelVector[i * 2]; p3dsMesh->texelL[i][1]= texelVector[i * 2 + 1]; } } // Add faces to the 3ds mesh const uint totalFaceCount= pMesh->faceCount(0); lib3ds_mesh_new_face_list(p3dsMesh, totalFaceCount); QSet<GLC_Material*> materialSet= pMesh->materialSet(); QSet<GLC_Material*>::iterator iMat= materialSet.begin(); uint currentFaceIndex= 0; while(iMat != materialSet.end()) { GLC_Material* pCurrentGLCMat= *iMat; Lib3dsMaterial* pMaterial= get3dsMaterialFromGLC_Material(pCurrentGLCMat); IndexList currentTriangleIndex= pMesh->getEquivalentTrianglesStripsFansIndex(0, pCurrentGLCMat->id()); const int faceCount= currentTriangleIndex.count() / 3; for (int i= 0; i < faceCount; ++i) { Lib3dsFace face; strcpy(face.material, pMaterial->name); face.points[0]= currentTriangleIndex.at(i * 3); face.points[1]= currentTriangleIndex.at(i * 3 + 1); face.points[2]= currentTriangleIndex.at(i * 3 + 2); p3dsMesh->faceL[currentFaceIndex++]= face; Q_ASSERT(currentFaceIndex <= totalFaceCount); } ++iMat; } return p3dsMesh; }
static void dump_to_3ds(Lib3dsFile *f, FILE *fp) { Lib3dsMesh *m = lib3ds_mesh_new("Warzone Mesh"); Lib3dsMaterial *material = lib3ds_material_new("Warzone texture"); Lib3dsTextureMap *texture = &material->texture1_map; int i, num, x, y, levels; char s[200]; num = fscanf(fp, "PIE %d\n", &i); if (num != 1) { fprintf(stderr, "Bad PIE file %s\n", input); exit(1); } fprintf(stdout, "PIE version %d\n", i); num = fscanf(fp, "TYPE %d\n", &i); // ignore if (num != 1) { fprintf(stderr, "Bad TYPE directive in %s\n", input); exit(1); } num = fscanf(fp, "TEXTURE %d %s %d %d\n", &i, s, &x, &y); if (num != 4) { fprintf(stderr, "Bad TEXTURE directive in %s\n", input); exit(1); } strcpy(texture->name, s); num = fscanf(fp, "LEVELS %d\n", &levels); if (num != 1) { fprintf(stderr, "Bad LEVELS directive in %s\n", input); exit(1); } f->frames = levels; f->meshes = m; f->materials = material; for (i = 0; i < levels; i++) { int j, points, faces, faces3DS, faceCount, points3DS, pointCount; WZ_FACE *faceList; WZ_POSITION *posList; num = fscanf(fp, "LEVEL %d\n", &x); if (num != 1 || (i + 1) != x) { fprintf(stderr, "Bad LEVEL directive in %s, was %d should be %d\n", input, x, i + 1); exit(1); } num = fscanf(fp, "POINTS %d\n", &points); if (num != 1) { fprintf(stderr, "Bad POINTS directive in %s frame %d\n", input, i); exit(1); } posList = malloc(sizeof(WZ_POSITION) * points); for (j = 0; j < points; j++) { if (swapYZ) { num = fscanf(fp, "%d %d %d\n", &posList[j].x, &posList[j].z, &posList[j].y); } else { num = fscanf(fp, "%d %d %d\n", &posList[j].x, &posList[j].y, &posList[j].z); } if (num != 3) { fprintf(stderr, "Bad POINTS entry frame %d, number %d\n", i, j); exit(1); } } num = fscanf(fp, "POLYGONS %d", &faces); if (num != 1) { fprintf(stderr, "Bad POLYGONS directive in %s frame %d\n", input, i); exit(1); } faces3DS = faces; // for starters faceList = malloc(sizeof(WZ_FACE) * faces); points3DS = 0; for (j = 0; j < faces; ++j) { int k; unsigned int flags; num = fscanf(fp, "\n%x", &flags); if (num != 1) { fprintf(stderr, "Bad POLYGONS texture flag entry frame %d, number %d\n", i, j); exit(1); } if (!(flags & iV_IMD_TEX)) { fprintf(stderr, "Bad texture flag entry frame %d, number %d - no texture flag!\n", i, j); exit(1); } num = fscanf(fp, "%d", &faceList[j].vertices); if (num != 1) { fprintf(stderr, "Bad POLYGONS vertices entry frame %d, number %d\n", i, j); exit(1); } assert(faceList[j].vertices <= MAX_POLYGON_SIZE); // larger polygons not supported assert(faceList[j].vertices >= 3); // points and lines not supported if (faceList[j].vertices > 3) { // since they are triangle fans already, we get to do easy tessellation faces3DS += (faceList[j].vertices - 3); } points3DS += faceList[j].vertices; // Read in vertex indices and texture coordinates for (k = 0; k < faceList[j].vertices; k++) { num = fscanf(fp, "%d", &faceList[j].index[k]); if (num != 1) { fprintf(stderr, "Bad vertex position entry frame %d, number %d\n", i, j); exit(1); } } if (flags & iV_IMD_TEXANIM) { // read in and discard animation values for now int frames, rate, width, height; num = fscanf(fp, "%d %d %d %d", &frames, &rate, &width, &height); if (num != 4) { fprintf(stderr, "Bad texture animation entry frame %d, number %d\n", i, j); exit(1); } } for (k = 0; k < faceList[j].vertices; k++) { num = fscanf(fp, "%d %d", &faceList[j].texCoord[k][0], &faceList[j].texCoord[k][1]); if (num != 2) { fprintf(stderr, "Bad texture coordinate entry frame %d, number %d\n", i, j); exit(1); } } } // Calculate position list. Since positions hold texture coordinates in 3DS, unlike in Warzone, // we need to use some black magic to transfer them over here. lib3ds_mesh_new_point_list(m, points3DS); lib3ds_mesh_new_texel_list(m, points3DS); pointCount = 0; for (j = 0; j < faces; j++) { int k; for (k = 0; k < faceList[j].vertices; k++) { Lib3dsVector pos; pos[0] = posList[faceList[j].index[k]].x; pos[1] = posList[faceList[j].index[k]].y; pos[2] = posList[faceList[j].index[k]].z; lib3ds_vector_copy(m->pointL[pointCount].pos, pos); faceList[j].index[k] = pointCount; // use new position list if (invertUV) { m->texelL[pointCount][0] = ((float)faceList[j].texCoord[k][0] / 256.0f); m->texelL[pointCount][1] = 1.0f - ((float)faceList[j].texCoord[k][1] / 256.0f); } else { m->texelL[pointCount][0] = ((float)faceList[j].texCoord[k][0] / 256.0f); m->texelL[pointCount][1] = ((float)faceList[j].texCoord[k][1] / 256.0f); } pointCount++; } } lib3ds_mesh_new_face_list(m, faces3DS); faceCount = 0; // TODO reverse winding afterwards for (j = 0; j < faces; j++) { int k, key, previous; key = m->faceL[faceCount].points[0] = faceList[j].index[0]; m->faceL[faceCount].points[1] = faceList[j].index[1]; previous = m->faceL[faceCount].points[2] = faceList[j].index[2]; faceCount++; // Generate triangles from the Warzone triangle fans (PIEs, get it?) for (k = 3; k < faceList[j].vertices; k++) { m->faceL[faceCount].points[0] = key; m->faceL[faceCount].points[1] = previous; previous = m->faceL[faceCount].points[0] = faceList[j].index[k]; } // Since texture coordinates are properties of positions, not indices, // we do not need a similar expansion of these } free(faceList); free(posList); } if (!lib3ds_file_save(f, output)) { fprintf(stderr, "Cannot open \"%s\" for writing: %s", output, strerror(errno)); exit(1); } }
static Lib3dsBool named_object_read(Lib3dsFile *file, Lib3dsIo *io) { Lib3dsChunk c; char name[64]; Lib3dsWord chunk; Lib3dsMesh *mesh = NULL; Lib3dsCamera *camera = NULL; Lib3dsLight *light = NULL; Lib3dsDword object_flags; if (!lib3ds_chunk_read_start(&c, LIB3DS_NAMED_OBJECT, io)) { return(LIB3DS_FALSE); } if (!lib3ds_io_read_string(io, name, 64)) { return(LIB3DS_FALSE); } lib3ds_chunk_dump_info(" NAME=%s", name); lib3ds_chunk_read_tell(&c, io); object_flags = 0; while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { switch (chunk) { case LIB3DS_N_TRI_OBJECT: { mesh=lib3ds_mesh_new(name); if (!mesh) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, io); if (!lib3ds_mesh_read(mesh, io)) { return(LIB3DS_FALSE); } lib3ds_file_insert_mesh(file, mesh); } break; case LIB3DS_N_CAMERA: { camera=lib3ds_camera_new(name); if (!camera) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, io); if (!lib3ds_camera_read(camera, io)) { return(LIB3DS_FALSE); } lib3ds_file_insert_camera(file, camera); } break; case LIB3DS_N_DIRECT_LIGHT: { light=lib3ds_light_new(name); if (!light) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, io); if (!lib3ds_light_read(light, io)) { return(LIB3DS_FALSE); } lib3ds_file_insert_light(file, light); } break; case LIB3DS_OBJ_HIDDEN: object_flags |= LIB3DS_OBJECT_HIDDEN; break; case LIB3DS_OBJ_DOESNT_CAST: object_flags |= LIB3DS_OBJECT_DOESNT_CAST; break; case LIB3DS_OBJ_VIS_LOFTER: object_flags |= LIB3DS_OBJECT_VIS_LOFTER; break; case LIB3DS_OBJ_MATTE: object_flags |= LIB3DS_OBJECT_MATTE; break; case LIB3DS_OBJ_DONT_RCVSHADOW: object_flags |= LIB3DS_OBJECT_DONT_RCVSHADOW; break; case LIB3DS_OBJ_FAST: object_flags |= LIB3DS_OBJECT_FAST; break; case LIB3DS_OBJ_FROZEN: object_flags |= LIB3DS_OBJECT_FROZEN; break; default: lib3ds_chunk_unknown(chunk); } } if (mesh) mesh->object_flags = object_flags; if (camera) camera->object_flags = object_flags; if (light) light->object_flags = object_flags; lib3ds_chunk_read_end(&c, io); return(LIB3DS_TRUE); }
static void named_object_read(Lib3dsFile *file, Lib3dsIo *io) { Lib3dsChunk c; char name[64]; uint16_t chunk; Lib3dsMesh *mesh = NULL; Lib3dsCamera *camera = NULL; Lib3dsLight *light = NULL; uint32_t object_flags; lib3ds_chunk_read_start(&c, CHK_NAMED_OBJECT, io); lib3ds_io_read_string(io, name, 64); lib3ds_io_log(io, LIB3DS_LOG_INFO, " NAME=%s", name); lib3ds_chunk_read_tell(&c, io); object_flags = 0; while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { switch (chunk) { case CHK_N_TRI_OBJECT: { mesh = lib3ds_mesh_new(name); lib3ds_file_insert_mesh(file, mesh, -1); lib3ds_chunk_read_reset(&c, io); lib3ds_mesh_read(file, mesh, io); break; } case CHK_N_CAMERA: { camera = lib3ds_camera_new(name); lib3ds_file_insert_camera(file, camera, -1); lib3ds_chunk_read_reset(&c, io); lib3ds_camera_read(camera, io); break; } case CHK_N_DIRECT_LIGHT: { light = lib3ds_light_new(name); lib3ds_file_insert_light(file, light, -1); lib3ds_chunk_read_reset(&c, io); lib3ds_light_read(light, io); break; } case CHK_OBJ_HIDDEN: object_flags |= LIB3DS_OBJECT_HIDDEN; break; case CHK_OBJ_DOESNT_CAST: object_flags |= LIB3DS_OBJECT_DOESNT_CAST; break; case CHK_OBJ_VIS_LOFTER: object_flags |= LIB3DS_OBJECT_VIS_LOFTER; break; case CHK_OBJ_MATTE: object_flags |= LIB3DS_OBJECT_MATTE; break; case CHK_OBJ_DONT_RCVSHADOW: object_flags |= LIB3DS_OBJECT_DONT_RCVSHADOW; break; case CHK_OBJ_FAST: object_flags |= LIB3DS_OBJECT_FAST; break; case CHK_OBJ_FROZEN: object_flags |= LIB3DS_OBJECT_FROZEN; break; default: lib3ds_chunk_unknown(chunk, io); } } if (mesh) mesh->object_flags = object_flags; if (camera) camera->object_flags = object_flags; if (light) light->object_flags = object_flags; lib3ds_chunk_read_end(&c, io); }
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::buildFaces(osg::Geode & geo, const osg::Matrix & mat, ListTriangle & listTriangles, bool texcoords) { unsigned int nbTrianglesRemaining = listTriangles.size(); unsigned int nbVerticesRemaining = calcVertices(geo); // May set _succeded to false if (!succeeded()) return; std::string name( getUniqueName(geo.getName().empty() ? geo.className() : geo.getName(), true, "geo") ); if (!succeeded()) return; Lib3dsMesh *mesh = lib3ds_mesh_new( name.c_str() ); if (!mesh) { OSG_NOTIFY(osg::FATAL) << "Allocation error" << std::endl; _succeeded = false; return; } //copyOsgMatrixToLib3dsMatrix(mesh->matrix, mat); lib3ds_mesh_resize_faces (mesh, osg::minimum(nbTrianglesRemaining, MAX_FACES)); lib3ds_mesh_resize_vertices(mesh, osg::minimum(nbVerticesRemaining, MAX_VERTICES), texcoords ? 0 : 1, 0); // Not mandatory but will allocate once a big block // Test if the mesh will be split and needs sorting if (nbVerticesRemaining >= MAX_VERTICES || nbTrianglesRemaining >= MAX_FACES) { OSG_INFO << "Sorting elements..." << std::endl; WriterCompareTriangle cmp(geo, nbVerticesRemaining); std::sort(listTriangles.begin(), listTriangles.end(), cmp); } MapIndices index_vert; unsigned int numFace = 0; // Current face index for (ListTriangle::iterator it = listTriangles.begin(); it != listTriangles.end(); ++it) //Go through the triangle list to define meshs { // Test if the mesh will be full after adding a face if (index_vert.size()+3 >= MAX_VERTICES || numFace+1 >= MAX_FACES) { // Finnish mesh lib3ds_mesh_resize_faces (mesh, numFace); //lib3ds_mesh_resize_vertices() will be called in buildMesh() buildMesh(geo, mat, index_vert, texcoords, mesh); // May set _succeded to false if (!succeeded()) { lib3ds_mesh_free(mesh); return; } // "Reset" values and start over a new mesh index_vert.clear(); nbTrianglesRemaining -= numFace; numFace = 0; // We can't call a thing like "nbVerticesRemaining -= ...;" because points may be used multiple times. // [Sukender: An optimisation here would take too much time I think.] mesh = lib3ds_mesh_new( getUniqueName(geo.getName().empty() ? geo.className() : geo.getName(), true, "geo").c_str()); if (!mesh) { OSG_NOTIFY(osg::FATAL) << "Allocation error" << std::endl; _succeeded = false; return; } lib3ds_mesh_resize_faces (mesh, osg::minimum(nbTrianglesRemaining, MAX_FACES)); lib3ds_mesh_resize_vertices(mesh, osg::minimum(nbVerticesRemaining, MAX_VERTICES), texcoords ? 0 : 1, 0); // Not mandatory but will allocate once a big block } Lib3dsFace & face = mesh->faces[numFace++]; face.index[0] = getMeshIndexForGeometryIndex(index_vert, it->first.t1, it->second); face.index[1] = getMeshIndexForGeometryIndex(index_vert, it->first.t2, it->second); face.index[2] = getMeshIndexForGeometryIndex(index_vert, it->first.t3, it->second); face.material = it->first.material; } buildMesh(geo, mat, index_vert, texcoords, mesh); // May set _succeded to false if (!succeeded()) { lib3ds_mesh_free(mesh); return; } }
void LD3dsExporter::doExport( LDLModel *pModel, Lib3dsNode *pParentNode, const TCFloat *matrix, int colorNumber, bool inPart, bool bfc, bool invert) { LDLFileLineArray *pFileLines = pModel->getFileLines(); if (pFileLines != NULL) { BFCState newBfcState = pModel->getBFCState(); int count = pModel->getActiveLineCount(); std::string meshName; Lib3dsMesh *pMesh = NULL; Lib3dsNode *pChildNode = NULL; // Lib3dsMeshInstanceNode *pInst; bool linesInvert = invert; bool isNew = false; if (TCVector::determinant(matrix) < 0.0f) { linesInvert = !linesInvert; } bfc = (bfc && newBfcState == BFCOnState) || newBfcState == BFCForcedOnState; meshName.resize(128); sprintf(&meshName[0], "m_%06d", ++m_meshCount); // meshName = getMeshName(pModel, pMesh); if (pMesh == NULL) { pMesh = lib3ds_mesh_new(meshName.c_str()); // memcpy(pMesh->matrix, matrix, sizeof(pMesh->matrix)); m_meshes[meshName] = pMesh; lib3ds_file_insert_mesh(m_file, pMesh, -1); isNew = true; } // pInst = lib3ds_node_new_mesh_instance(pMesh, // NULL/*(meshName + "n").c_str()*/, NULL, NULL, NULL); // pChildNode = (Lib3dsNode *)pInst; // memcpy(pChildNode->matrix, matrix, sizeof(float) * 16); // lib3ds_file_append_node(m_file, pChildNode, pParentNode); VertexVector vecVertices; FaceVector vecFaces; for (int i = 0; i < count; i++) { LDLFileLine *pFileLine = (*pFileLines)[i]; if (!pFileLine->isValid()) { continue; } switch (pFileLine->getLineType()) { case LDLLineTypeTriangle: case LDLLineTypeQuad: writeShapeLine(vecVertices, vecFaces, (LDLShapeLine *)pFileLine, matrix, colorNumber, bfc, linesInvert); break; case LDLLineTypeModel: { LDLModelLine *pModelLine = (LDLModelLine *)pFileLine; LDLModel *pOtherModel = pModelLine->getModel(true); if (pOtherModel != NULL) { TCFloat newMatrix[16]; int otherColorNumber = pModelLine->getColorNumber(); bool otherInPart = inPart; bool otherInvert = invert; if (pModelLine->getBFCInvert()) { otherInvert = !otherInvert; } if (otherColorNumber == 16) { otherColorNumber = colorNumber; } TCVector::multMatrix(matrix, pModelLine->getMatrix(), newMatrix); if (!inPart && pOtherModel->isPart() && m_seams) { TCVector min, max; TCFloat seamMatrix[16]; TCFloat tempMatrix[16]; pOtherModel->getBoundingBox(min, max); TCVector::calcScaleMatrix(m_seamWidth, seamMatrix, min, max); TCVector::multMatrix(newMatrix, seamMatrix, tempMatrix); memcpy(newMatrix, tempMatrix, sizeof(newMatrix)); otherInPart = true; } doExport(pOtherModel, pChildNode, newMatrix, otherColorNumber, otherInPart, bfc, otherInvert); } } break; default: // Get rid of warning break; } } if (isNew && vecVertices.size() > 0) { lib3ds_mesh_resize_vertices(pMesh, (int)vecVertices.size(), 0, 0); memcpy(pMesh->vertices, &vecVertices[0], sizeof(vecVertices[0]) * vecVertices.size()); lib3ds_mesh_resize_faces(pMesh, (int)vecFaces.size()); memcpy(pMesh->faces, &vecFaces[0], sizeof(vecFaces[0]) * vecFaces.size()); } else { --m_meshCount; } } }