📄 file.cpp
字号:
/* * The 3D Studio File Format Library * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net> * All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: file.cpp 9124 2008-11-07 15:08:08Z robert $ */#define LIB3DS_EXPORT#include "file.h"#include "chunk.h"#include "readwrite.h"#include "material.h"#include "mesh.h"#include "camera.h"#include "light.h"#include "node.h"#include "vector.h"#include <stdlib.h>#include <string.h>#include <math.h>#include "config.h"#ifdef WITH_DMALLOC#include <dmalloc.h>#endif#include <osgDB/FileUtils>/*! * \defgroup file Files * * \author J.E. Hoffmann <je-h@gmx.net> *//*! * Loads a .3DS file from disk into memory. * * \param filename The filename of the .3DS file * * \return A pointer to the Lib3dsFile structure containing the * data of the .3DS file. * If the .3DS file can not be loaded NULL is returned. * * \note To free the returned pointer use lib3ds_free. * * \see lib3ds_file_save * \see lib3ds_file_new * \see lib3ds_file_free * * \ingroup file */Lib3dsFile*lib3ds_file_load(const char *filename){ FILE *f; Lib3dsFile *file; f=osgDB::fopen(filename, "rb"); if (!f) { return(0); } file=lib3ds_file_new(); if (!file) { fclose(f); return(0); } if (!lib3ds_file_read(file, f)) { free(file); fclose(f); return(0); } fclose(f); return(file);}/*! * Saves a .3DS file from memory to disk. * * \param file A pointer to a Lib3dsFile structure containing the * the data that should be stored. * \param filename The filename of the .3DS file to store the data in. * * \return TRUE on success, FALSE otherwise. * * \see lib3ds_file_load * * \ingroup file */Lib3dsBoollib3ds_file_save(Lib3dsFile *file, const char *filename){ FILE *f; f=osgDB::fopen(filename, "wb"); if (!f) { return(LIB3DS_FALSE); } if (!lib3ds_file_write(file, f)) { fclose(f); return(LIB3DS_FALSE); } fclose(f); return(LIB3DS_TRUE);}/*! * \ingroup file */Lib3dsFile*lib3ds_file_new(){ Lib3dsFile *file; file=(Lib3dsFile*)calloc(sizeof(Lib3dsFile),1); if (!file) { return(0); } file->mesh_version=3; file->master_scale=1.0f; file->keyf_revision=5; strcpy(file->name, "LIB3DS"); return(file);}/*! * \ingroup file */voidlib3ds_file_free(Lib3dsFile* file){ ASSERT(file); lib3ds_viewport_set_views(&file->viewport,0); { Lib3dsMaterial *p,*q; for (p=file->materials; p; p=q) { q=p->next; lib3ds_material_free(p); } file->materials=0; } { Lib3dsCamera *p,*q; for (p=file->cameras; p; p=q) { q=p->next; lib3ds_camera_free(p); } file->cameras=0; } { Lib3dsLight *p,*q; for (p=file->lights; p; p=q) { q=p->next; lib3ds_light_free(p); } file->lights=0; } { Lib3dsMesh *p,*q; for (p=file->meshes; p; p=q) { q=p->next; lib3ds_mesh_free(p); } file->meshes=0; } { Lib3dsNode *p,*q; for (p=file->nodes; p; p=q) { q=p->next; lib3ds_node_free(p); } } free(file);}/*! * \ingroup file */voidlib3ds_file_eval(Lib3dsFile *file, Lib3dsFloat t){ Lib3dsNode *p; for (p=file->nodes; p!=0; p=p->next) { lib3ds_node_eval(p, t); }}static Lib3dsBoolnamed_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);}static Lib3dsBoolambient_read(Lib3dsFile *file, FILE *f){ Lib3dsChunk c; Lib3dsWord chunk; Lib3dsBool have_lin=LIB3DS_FALSE; if (!lib3ds_chunk_read_start(&c, LIB3DS_AMBIENT_LIGHT, f)) { return(LIB3DS_FALSE); } while ((chunk=lib3ds_chunk_read_next(&c, f))!=0) { switch (chunk) { case LIB3DS_LIN_COLOR_F: { int i; for (i=0; i<3; ++i) { file->ambient[i]=lib3ds_float_read(f); } } have_lin=LIB3DS_TRUE; break; case LIB3DS_COLOR_F: { /* gamma corrected color chunk replaced in 3ds R3 by LIN_COLOR_24 */ if (!have_lin) { int i; for (i=0; i<3; ++i) { file->ambient[i]=lib3ds_float_read(f); } } } break; default: lib3ds_chunk_unknown(chunk); } } lib3ds_chunk_read_end(&c, f); return(LIB3DS_TRUE);}static Lib3dsBoolmdata_read(Lib3dsFile *file, FILE *f){ Lib3dsChunk c; Lib3dsWord chunk; if (!lib3ds_chunk_read_start(&c, LIB3DS_MDATA, f)) { return(LIB3DS_FALSE); } while ((chunk=lib3ds_chunk_read_next(&c, f))!=0) { switch (chunk) { case LIB3DS_MESH_VERSION: { file->mesh_version=lib3ds_intd_read(f); } break; case LIB3DS_MASTER_SCALE: { file->master_scale=lib3ds_float_read(f); } break; case LIB3DS_SHADOW_MAP_SIZE: case LIB3DS_LO_SHADOW_BIAS: case LIB3DS_HI_SHADOW_BIAS: case LIB3DS_SHADOW_SAMPLES: case LIB3DS_SHADOW_RANGE: case LIB3DS_SHADOW_FILTER: case LIB3DS_RAY_BIAS: { lib3ds_chunk_read_reset(&c, f); if (!lib3ds_shadow_read(&file->shadow, f)) { return(LIB3DS_FALSE); } } break; case LIB3DS_VIEWPORT_LAYOUT: case LIB3DS_DEFAULT_VIEW: { lib3ds_chunk_read_reset(&c, f); if (!lib3ds_viewport_read(&file->viewport, f)) { return(LIB3DS_FALSE); } } break; case LIB3DS_O_CONSTS: { int i; for (i=0; i<3; ++i) { file->construction_plane[i]=lib3ds_float_read(f); } } break; case LIB3DS_AMBIENT_LIGHT: { lib3ds_chunk_read_reset(&c, f); if (!ambient_read(file, f)) { return(LIB3DS_FALSE); } } break; case LIB3DS_BIT_MAP: case LIB3DS_SOLID_BGND: case LIB3DS_V_GRADIENT: case LIB3DS_USE_BIT_MAP: case LIB3DS_USE_SOLID_BGND: case LIB3DS_USE_V_GRADIENT: { lib3ds_chunk_read_reset(&c, f); if (!lib3ds_background_read(&file->background, f)) { return(LIB3DS_FALSE); } } break; case LIB3DS_FOG: case LIB3DS_LAYER_FOG: case LIB3DS_DISTANCE_CUE: case LIB3DS_USE_FOG: case LIB3DS_USE_LAYER_FOG: case LIB3DS_USE_DISTANCE_CUE: { lib3ds_chunk_read_reset(&c, f); if (!lib3ds_atmosphere_read(&file->atmosphere, f)) { return(LIB3DS_FALSE); } } break; case LIB3DS_MAT_ENTRY: { Lib3dsMaterial *material; material=lib3ds_material_new(); if (!material) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_material_read(material, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_material(file, material); } break; case LIB3DS_NAMED_OBJECT: { lib3ds_chunk_read_reset(&c, f); if (!named_object_read(file, f)) { return(LIB3DS_FALSE); } } break; default: lib3ds_chunk_unknown(chunk); } } lib3ds_chunk_read_end(&c, f); return(LIB3DS_TRUE);}static Lib3dsBoolkfdata_read(Lib3dsFile *file, FILE *f){ Lib3dsChunk c; Lib3dsWord chunk; if (!lib3ds_chunk_read_start(&c, LIB3DS_KFDATA, f)) { return(LIB3DS_FALSE); } while ((chunk=lib3ds_chunk_read_next(&c, f))!=0) { switch (chunk) { case LIB3DS_KFHDR: { file->keyf_revision=lib3ds_word_read(f); if (!lib3ds_string_read(file->name, 12+1, f)) { return(LIB3DS_FALSE); } file->frames=lib3ds_intd_read(f); } break; case LIB3DS_KFSEG: { file->segment_from=lib3ds_intd_read(f); file->segment_to=lib3ds_intd_read(f); } break; case LIB3DS_KFCURTIME: { file->current_frame=lib3ds_intd_read(f); } break; case LIB3DS_VIEWPORT_LAYOUT: case LIB3DS_DEFAULT_VIEW: { lib3ds_chunk_read_reset(&c, f); if (!lib3ds_viewport_read(&file->viewport_keyf, f)) { return(LIB3DS_FALSE); } } break; case LIB3DS_AMBIENT_NODE_TAG: { Lib3dsNode *node; node=lib3ds_node_new_ambient(); if (!node) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_node_read(node, file, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_node(file, node); } break; case LIB3DS_OBJECT_NODE_TAG: { Lib3dsNode *node; node=lib3ds_node_new_object(); if (!node) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_node_read(node, file, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_node(file, node); } break; case LIB3DS_CAMERA_NODE_TAG: { Lib3dsNode *node; node=lib3ds_node_new_camera(); if (!node) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_node_read(node, file, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_node(file, node); } break; case LIB3DS_TARGET_NODE_TAG: { Lib3dsNode *node; node=lib3ds_node_new_target(); if (!node) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_node_read(node, file, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_node(file, node); } break; case LIB3DS_LIGHT_NODE_TAG: case LIB3DS_SPOTLIGHT_NODE_TAG: { Lib3dsNode *node; node=lib3ds_node_new_light(); if (!node) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_node_read(node, file, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_node(file, node); } break; case LIB3DS_L_TARGET_NODE_TAG: { Lib3dsNode *node; node=lib3ds_node_new_spot(); if (!node) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_node_read(node, file, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_node(file, node); } break; default: lib3ds_chunk_unknown(chunk); } } lib3ds_chunk_read_end(&c, f); return(LIB3DS_TRUE);}/*! * \ingroup file */Lib3dsBoollib3ds_file_read(Lib3dsFile *file, FILE *f){ Lib3dsChunk c; Lib3dsWord chunk; if (!lib3ds_chunk_read_start(&c, 0, f)) { return(LIB3DS_FALSE); } switch (c.chunk) { case LIB3DS_MDATA: { lib3ds_chunk_read_reset(&c, f); if (!mdata_read(file, f)) { return(LIB3DS_FALSE); } } break; case LIB3DS_M3DMAGIC: case LIB3DS_MLIBMAGIC: case LIB3DS_CMAGIC: { while ((chunk=lib3ds_chunk_read_next(&c, f))!=0) { switch (chunk) { case LIB3DS_M3D_VERSION: { file->mesh_version=lib3ds_dword_read(f); } break; case LIB3DS_MDATA: { lib3ds_chunk_read_reset(&c, f); if (!mdata_read(file, f)) { return(LIB3DS_FALSE); } } break; case LIB3DS_KFDATA: { lib3ds_chunk_read_reset(&c, f); if (!kfdata_read(file, f)) { return(LIB3DS_FALSE); } } break; default: lib3ds_chunk_unknown(chunk); } } } break; default: lib3ds_chunk_unknown(c.chunk); return(LIB3DS_FALSE); } lib3ds_chunk_read_end(&c, f); return(LIB3DS_TRUE);}static Lib3dsBoolcolorf_write(Lib3dsRgba rgb, FILE *f){ Lib3dsChunk c; c.chunk=LIB3DS_COLOR_F; c.size=18; lib3ds_chunk_write(&c,f); lib3ds_rgb_write(rgb,f); c.chunk=LIB3DS_LIN_COLOR_F; c.size=18; lib3ds_chunk_write(&c,f); lib3ds_rgb_write(rgb,f); return(LIB3DS_TRUE);}static Lib3dsBoolmdata_write(Lib3dsFile *file, FILE *f){ Lib3dsChunk c; c.chunk=LIB3DS_MDATA; if (!lib3ds_chunk_write_start(&c,f)) { return(LIB3DS_FALSE); } { /*---- LIB3DS_MESH_VERSION ----*/ Lib3dsChunk c; c.chunk=LIB3DS_MESH_VERSION; c.size=10; lib3ds_chunk_write(&c,f); lib3ds_intd_write(file->mesh_version,f); } { /*---- LIB3DS_MASTER_SCALE ----*/ Lib3dsChunk c; c.chunk=LIB3DS_MASTER_SCALE; c.size=10; lib3ds_chunk_write(&c,f); lib3ds_float_write(file->master_scale,f); } { /*---- LIB3DS_O_CONSTS ----*/ int i; for (i=0; i<3; ++i) { if (fabs(file->construction_plane[i])>LIB3DS_EPSILON) { break; } } if (i<3) { Lib3dsChunk c; c.chunk=LIB3DS_O_CONSTS; c.size=18; lib3ds_chunk_write(&c,f); lib3ds_vector_write(file->construction_plane,f); } } { /*---- LIB3DS_AMBIENT_LIGHT ----*/ int i; for (i=0; i<3; ++i) { if (fabs(file->ambient[i])>LIB3DS_EPSILON) { break; } } if (i<3) { Lib3dsChunk c; c.chunk=LIB3DS_AMBIENT_LIGHT; c.size=42; lib3ds_chunk_write(&c,f); colorf_write(file->ambient,f); } } lib3ds_background_write(&file->background, f); lib3ds_atmosphere_write(&file->atmosphere, f); lib3ds_shadow_write(&file->shadow, f); lib3ds_viewport_write(&file->viewport, f); { Lib3dsMaterial *p; for (p=file->materials; p!=0; p=p->next) { if (!lib3ds_material_write(p,f)) { return(LIB3DS_FALSE); } } } { Lib3dsCamera *p; Lib3dsChunk c; for (p=file->cameras; p!=0; p=p->next) { c.chunk=LIB3DS_NAMED_OBJECT; if (!lib3ds_chunk_write_start(&c,f)) { return(LIB3DS_FALSE); } lib3ds_string_write(p->name,f); lib3ds_camera_write(p,f); if (!lib3ds_chunk_write_end(&c,f)) { return(LIB3DS_FALSE); } } } { Lib3dsLight *p; Lib3dsChunk c; for (p=file->lights; p!=0; p=p->next) { c.chunk=LIB3DS_NAMED_OBJECT; if (!lib3ds_chunk_write_start(&c,f)) { return(LIB3DS_FALSE); } lib3ds_string_write(p->name,f); lib3ds_light_write(p,f); if (!lib3ds_chunk_write_end(&c,f)) { return(LIB3DS_FALSE); } } } {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -