void lib3ds_track_write(Lib3dsTrack *track, Lib3dsIo *io) { int i; lib3ds_io_write_word(io, (uint16_t)track->flags); lib3ds_io_write_dword(io, 0); lib3ds_io_write_dword(io, 0); lib3ds_io_write_dword(io, track->nkeys); switch (track->type) { case LIB3DS_TRACK_BOOL: for (i = 0; i < track->nkeys; ++i) { lib3ds_io_write_intd(io, track->keys[i].frame); tcb_write(&track->keys[i], io); } break; case LIB3DS_TRACK_FLOAT: for (i = 0; i < track->nkeys; ++i) { lib3ds_io_write_intd(io, track->keys[i].frame); tcb_write(&track->keys[i], io); lib3ds_io_write_float(io, track->keys[i].value[0]); } break; case LIB3DS_TRACK_VECTOR: for (i = 0; i < track->nkeys; ++i) { lib3ds_io_write_intd(io, track->keys[i].frame); tcb_write(&track->keys[i], io); lib3ds_io_write_vector(io, track->keys[i].value); } break; case LIB3DS_TRACK_QUAT: for (i = 0; i < track->nkeys; ++i) { lib3ds_io_write_intd(io, track->keys[i].frame); tcb_write(&track->keys[i], io); lib3ds_io_write_float(io, track->keys[i].value[3]); lib3ds_io_write_vector(io, track->keys[i].value); } break; /*case LIB3DS_TRACK_MORPH: for (i = 0; i < track->nkeys; ++i) { lib3ds_io_write_intd(io, track->keys[i].frame); tcb_write(&track->keys[i].tcb, io); lib3ds_io_write_string(io, track->keys[i].data.m.name); } break;*/ } }
/*! * Write 3ds file data from a Lib3dsFile object to a file. * * \param file The Lib3dsFile object to be written. * \param io A Lib3dsIo object previously set up by the caller. * * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure. * * \ingroup file */ Lib3dsBool lib3ds_file_write(Lib3dsFile *file, Lib3dsIo *io) { Lib3dsChunk c; c.chunk=LIB3DS_M3DMAGIC; if (!lib3ds_chunk_write_start(&c,io)) { LIB3DS_ERROR_LOG; return(LIB3DS_FALSE); } { /*---- LIB3DS_M3D_VERSION ----*/ Lib3dsChunk c; c.chunk=LIB3DS_M3D_VERSION; c.size=10; lib3ds_chunk_write(&c,io); lib3ds_io_write_dword(io, file->mesh_version); } if (!mdata_write(file, io)) { return(LIB3DS_FALSE); } if (!kfdata_write(file, io)) { return(LIB3DS_FALSE); } if (!lib3ds_chunk_write_end(&c,io)) { return(LIB3DS_FALSE); } return(LIB3DS_TRUE); }
/*! * Write 3ds file data from a Lib3dsFile object to a file. * * \param file The Lib3dsFile object to be written. * \param io A Lib3dsIo object previously set up by the caller. * * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure. */ int lib3ds_file_write(Lib3dsFile *file, Lib3dsIo *io) { Lib3dsChunk c; Lib3dsIoImpl *impl; lib3ds_io_setup(io); impl = (Lib3dsIoImpl*)io->impl; if (setjmp(impl->jmpbuf) != 0) { lib3ds_io_cleanup(io); return FALSE; } c.chunk = CHK_M3DMAGIC; lib3ds_chunk_write_start(&c, io); { /*---- LIB3DS_M3D_VERSION ----*/ Lib3dsChunk c; c.chunk = CHK_M3D_VERSION; c.size = 10; lib3ds_chunk_write(&c, io); lib3ds_io_write_dword(io, file->mesh_version); } mdata_write(file, io); kfdata_write(file, io); lib3ds_chunk_write_end(&c, io); memset(impl->jmpbuf, 0, sizeof(impl->jmpbuf)); lib3ds_io_cleanup(io); return TRUE; }
/*! * Writes a 3d-Studio chunk header into a little endian file stream. * * \param c The chunk to be written. * \param io The file stream. * * \return True on success, False otherwise. */ void lib3ds_chunk_write(Lib3dsChunk *c, Lib3dsIo *io) { assert(c); lib3ds_io_write_word(io, c->chunk); lib3ds_io_write_dword(io, c->size); }
void lib3ds_chunk_write_start(Lib3dsChunk *c, Lib3dsIo *io) { assert(c); c->size = 0; c->cur = lib3ds_io_tell(io); lib3ds_io_write_word(io, c->chunk); lib3ds_io_write_dword(io, c->size); }
void lib3ds_chunk_write_end(Lib3dsChunk *c, Lib3dsIo *io) { assert(c); c->size = lib3ds_io_tell(io) - c->cur; lib3ds_io_seek(io, c->cur + 2, LIB3DS_SEEK_SET); lib3ds_io_write_dword(io, c->size); c->cur += c->size; lib3ds_io_seek(io, c->cur, LIB3DS_SEEK_SET); }
/*! * \ingroup tracks */ Lib3dsBool lib3ds_bool_track_write(Lib3dsBoolTrack *track, Lib3dsIo *io) { Lib3dsBoolKey *k; Lib3dsDword num=0; for (k=track->keyL; k; k=k->next) { ++num; } lib3ds_io_write_word(io, (Lib3dsWord)track->flags); lib3ds_io_write_dword(io, 0); lib3ds_io_write_dword(io, 0); lib3ds_io_write_dword(io, num); for (k=track->keyL; k; k=k->next) { if (!lib3ds_tcb_write(&k->tcb,io)) { return(LIB3DS_FALSE); } } return(LIB3DS_TRUE); }
/*! * \ingroup tracks */ Lib3dsBool lib3ds_quat_track_write(Lib3dsQuatTrack *track, Lib3dsIo *io) { Lib3dsQuatKey *k; Lib3dsDword num=0; for (k=track->keyL; k; k=k->next) { ++num; } lib3ds_io_write_word(io, (Lib3dsWord)track->flags); lib3ds_io_write_dword(io, 0); lib3ds_io_write_dword(io, 0); lib3ds_io_write_dword(io, num); for (k=track->keyL; k; k=k->next) { if (!lib3ds_tcb_write(&k->tcb,io)) { return(LIB3DS_FALSE); } lib3ds_io_write_float(io, k->angle); lib3ds_io_write_vector(io, k->axis); } return(LIB3DS_TRUE); }
/*! * \ingroup chunk */ Lib3dsBool lib3ds_chunk_write_start(Lib3dsChunk *c, Lib3dsIo *io) { ASSERT(c); c->size=0; c->cur=lib3ds_io_tell(io); if (!lib3ds_io_write_word(io, c->chunk)) { return(LIB3DS_FALSE); } if (!lib3ds_io_write_dword(io, c->size)) { return(LIB3DS_FALSE); } return(LIB3DS_TRUE); }
/*! * \ingroup chunk * * Writes a 3d-Studio chunk header into a little endian file stream. * * \param c The chunk to be written. * \param io The file stream. * * \return True on success, False otherwise. */ Lib3dsBool lib3ds_chunk_write(Lib3dsChunk *c, Lib3dsIo *io) { ASSERT(c); if (!lib3ds_io_write_word(io, c->chunk)) { LIB3DS_ERROR_LOG; return(LIB3DS_FALSE); } if (!lib3ds_io_write_dword(io, c->size)) { LIB3DS_ERROR_LOG; return(LIB3DS_FALSE); } return(LIB3DS_TRUE); }
/*! * \ingroup chunk */ Lib3dsBool lib3ds_chunk_write_end(Lib3dsChunk *c, Lib3dsIo *io) { ASSERT(c); c->size=lib3ds_io_tell(io) - c->cur; lib3ds_io_seek(io, c->cur+2, LIB3DS_SEEK_SET); if (!lib3ds_io_write_dword(io, c->size)) { LIB3DS_ERROR_LOG; return(LIB3DS_FALSE); } c->cur+=c->size; lib3ds_io_seek(io, c->cur, LIB3DS_SEEK_SET); if (lib3ds_io_error(io)) { LIB3DS_ERROR_LOG; return(LIB3DS_FALSE); } return(LIB3DS_TRUE); }
static void face_array_write(Lib3dsFile *file, Lib3dsMesh *mesh, Lib3dsIo *io) { Lib3dsChunk c; if (mesh->nfaces == 0) { return; } c.chunk = CHK_FACE_ARRAY; lib3ds_chunk_write_start(&c, io); { int i; lib3ds_io_write_word(io, (uint16_t) mesh->nfaces); for (i = 0; i < mesh->nfaces; ++i) { lib3ds_io_write_word(io, mesh->faces[i].index[0]); lib3ds_io_write_word(io, mesh->faces[i].index[1]); lib3ds_io_write_word(io, mesh->faces[i].index[2]); lib3ds_io_write_word(io, mesh->faces[i].flags); } } { /*---- MSH_CHK_MAT_GROUP ----*/ Lib3dsChunk c; int i, j; uint16_t num; char *matf = (char*)calloc(sizeof(char), mesh->nfaces); ((Lib3dsIoImpl*)io->impl)->tmp_mem = matf; assert(matf); for (i = 0; i < mesh->nfaces; ++i) { if (!matf[i] && (mesh->faces[i].material >= 0) && (mesh->faces[i].material < file->nmaterials)) { matf[i] = 1; num = 1; for (j = i + 1; j < mesh->nfaces; ++j) { if (mesh->faces[i].material == mesh->faces[j].material) ++num; } c.chunk = CHK_MSH_MAT_GROUP; c.size = 6 + (uint32_t)strlen(file->materials[mesh->faces[i].material]->name) + 1 + 2 + 2 * num; lib3ds_chunk_write(&c, io); lib3ds_io_write_string(io, file->materials[mesh->faces[i].material]->name); lib3ds_io_write_word(io, num); lib3ds_io_write_word(io, (uint16_t) i); for (j = i + 1; j < mesh->nfaces; ++j) { if (mesh->faces[i].material == mesh->faces[j].material) { lib3ds_io_write_word(io, (uint16_t) j); matf[j] = 1; } } } } ((Lib3dsIoImpl*)io->impl)->tmp_mem = NULL; free(matf); } { /*---- SMOOTH_GROUP ----*/ Lib3dsChunk c; int i; c.chunk = CHK_SMOOTH_GROUP; c.size = 6 + 4 * mesh->nfaces; lib3ds_chunk_write(&c, io); for (i = 0; i < mesh->nfaces; ++i) { lib3ds_io_write_dword(io, mesh->faces[i].smoothing_group); } } { /*---- MSH_BOXMAP ----*/ Lib3dsChunk c; if (strlen(mesh->box_front) || strlen(mesh->box_back) || strlen(mesh->box_left) || strlen(mesh->box_right) || strlen(mesh->box_top) || strlen(mesh->box_bottom)) { c.chunk = CHK_MSH_BOXMAP; lib3ds_chunk_write_start(&c, io); lib3ds_io_write_string(io, mesh->box_front); lib3ds_io_write_string(io, mesh->box_back); lib3ds_io_write_string(io, mesh->box_left); lib3ds_io_write_string(io, mesh->box_right); lib3ds_io_write_string(io, mesh->box_top); lib3ds_io_write_string(io, mesh->box_bottom); lib3ds_chunk_write_end(&c, io); } } lib3ds_chunk_write_end(&c, io); }
static Lib3dsBool face_array_write(Lib3dsMesh *mesh, Lib3dsIo *io) { Lib3dsChunk c; if (!mesh->faces || !mesh->faceL) { return(LIB3DS_TRUE); } ASSERT(mesh->faces<0x10000); c.chunk=LIB3DS_FACE_ARRAY; if (!lib3ds_chunk_write_start(&c, io)) { return(LIB3DS_FALSE); } { unsigned i; lib3ds_io_write_word(io, (Lib3dsWord)mesh->faces); for (i=0; i<mesh->faces; ++i) { lib3ds_io_write_word(io, mesh->faceL[i].points[0]); lib3ds_io_write_word(io, mesh->faceL[i].points[1]); lib3ds_io_write_word(io, mesh->faceL[i].points[2]); lib3ds_io_write_word(io, mesh->faceL[i].flags); } } { /*---- MSH_MAT_GROUP ----*/ Lib3dsChunk c; unsigned i,j; Lib3dsWord num; char *matf=calloc(sizeof(char), mesh->faces); if (!matf) { return(LIB3DS_FALSE); } for (i=0; i<mesh->faces; ++i) { if (!matf[i] && strlen(mesh->faceL[i].material)) { matf[i]=1; num=1; for (j=i+1; j<mesh->faces; ++j) { if (strcmp(mesh->faceL[i].material, mesh->faceL[j].material)==0) ++num; } c.chunk=LIB3DS_MSH_MAT_GROUP; c.size=6+ (Lib3dsDword)strlen(mesh->faceL[i].material)+1 +2+2*num; lib3ds_chunk_write(&c, io); lib3ds_io_write_string(io, mesh->faceL[i].material); lib3ds_io_write_word(io, num); lib3ds_io_write_word(io, (Lib3dsWord)i); for (j=i+1; j<mesh->faces; ++j) { if (strcmp(mesh->faceL[i].material, mesh->faceL[j].material)==0) { lib3ds_io_write_word(io, (Lib3dsWord)j); matf[j]=1; } } } } free(matf); } { /*---- SMOOTH_GROUP ----*/ Lib3dsChunk c; unsigned i; c.chunk=LIB3DS_SMOOTH_GROUP; c.size=6+4*mesh->faces; lib3ds_chunk_write(&c, io); for (i=0; i<mesh->faces; ++i) { lib3ds_io_write_dword(io, mesh->faceL[i].smoothing); } } { /*---- MSH_BOXMAP ----*/ Lib3dsChunk c; if (strlen(mesh->box_map.front) || strlen(mesh->box_map.back) || strlen(mesh->box_map.left) || strlen(mesh->box_map.right) || strlen(mesh->box_map.top) || strlen(mesh->box_map.bottom)) { c.chunk=LIB3DS_MSH_BOXMAP; if (!lib3ds_chunk_write_start(&c, io)) { return(LIB3DS_FALSE); } lib3ds_io_write_string(io, mesh->box_map.front); lib3ds_io_write_string(io, mesh->box_map.back); lib3ds_io_write_string(io, mesh->box_map.left); lib3ds_io_write_string(io, mesh->box_map.right); lib3ds_io_write_string(io, mesh->box_map.top); lib3ds_io_write_string(io, mesh->box_map.bottom); if (!lib3ds_chunk_write_end(&c, io)) { return(LIB3DS_FALSE); } } } if (!lib3ds_chunk_write_end(&c, io)) { return(LIB3DS_FALSE); } return(LIB3DS_TRUE); }
/*! * \ingroup atmosphere */ Lib3dsBool lib3ds_atmosphere_write(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io) { if (atmosphere->fog.use) { /*---- LIB3DS_FOG ----*/ Lib3dsChunk c; c.chunk=LIB3DS_FOG; if (!lib3ds_chunk_write_start(&c,io)) { return(LIB3DS_FALSE); } lib3ds_io_write_float(io, atmosphere->fog.near_plane); lib3ds_io_write_float(io, atmosphere->fog.near_density); lib3ds_io_write_float(io, atmosphere->fog.far_plane); lib3ds_io_write_float(io, atmosphere->fog.far_density); { Lib3dsChunk c; c.chunk=LIB3DS_COLOR_F; c.size=18; lib3ds_chunk_write(&c,io); lib3ds_io_write_rgb(io, atmosphere->fog.col); } if (atmosphere->fog.fog_background) { Lib3dsChunk c; c.chunk=LIB3DS_FOG_BGND; c.size=6; lib3ds_chunk_write(&c,io); } if (!lib3ds_chunk_write_end(&c,io)) { return(LIB3DS_FALSE); } } if (atmosphere->layer_fog.use) { /*---- LIB3DS_LAYER_FOG ----*/ Lib3dsChunk c; c.chunk=LIB3DS_LAYER_FOG; c.size=40; lib3ds_chunk_write(&c,io); lib3ds_io_write_float(io, atmosphere->layer_fog.near_y); lib3ds_io_write_float(io, atmosphere->layer_fog.far_y); lib3ds_io_write_float(io, atmosphere->layer_fog.near_y); lib3ds_io_write_dword(io, atmosphere->layer_fog.flags); { Lib3dsChunk c; c.chunk=LIB3DS_COLOR_F; c.size=18; lib3ds_chunk_write(&c,io); lib3ds_io_write_rgb(io, atmosphere->fog.col); } } if (atmosphere->dist_cue.use) { /*---- LIB3DS_DISTANCE_CUE ----*/ Lib3dsChunk c; c.chunk=LIB3DS_DISTANCE_CUE; if (!lib3ds_chunk_write_start(&c,io)) { return(LIB3DS_FALSE); } lib3ds_io_write_float(io, atmosphere->dist_cue.near_plane); lib3ds_io_write_float(io, atmosphere->dist_cue.near_dimming); lib3ds_io_write_float(io, atmosphere->dist_cue.far_plane); lib3ds_io_write_float(io, atmosphere->dist_cue.far_dimming); if (atmosphere->dist_cue.cue_background) { Lib3dsChunk c; c.chunk=LIB3DS_DCUE_BGND; c.size=6; lib3ds_chunk_write(&c,io); } if (!lib3ds_chunk_write_end(&c,io)) { return(LIB3DS_FALSE); } } if (atmosphere->fog.use) { /*---- LIB3DS_USE_FOG ----*/ Lib3dsChunk c; c.chunk=LIB3DS_USE_FOG; c.size=6; lib3ds_chunk_write(&c,io); } if (atmosphere->layer_fog.use) { /*---- LIB3DS_USE_LAYER_FOG ----*/ Lib3dsChunk c; c.chunk=LIB3DS_USE_LAYER_FOG; c.size=6; lib3ds_chunk_write(&c,io); } if (atmosphere->dist_cue.use) { /*---- LIB3DS_USE_DISTANCE_CUE ----*/ Lib3dsChunk c; c.chunk=LIB3DS_USE_V_GRADIENT; c.size=6; lib3ds_chunk_write(&c,io); } return(LIB3DS_TRUE); }
void lib3ds_atmosphere_write(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io) { if (atmosphere->use_fog) /*---- LIB3DS_FOG ----*/ { Lib3dsChunk c; c.chunk = CHK_FOG; lib3ds_chunk_write_start(&c, io); lib3ds_io_write_float(io, atmosphere->fog_near_plane); lib3ds_io_write_float(io, atmosphere->fog_near_density); lib3ds_io_write_float(io, atmosphere->fog_far_plane); lib3ds_io_write_float(io, atmosphere->fog_far_density); { Lib3dsChunk c; c.chunk = CHK_COLOR_F; c.size = 18; lib3ds_chunk_write(&c, io); lib3ds_io_write_rgb(io, atmosphere->fog_color); } if (atmosphere->fog_background) { Lib3dsChunk c; c.chunk = CHK_FOG_BGND; c.size = 6; lib3ds_chunk_write(&c, io); } lib3ds_chunk_write_end(&c, io); } if (atmosphere->use_layer_fog) /*---- LIB3DS_LAYER_FOG ----*/ { Lib3dsChunk c; c.chunk = CHK_LAYER_FOG; c.size = 40; lib3ds_chunk_write(&c, io); lib3ds_io_write_float(io, atmosphere->layer_fog_near_y); lib3ds_io_write_float(io, atmosphere->layer_fog_far_y); lib3ds_io_write_float(io, atmosphere->layer_fog_near_y); lib3ds_io_write_dword(io, atmosphere->layer_fog_flags); { Lib3dsChunk c; c.chunk = CHK_COLOR_F; c.size = 18; lib3ds_chunk_write(&c, io); lib3ds_io_write_rgb(io, atmosphere->fog_color); } } if (atmosphere->use_dist_cue) /*---- LIB3DS_DISTANCE_CUE ----*/ { Lib3dsChunk c; c.chunk = CHK_DISTANCE_CUE; lib3ds_chunk_write_start(&c, io); lib3ds_io_write_float(io, atmosphere->dist_cue_near_plane); lib3ds_io_write_float(io, atmosphere->dist_cue_near_dimming); lib3ds_io_write_float(io, atmosphere->dist_cue_far_plane); lib3ds_io_write_float(io, atmosphere->dist_cue_far_dimming); if (atmosphere->dist_cue_background) { Lib3dsChunk c; c.chunk = CHK_DCUE_BGND; c.size = 6; lib3ds_chunk_write(&c, io); } lib3ds_chunk_write_end(&c, io); } if (atmosphere->use_fog) /*---- LIB3DS_USE_FOG ----*/ { Lib3dsChunk c; c.chunk = CHK_USE_FOG; c.size = 6; lib3ds_chunk_write(&c, io); } if (atmosphere->use_layer_fog) /*---- LIB3DS_USE_LAYER_FOG ----*/ { Lib3dsChunk c; c.chunk = CHK_USE_LAYER_FOG; c.size = 6; lib3ds_chunk_write(&c, io); } if (atmosphere->use_dist_cue) /*---- LIB3DS_USE_DISTANCE_CUE ----*/ { Lib3dsChunk c; c.chunk = CHK_USE_V_GRADIENT; c.size = 6; lib3ds_chunk_write(&c, io); } }