// 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_open public static bool lib3ds_file_save(Lib3dsFile file, string filename) { try { FileStream f = File.Create(filename); try { Lib3dsIo io = new Lib3dsIo(); io.self = f; io.seek_func = fileio_seek_func; io.tell_func = fileio_tell_func; io.read_func = fileio_read_func; io.write_func = fileio_write_func; io.log_func = null; return(lib3ds_file_write(file, io)); } finally { f.Close(); } } catch { return(false); } }
// 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 true on success, false on failure. public static bool lib3ds_file_write(Lib3dsFile file, Lib3dsIo io) { Lib3dsChunk c = new Lib3dsChunk(); lib3ds_io_setup(io); try { c.chunk = Lib3dsChunks.CHK_M3DMAGIC; lib3ds_chunk_write_start(c, io); // ---- LIB3DS_M3D_VERSION ---- Lib3dsChunk c_version = new Lib3dsChunk(); c_version.chunk = Lib3dsChunks.CHK_M3D_VERSION; c_version.size = 10; lib3ds_chunk_write(c_version, io); lib3ds_io_write_dword(io, file.mesh_version); mdata_write(file, io); kfdata_write(file, io); lib3ds_chunk_write_end(c, io); lib3ds_io_cleanup(io); return(true); } catch { lib3ds_io_cleanup(io); return(false); } }
public static void lib3ds_file_insert_node(Lib3dsFile file, Lib3dsNode node, Lib3dsNode before) { Debug.Assert(file != null); Debug.Assert(node != null); if (before != null) { List <Lib3dsNode> list = before.parent != null?before.parent.childs:file.nodes; Debug.Assert(list.Count != 0); int index = list.IndexOf(before); if (index >= 0) { list.Insert(index, node); } else { list.Add(node); } node.parent = before.parent; } else { file.nodes.Insert(0, node); node.parent = null; } }
// Evaluate all of the nodes in this Lib3dsFile object. // // \param file The Lib3dsFile object to be evaluated. // \param t time value, between 0. and file->frames // // \see lib3ds_node_eval public static void lib3ds_file_eval(Lib3dsFile file, float t) { foreach (Lib3dsNode p in file.nodes) { lib3ds_node_eval(p, t); } }
// Read 3ds file data into a Lib3dsFile object. // // \param file The Lib3dsFile object to be filled. // \param io A Lib3dsIo object previously set up by the caller. // // \return true on success, false on failure. public static bool lib3ds_file_read(Lib3dsFile file, Lib3dsIo io) { Lib3dsChunk c = new Lib3dsChunk(); Lib3dsChunks chunk; lib3ds_io_setup(io); try { lib3ds_chunk_read_start(c, 0, io); switch (c.chunk) { case Lib3dsChunks.CHK_MDATA: lib3ds_chunk_read_reset(c, io); mdata_read(file, io); break; case Lib3dsChunks.CHK_M3DMAGIC: case Lib3dsChunks.CHK_MLIBMAGIC: case Lib3dsChunks.CHK_CMAGIC: while ((chunk = lib3ds_chunk_read_next(c, io)) != 0) { switch (chunk) { case Lib3dsChunks.CHK_M3D_VERSION: file.mesh_version = lib3ds_io_read_dword(io); break; case Lib3dsChunks.CHK_MDATA: lib3ds_chunk_read_reset(c, io); mdata_read(file, io); break; case Lib3dsChunks.CHK_KFDATA: lib3ds_chunk_read_reset(c, io); kfdata_read(file, io); break; default: lib3ds_chunk_unknown(chunk, io); break; } } break; default: lib3ds_chunk_unknown(c.chunk, io); return(false); } lib3ds_chunk_read_end(c, io); lib3ds_io_cleanup(io); return(true); } catch { lib3ds_io_cleanup(io); return(false); } }
public static void lib3ds_file_create_nodes_for_meshes(Lib3dsFile file) { foreach (Lib3dsMesh mesh in file.meshes) { Lib3dsNode p = lib3ds_node_new(Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE); p.name = mesh.name; lib3ds_file_insert_node(file, p, null); } }
public static void lib3ds_file_minmax_node_id(Lib3dsFile file, ref ushort min_id, ref ushort max_id) { min_id = 65535; max_id = 0; foreach (Lib3dsNode p in file.nodes) { file_minmax_node_id_impl(file, p, ref min_id, ref max_id); } }
public static void lib3ds_file_append_node(Lib3dsFile file, Lib3dsNode node, Lib3dsNode parent) { Debug.Assert(file != null); Debug.Assert(node != null); List <Lib3dsNode> list = parent != null?parent.childs:file.nodes; list.Add(node); node.parent = parent; }
// Remove a node from the a Lib3dsFile object. // // \param file The Lib3dsFile object to be modified. // \param node The Lib3dsNode object to be removed from file public static void lib3ds_file_remove_node(Lib3dsFile file, Lib3dsNode node) { if (node.parent != null) { node.parent.childs.Remove(node); } else { file.nodes.Remove(node); } }
public static Lib3dsMesh lib3ds_file_mesh_for_node(Lib3dsFile file, Lib3dsNode node) { if (node.type != Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE) { return(null); } Lib3dsMeshInstanceNode n = (Lib3dsMeshInstanceNode)node; int index = lib3ds_file_mesh_by_name(file, node.name); return((index >= 0)?file.meshes[index]:null); }
public static void lib3ds_file_insert_mesh(Lib3dsFile file, Lib3dsMesh mesh, int index) { Debug.Assert(file != null); if (index < 0) { file.meshes.Add(mesh); } else { file.meshes.Insert(index, mesh); } }
public static void lib3ds_file_insert_material(Lib3dsFile file, Lib3dsMaterial material, int index) { Debug.Assert(file != null); if (index < 0) { file.materials.Add(material); } else { file.materials.Insert(index, material); } }
public static void lib3ds_file_insert_light(Lib3dsFile file, Lib3dsLight light, int index) { Debug.Assert(file != null); if (index < 0) { file.lights.Add(light); } else { file.lights.Insert(index, light); } }
public static void lib3ds_file_insert_camera(Lib3dsFile file, Lib3dsCamera camera, int index) { Debug.Assert(file != null); if (index < 0) { file.cameras.Add(camera); } else { file.cameras.Insert(index, camera); } }
public static int lib3ds_file_light_by_name(Lib3dsFile file, string name) { Debug.Assert(file != null); for (int i = 0; i < file.lights.Count; i++) { if (file.lights[i].name == name) { return(i); } } return(-1); }
static void write_mtl(StreamWriter mtl, Lib3dsFile f) { mtl.WriteLine("# Wavefront material file"); mtl.WriteLine("# Converted by 3ds2obj"); mtl.WriteLine("# http://www.lib3ds.org"); mtl.WriteLine(); bool unique=true; for(int i=0; i<f.materials.Count; i++) { string newname=""; foreach(char p in f.materials[i].name) { if(!char.IsLetterOrDigit(p)&&p!='_') newname+='_'; else newname+=p; } f.materials[i].name=newname; for(int j=0; j<i; j++) { if(f.materials[i].name==f.materials[j].name) { unique=false; break; } } if(!unique) break; } if(!unique) { for(int i=0; i<f.materials.Count; i++) f.materials[i].name=string.Format("mat_{0}", i); } foreach(Lib3dsMaterial m in f.materials) { mtl.WriteLine("newmtl {0}", m.name); mtl.WriteLine("Ka {0} {1} {2}", m.ambient[0], m.ambient[1], m.ambient[2]); mtl.WriteLine("Kd {0} {1} {2}", m.diffuse[0], m.diffuse[1], m.diffuse[2]); mtl.WriteLine("Ks {0} {1} {2}", m.specular[0], m.specular[1], m.specular[2]); mtl.WriteLine("illum 2"); mtl.WriteLine("Ns {0}", Math.Pow(2, 10*m.shininess+1)); mtl.WriteLine("d {0}", 1.0-m.transparency); mtl.WriteLine("map_Kd {0}", m.texture1_map.name); mtl.WriteLine("map_bump {0}", m.bump_map.name); mtl.WriteLine("map_d {0}", m.opacity_map.name); mtl.WriteLine("refl {0}", m.reflection_map.name); mtl.WriteLine("map_KS {0}", m.specular_map.name); mtl.WriteLine(); } }
// Free a Lib3dsFile object and all of its resources. // // \param file The Lib3dsFile object to be freed. public static void lib3ds_file_free(Lib3dsFile file) { Debug.Assert(file != null); lib3ds_file_reserve_materials(file, 0, true); lib3ds_file_reserve_cameras(file, 0, true); lib3ds_file_reserve_lights(file, 0, true); lib3ds_file_reserve_meshes(file, 0, true); foreach (Lib3dsNode p in file.nodes) { lib3ds_node_free(p); } file.nodes.Clear(); }
static void file_minmax_node_id_impl(Lib3dsFile file, Lib3dsNode node, ref ushort min_id, ref ushort max_id) { if (min_id > node.node_id) { min_id = node.node_id; } if (max_id < node.node_id) { max_id = node.node_id; } foreach (Lib3dsNode p in node.childs) { file_minmax_node_id_impl(file, p, ref min_id, ref max_id); } }
// Return a node object by name and type. // // This function performs a recursive search for the specified node. // Both name and type must match. // // \param file The Lib3dsFile to be searched. // \param name The target node name. // \param type The target node type // // \return A pointer to the first matching node, or NULL if not found. // // \see lib3ds_node_by_name public static Lib3dsNode lib3ds_file_node_by_name(Lib3dsFile file, string name, Lib3dsNodeType type) { Debug.Assert(file != null); foreach (Lib3dsNode p in file.nodes) { if (p.type == type && p.name == name) { return(p); } Lib3dsNode q = lib3ds_node_by_name(p, name, type); if (q != null) { return(q); } } return(null); }
// Return a node object by id. // // This function performs a recursive search for the specified node. // // \param file The Lib3dsFile to be searched. // \param node_id The target node id. // // \return A pointer to the first matching node, or NULL if not found. // // \see lib3ds_node_by_id public static Lib3dsNode lib3ds_file_node_by_id(Lib3dsFile file, ushort node_id) { Debug.Assert(file != null); foreach (Lib3dsNode p in file.nodes) { if (p.node_id == node_id) { return(p); } Lib3dsNode q = lib3ds_node_by_id(p, node_id); if (q != null) { return(q); } } return(null); }
public static void AddMeshTo3DS(Lib3dsFile res, PSKFile f, Matrix m) { Lib3dsMesh mesh = new Lib3dsMesh(); string name = "Box00" + res.meshes.Count.ToString(); mesh.name = name; mesh.matrix = Matrix2FA(Matrix.Identity); mesh.vertices = new List<Lib3dsVertex>(); foreach (PSKFile.PSKPoint p in f.psk.points) { Vector3 v = p.ToVector3(); v = Vector3.TransformCoordinate(v, m); mesh.vertices.Add(new Lib3dsVertex(v.X, -v.Y, v.Z)); } mesh.texcos = new List<Lib3dsTexturecoordinate>(); for (int i = 0; i < f.psk.points.Count; i++) foreach (PSKFile.PSKEdge e in f.psk.edges) if (e.index == i) mesh.texcos.Add(new Lib3dsTexturecoordinate(e.U, e.V)); mesh.faces = new List<Lib3dsFace>(); foreach (PSKFile.PSKFace face in f.psk.faces) { Lib3dsFace ff = new Lib3dsFace(); ff.flags = 6; ff.index = new ushort[3]; ff.index[0] = (ushort)f.psk.edges[face.v0].index; ff.index[1] = (ushort)f.psk.edges[face.v2].index; ff.index[2] = (ushort)f.psk.edges[face.v1].index; mesh.faces.Add(ff); } mesh.nfaces = (ushort)mesh.faces.Count; mesh.nvertices = (ushort)mesh.vertices.Count; mesh.map_type = Lib3dsMapType.LIB3DS_MAP_NONE; mesh.object_flags = 0; mesh.color = 128; res.meshes.Add(mesh); Lib3dsNode node = new Lib3dsMeshInstanceNode(); node.matrixNode = Matrix2FA(Matrix.Identity); node.parent = null; node.parent_id = 0xffff; node.hasNodeID = true; node.type = Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE; node.flags = res.nodes[0].flags; node.node_id = (ushort)(res.meshes.Count() - 1); node.name = name; res.nodes.Add(node); }
static void kfdata_write(Lib3dsFile file, Lib3dsIo io) { if (file.nodes.Count == 0) { return; } Lib3dsChunk c_kfdata = new Lib3dsChunk(); c_kfdata.chunk = Lib3dsChunks.CHK_KFDATA; lib3ds_chunk_write_start(c_kfdata, io); { // ---- LIB3DS_KFHDR ---- Lib3dsChunk c = new Lib3dsChunk(); c.chunk = Lib3dsChunks.CHK_KFHDR; c.size = 6 + 2 + (uint)file.name.Length + 1 + 4; lib3ds_chunk_write(c, io); lib3ds_io_write_intw(io, (short)file.keyf_revision); lib3ds_io_write_string(io, file.name); lib3ds_io_write_intd(io, file.frames); } { // ---- LIB3DS_KFSEG ---- Lib3dsChunk c = new Lib3dsChunk(); c.chunk = Lib3dsChunks.CHK_KFSEG; c.size = 14; lib3ds_chunk_write(c, io); lib3ds_io_write_intd(io, file.segment_from); lib3ds_io_write_intd(io, file.segment_to); } { // ---- LIB3DS_KFCURTIME ---- Lib3dsChunk c = new Lib3dsChunk(); c.chunk = Lib3dsChunks.CHK_KFCURTIME; c.size = 10; lib3ds_chunk_write(c, io); lib3ds_io_write_intd(io, file.current_frame); } lib3ds_viewport_write(file.viewport_keyf, io); ushort default_id = 0; nodes_write(file.nodes, ref default_id, 65535, io); lib3ds_chunk_write_end(c_kfdata, io); }
public static void lib3ds_file_bounding_box_of_nodes(Lib3dsFile file, bool include_meshes, bool include_cameras, bool include_lights, float[] bmin, float[] bmax, float[,] matrix) { float[,] M = new float[4, 4]; if (matrix != null) { lib3ds_matrix_copy(M, matrix); } else { lib3ds_matrix_identity(M); } bmin[0] = bmin[1] = bmin[2] = float.MaxValue; bmax[0] = bmax[1] = bmax[2] = -float.MaxValue; foreach (Lib3dsNode p in file.nodes) { file_bounding_box_of_nodes_impl(p, file, include_meshes, include_cameras, include_lights, bmin, bmax, M); } }
public static void lib3ds_file_bounding_box_of_objects(Lib3dsFile file, bool include_meshes, bool include_cameras, bool include_lights, float[] bmin, float[] bmax) { bmin[0] = bmin[1] = bmin[2] = float.MaxValue; bmax[0] = bmax[1] = bmax[2] = -float.MaxValue; if (include_meshes) { float[] lmin = new float[3], lmax = new float[3]; foreach (Lib3dsMesh mesh in file.meshes) { lib3ds_mesh_bounding_box(mesh, lmin, lmax); lib3ds_vector_min(bmin, lmin); lib3ds_vector_max(bmax, lmax); } } if (include_cameras) { foreach (Lib3dsCamera camera in file.cameras) { lib3ds_vector_min(bmin, camera.position); lib3ds_vector_max(bmax, camera.position); lib3ds_vector_min(bmin, camera.target); lib3ds_vector_max(bmax, camera.target); } } if (include_lights) { foreach (Lib3dsLight light in file.lights) { lib3ds_vector_min(bmin, light.position); lib3ds_vector_max(bmax, light.position); if (light.spot_light) { lib3ds_vector_min(bmin, light.target); lib3ds_vector_max(bmax, light.target); } } } }
public static Lib3dsFile lib3ds_file_open(string filename, log_func log_func) { try { FileStream f = File.Open(filename, FileMode.Open, FileAccess.Read); try { Lib3dsIo io = new Lib3dsIo(); io.self = f; io.seek_func = fileio_seek_func; io.tell_func = fileio_tell_func; io.read_func = fileio_read_func; io.write_func = fileio_write_func; io.log_func = log_func; Lib3dsFile file = lib3ds_file_new(); if (file == null) { return(null); } if (!lib3ds_file_read(file, io)) { return(null); } return(file); } finally { f.Close(); } } catch { return(null); } }
static void ambient_read(Lib3dsFile file, Lib3dsIo io) { Lib3dsChunk c = new Lib3dsChunk(); Lib3dsChunks chunk; bool have_lin = false; lib3ds_chunk_read_start(c, Lib3dsChunks.CHK_AMBIENT_LIGHT, io); while ((chunk = lib3ds_chunk_read_next(c, io)) != 0) { switch (chunk) { case Lib3dsChunks.CHK_LIN_COLOR_F: for (int i = 0; i < 3; i++) { file.ambient[i] = lib3ds_io_read_float(io); } have_lin = true; break; case Lib3dsChunks.CHK_COLOR_F: // gamma corrected color chunk // replaced in 3ds R3 by LIN_COLOR_24 if (!have_lin) { for (int i = 0; i < 3; i++) { file.ambient[i] = lib3ds_io_read_float(io); } } break; default: lib3ds_chunk_unknown(chunk, io); break; } } lib3ds_chunk_read_end(c, io); }
// Creates and returns a new, empty Lib3dsFile object. // // \return A pointer to the Lib3dsFile structure. // If the structure cannot be allocated, NULL is returned. public static Lib3dsFile lib3ds_file_new() { try { Lib3dsFile file = new Lib3dsFile(); file.mesh_version = 3; file.master_scale = 1.0f; file.keyf_revision = 5; file.name = "LIB3DS"; file.frames = 100; file.segment_from = 0; file.segment_to = 100; file.current_frame = 0; return(file); } catch { return(null); } }
public static void lib3ds_file_remove_light(Lib3dsFile file, int index) { Debug.Assert(file!=null); file.lights.RemoveAt(index); }
public static void lib3ds_file_insert_light(Lib3dsFile file, Lib3dsLight light, int index) { Debug.Assert(file!=null); if(index<0) file.lights.Add(light); else file.lights.Insert(index, light); }
static void face_array_read(Lib3dsFile file, Lib3dsMesh mesh, Lib3dsIo io) { Lib3dsChunk c = new Lib3dsChunk(); Lib3dsChunks chunk; lib3ds_chunk_read_start(c, Lib3dsChunks.CHK_FACE_ARRAY, io); lib3ds_mesh_resize_faces(mesh, 0); ushort nfaces = lib3ds_io_read_word(io); if (nfaces != 0) { lib3ds_mesh_resize_faces(mesh, nfaces); for (int i = 0; i < nfaces; i++) { mesh.faces[i].index[0] = lib3ds_io_read_word(io); mesh.faces[i].index[1] = lib3ds_io_read_word(io); mesh.faces[i].index[2] = lib3ds_io_read_word(io); mesh.faces[i].flags = lib3ds_io_read_word(io); } lib3ds_chunk_read_tell(c, io); while ((chunk = lib3ds_chunk_read_next(c, io)) != 0) { switch (chunk) { case Lib3dsChunks.CHK_MSH_MAT_GROUP: string name = lib3ds_io_read_string(io, 64); int material = lib3ds_file_material_by_name(file, name); ushort n = lib3ds_io_read_word(io); for (int i = 0; i < n; i++) { ushort index = lib3ds_io_read_word(io); if (index < mesh.nfaces) { mesh.faces[index].material = material; } else { // TODO warning } } break; case Lib3dsChunks.CHK_SMOOTH_GROUP: for (int i = 0; i < mesh.nfaces; i++) { mesh.faces[i].smoothing_group = lib3ds_io_read_dword(io); } break; case Lib3dsChunks.CHK_MSH_BOXMAP: mesh.box_front = lib3ds_io_read_string(io, 64); mesh.box_back = lib3ds_io_read_string(io, 64); mesh.box_left = lib3ds_io_read_string(io, 64); mesh.box_right = lib3ds_io_read_string(io, 64); mesh.box_top = lib3ds_io_read_string(io, 64); mesh.box_bottom = lib3ds_io_read_string(io, 64); break; default: lib3ds_chunk_unknown(chunk, io); break; } } } lib3ds_chunk_read_end(c, io); }
static void file_minmax_node_id_impl(Lib3dsFile file, Lib3dsNode node, ref ushort min_id, ref ushort max_id) { if(min_id>node.node_id) min_id=node.node_id; if(max_id<node.node_id) max_id=node.node_id; foreach(Lib3dsNode p in node.childs) file_minmax_node_id_impl(file, p, ref min_id, ref max_id); }
public static void lib3ds_file_insert_node(Lib3dsFile file, Lib3dsNode node, Lib3dsNode before) { Debug.Assert(file!=null); Debug.Assert(node!=null); if(before!=null) { List<Lib3dsNode> list=before.parent!=null?before.parent.childs:file.nodes; Debug.Assert(list.Count!=0); int index=list.IndexOf(before); if(index>=0) list.Insert(index, node); else list.Add(node); node.parent=before.parent; } else { file.nodes.Insert(0, node); node.parent=null; } }
// Return a node object by id. // // This function performs a recursive search for the specified node. // // \param file The Lib3dsFile to be searched. // \param node_id The target node id. // // \return A pointer to the first matching node, or NULL if not found. // // \see lib3ds_node_by_id public static Lib3dsNode lib3ds_file_node_by_id(Lib3dsFile file, ushort node_id) { Debug.Assert(file!=null); foreach(Lib3dsNode p in file.nodes) { if(p.node_id==node_id) return p; Lib3dsNode q=lib3ds_node_by_id(p, node_id); if(q!=null) return q; } return null; }
public static Lib3dsMesh lib3ds_file_mesh_for_node(Lib3dsFile file, Lib3dsNode node) { if(node.type!=Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE) return null; //Lib3dsMeshInstanceNode n=(Lib3dsMeshInstanceNode)node; int index=lib3ds_file_mesh_by_name(file, node.name); return (index>=0)?file.meshes[index]:null; }
public static void lib3ds_file_remove_mesh(Lib3dsFile file, int index) { Debug.Assert(file!=null); file.meshes.RemoveAt(index); }
public static void lib3ds_file_reserve_meshes(Lib3dsFile file, int size, bool force) { Debug.Assert(file!=null); // nix }
public MyObject(Lib3dsMesh _node, Lib3dsFile _model) { this.node = _node; this.model = _model; if (_node.faces == null || _node.faces.Count == 0) { this.Flag = false; } else { this.Flag = true; this.Normalizes = new Lib3dsVertex[_node.faces.Count]; for (int i = 0; i < _node.faces.Count; i++) { Lib3dsFace face = _node.faces[i]; Lib3dsVertex Point1 = _node.vertices[face.index[0]]; Lib3dsVertex Point2 = _node.vertices[face.index[1]]; Lib3dsVertex Point3 = _node.vertices[face.index[2]]; this.Normalizes[i] = CreateNormalize(Point1, Point2, Point3); } } }
public void Export3DS(Lib3dsFile f, Matrix m) { try { PSKFile p = ExportToPsk(); Helper3DS.AddMeshTo3DS(f, p, m); } catch (Exception e) { DebugOutput.PrintLn("Export to 3ds ERROR: in\"" + MyName + "\" " + e.Message); } }
static void face_array_write(Lib3dsFile file, Lib3dsMesh mesh, Lib3dsIo io) { if (mesh.nfaces == 0) { return; } Lib3dsChunk c_face_array = new Lib3dsChunk(); c_face_array.chunk = Lib3dsChunks.CHK_FACE_ARRAY; lib3ds_chunk_write_start(c_face_array, io); lib3ds_io_write_word(io, mesh.nfaces); for (int 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 = new Lib3dsChunk(); ushort num; bool[] matf = new bool[mesh.nfaces]; for (ushort i = 0; i < mesh.nfaces; i++) { if (!matf[i] && (mesh.faces[i].material >= 0) && (mesh.faces[i].material < file.materials.Count)) { matf[i] = true; num = 1; for (ushort j = (ushort)(i + 1); j < mesh.nfaces; j++) { if (mesh.faces[i].material == mesh.faces[j].material) { num++; } } c.chunk = Lib3dsChunks.CHK_MSH_MAT_GROUP; c.size = (uint)(6 + file.materials[mesh.faces[i].material].name.Length + 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, i); for (ushort j = (ushort)(i + 1); j < mesh.nfaces; j++) { if (mesh.faces[i].material == mesh.faces[j].material) { lib3ds_io_write_word(io, j); matf[j] = true; } } } } } { // ---- SMOOTH_GROUP ---- Lib3dsChunk c = new Lib3dsChunk(); c.chunk = Lib3dsChunks.CHK_SMOOTH_GROUP; c.size = 6 + 4u * mesh.nfaces; lib3ds_chunk_write(c, io); for (int i = 0; i < mesh.nfaces; i++) { lib3ds_io_write_dword(io, mesh.faces[i].smoothing_group); } } if (mesh.box_front.Length > 0 || mesh.box_back.Length > 0 || mesh.box_left.Length > 0 || mesh.box_right.Length > 0 || mesh.box_top.Length > 0 || mesh.box_bottom.Length > 0) { // ---- MSH_BOXMAP ---- Lib3dsChunk c = new Lib3dsChunk(); c.chunk = Lib3dsChunks.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_face_array, io); }
public static void lib3ds_file_reserve_meshes(Lib3dsFile file, int size, bool force) { Debug.Assert(file != null); // nix }
public static void lib3ds_file_insert_mesh(Lib3dsFile file, Lib3dsMesh mesh, int index) { Debug.Assert(file!=null); if(index<0) file.meshes.Add(mesh); else file.meshes.Insert(index, mesh); }
// Read 3ds file data into a Lib3dsFile object. // // \param file The Lib3dsFile object to be filled. // \param io A Lib3dsIo object previously set up by the caller. // // \return true on success, false on failure. public static bool lib3ds_file_read(Lib3dsFile file, Lib3dsIo io) { Lib3dsChunk c=new Lib3dsChunk(); Lib3dsChunks chunk; lib3ds_io_setup(io); try { lib3ds_chunk_read_start(c, 0, io); switch(c.chunk) { case Lib3dsChunks.CHK_MDATA: lib3ds_chunk_read_reset(c, io); mdata_read(file, io); break; case Lib3dsChunks.CHK_M3DMAGIC: case Lib3dsChunks.CHK_MLIBMAGIC: case Lib3dsChunks.CHK_CMAGIC: while((chunk=lib3ds_chunk_read_next(c, io))!=0) { switch(chunk) { case Lib3dsChunks.CHK_M3D_VERSION: file.mesh_version=lib3ds_io_read_dword(io); break; case Lib3dsChunks.CHK_MDATA: lib3ds_chunk_read_reset(c, io); mdata_read(file, io); break; case Lib3dsChunks.CHK_KFDATA: lib3ds_chunk_read_reset(c, io); kfdata_read(file, io); break; default: lib3ds_chunk_unknown(chunk, io); break; } } break; default: lib3ds_chunk_unknown(c.chunk, io); return false; } lib3ds_chunk_read_end(c, io); lib3ds_io_cleanup(io); return true; } catch { lib3ds_io_cleanup(io); return false; } }
public static int lib3ds_file_mesh_by_name(Lib3dsFile file, string name) { Debug.Assert(file!=null); for(int i=0; i<file.meshes.Count; i++) if(file.meshes[i].name==name) return i; return -1; }
static void mdata_write(Lib3dsFile file, Lib3dsIo io) { Lib3dsChunk c_mdata=new Lib3dsChunk(); c_mdata.chunk=Lib3dsChunks.CHK_MDATA; lib3ds_chunk_write_start(c_mdata, io); { // ---- LIB3DS_MESH_VERSION ---- Lib3dsChunk c=new Lib3dsChunk(); c.chunk=Lib3dsChunks.CHK_MESH_VERSION; c.size=10; lib3ds_chunk_write(c, io); lib3ds_io_write_intd(io, (int)file.mesh_version); } { // ---- LIB3DS_MASTER_SCALE ---- Lib3dsChunk c=new Lib3dsChunk(); c.chunk=Lib3dsChunks.CHK_MASTER_SCALE; c.size=10; lib3ds_chunk_write(c, io); lib3ds_io_write_float(io, file.master_scale); } { // ---- LIB3DS_O_CONSTS ---- int i; for(i=0; i<3; i++) if(Math.Abs(file.construction_plane[i])>EPSILON) break; if(i<3) { Lib3dsChunk c=new Lib3dsChunk(); c.chunk=Lib3dsChunks.CHK_O_CONSTS; c.size=18; lib3ds_chunk_write(c, io); lib3ds_io_write_vector(io, file.construction_plane); } } { // ---- LIB3DS_AMBIENT_LIGHT ---- int i; for(i=0; i<3; i++) if(Math.Abs(file.ambient[i])>EPSILON) break; if(i<3) { Lib3dsChunk c=new Lib3dsChunk(); c.chunk=Lib3dsChunks.CHK_AMBIENT_LIGHT; c.size=42; lib3ds_chunk_write(c, io); colorf_write(file.ambient, io); } } lib3ds_background_write(file.background, io); lib3ds_atmosphere_write(file.atmosphere, io); lib3ds_shadow_write(file.shadow, io); lib3ds_viewport_write(file.viewport, io); { foreach(Lib3dsMaterial material in file.materials) lib3ds_material_write(material, io); } { Lib3dsChunk c=new Lib3dsChunk(); foreach(Lib3dsCamera camera in file.cameras) { c.chunk=Lib3dsChunks.CHK_NAMED_OBJECT; lib3ds_chunk_write_start(c, io); lib3ds_io_write_string(io, camera.name); lib3ds_camera_write(camera, io); object_flags_write(camera.object_flags, io); lib3ds_chunk_write_end(c, io); } } { Lib3dsChunk c=new Lib3dsChunk(); foreach(Lib3dsLight light in file.lights) { c.chunk=Lib3dsChunks.CHK_NAMED_OBJECT; lib3ds_chunk_write_start(c, io); lib3ds_io_write_string(io, light.name); lib3ds_light_write(light, io); object_flags_write(light.object_flags, io); lib3ds_chunk_write_end(c, io); } } { Lib3dsChunk c=new Lib3dsChunk(); foreach(Lib3dsMesh mesh in file.meshes) { c.chunk=Lib3dsChunks.CHK_NAMED_OBJECT; lib3ds_chunk_write_start(c, io); lib3ds_io_write_string(io, mesh.name); lib3ds_mesh_write(file, mesh, io); object_flags_write(mesh.object_flags, io); lib3ds_chunk_write_end(c, io); } } lib3ds_chunk_write_end(c_mdata, io); }
// Return a node object by name and type. // // This function performs a recursive search for the specified node. // Both name and type must match. // // \param file The Lib3dsFile to be searched. // \param name The target node name. // \param type The target node type // // \return A pointer to the first matching node, or NULL if not found. // // \see lib3ds_node_by_name public static Lib3dsNode lib3ds_file_node_by_name(Lib3dsFile file, string name, Lib3dsNodeType type) { Debug.Assert(file!=null); foreach(Lib3dsNode p in file.nodes) { if(p.type==type&&p.name==name) return p; Lib3dsNode q=lib3ds_node_by_name(p, name, type); if(q!=null) return q; } return null; }
static void kfdata_write(Lib3dsFile file, Lib3dsIo io) { if(file.nodes.Count==0) return; Lib3dsChunk c_kfdata=new Lib3dsChunk(); c_kfdata.chunk=Lib3dsChunks.CHK_KFDATA; lib3ds_chunk_write_start(c_kfdata, io); { // ---- LIB3DS_KFHDR ---- Lib3dsChunk c=new Lib3dsChunk(); c.chunk=Lib3dsChunks.CHK_KFHDR; c.size=6+2+(uint)file.name.Length+1+4; lib3ds_chunk_write(c, io); lib3ds_io_write_intw(io, (short)file.keyf_revision); lib3ds_io_write_string(io, file.name); lib3ds_io_write_intd(io, file.frames); } { // ---- LIB3DS_KFSEG ---- Lib3dsChunk c=new Lib3dsChunk(); c.chunk=Lib3dsChunks.CHK_KFSEG; c.size=14; lib3ds_chunk_write(c, io); lib3ds_io_write_intd(io, file.segment_from); lib3ds_io_write_intd(io, file.segment_to); } { // ---- LIB3DS_KFCURTIME ---- Lib3dsChunk c=new Lib3dsChunk(); c.chunk=Lib3dsChunks.CHK_KFCURTIME; c.size=10; lib3ds_chunk_write(c, io); lib3ds_io_write_intd(io, file.current_frame); } lib3ds_viewport_write(file.viewport_keyf, io); ushort default_id=0; nodes_write(file.nodes, ref default_id, 65535, io); lib3ds_chunk_write_end(c_kfdata, io); }
public static void lib3ds_file_append_node(Lib3dsFile file, Lib3dsNode node, Lib3dsNode parent) { Debug.Assert(file!=null); Debug.Assert(node!=null); List<Lib3dsNode> list=parent!=null?parent.childs:file.nodes; list.Add(node); node.parent=parent; }
// 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 true on success, false on failure. public static bool lib3ds_file_write(Lib3dsFile file, Lib3dsIo io) { Lib3dsChunk c=new Lib3dsChunk(); lib3ds_io_setup(io); try { c.chunk=Lib3dsChunks.CHK_M3DMAGIC; lib3ds_chunk_write_start(c, io); // ---- LIB3DS_M3D_VERSION ---- Lib3dsChunk c_version=new Lib3dsChunk(); c_version.chunk=Lib3dsChunks.CHK_M3D_VERSION; c_version.size=10; lib3ds_chunk_write(c_version, io); lib3ds_io_write_dword(io, file.mesh_version); mdata_write(file, io); kfdata_write(file, io); lib3ds_chunk_write_end(c, io); lib3ds_io_cleanup(io); return true; } catch { lib3ds_io_cleanup(io); return false; } }
// Remove a node from the a Lib3dsFile object. // // \param file The Lib3dsFile object to be modified. // \param node The Lib3dsNode object to be removed from file public static void lib3ds_file_remove_node(Lib3dsFile file, Lib3dsNode node) { if(node.parent!=null) node.parent.childs.Remove(node); else file.nodes.Remove(node); }
public static void lib3ds_file_insert_material(Lib3dsFile file, Lib3dsMaterial material, int index) { Debug.Assert(file!=null); if(index<0) file.materials.Add(material); else file.materials.Insert(index, material); }
public static void lib3ds_file_minmax_node_id(Lib3dsFile file, ref ushort min_id, ref ushort max_id) { min_id=65535; max_id=0; foreach(Lib3dsNode p in file.nodes) file_minmax_node_id_impl(file, p, ref min_id, ref max_id); }
public static void lib3ds_file_insert_camera(Lib3dsFile file, Lib3dsCamera camera, int index) { Debug.Assert(file!=null); if(index<0) file.cameras.Add(camera); else file.cameras.Insert(index, camera); }
public static void lib3ds_mesh_read(Lib3dsFile file, Lib3dsMesh mesh, Lib3dsIo io) { Lib3dsChunk c = new Lib3dsChunk(); Lib3dsChunks chunk; lib3ds_chunk_read_start(c, Lib3dsChunks.CHK_N_TRI_OBJECT, io); while ((chunk = lib3ds_chunk_read_next(c, io)) != 0) { switch (chunk) { case Lib3dsChunks.CHK_MESH_MATRIX: lib3ds_matrix_identity(mesh.matrix); for (int i = 0; i < 4; i++) { for (int j = 0; j < 3; j++) { mesh.matrix[i, j] = lib3ds_io_read_float(io); } } break; case Lib3dsChunks.CHK_MESH_COLOR: mesh.color = lib3ds_io_read_byte(io); break; case Lib3dsChunks.CHK_POINT_ARRAY: { ushort nvertices = lib3ds_io_read_word(io); lib3ds_mesh_resize_vertices(mesh, nvertices, mesh.texcos != null, mesh.vflags != null); for (int i = 0; i < mesh.nvertices; i++) { lib3ds_io_read_vector(io, mesh.vertices[i]); } } break; case Lib3dsChunks.CHK_POINT_FLAG_ARRAY: { ushort nflags = lib3ds_io_read_word(io); ushort nvertices = (mesh.nvertices >= nflags)?mesh.nvertices:nflags; lib3ds_mesh_resize_vertices(mesh, nvertices, mesh.texcos != null, true); for (int i = 0; i < nflags; i++) { mesh.vflags[i] = lib3ds_io_read_word(io); } } break; case Lib3dsChunks.CHK_FACE_ARRAY: lib3ds_chunk_read_reset(c, io); face_array_read(file, mesh, io); break; case Lib3dsChunks.CHK_MESH_TEXTURE_INFO: //FIXME: mesh.map_type = lib3ds_io_read_word(io); for (int i = 0; i < 2; i++) { mesh.map_tile[i] = lib3ds_io_read_float(io); } for (int i = 0; i < 3; i++) { mesh.map_pos[i] = lib3ds_io_read_float(io); } mesh.map_scale = lib3ds_io_read_float(io); lib3ds_matrix_identity(mesh.map_matrix); for (int i = 0; i < 4; i++) { for (int j = 0; j < 3; j++) { mesh.map_matrix[i, j] = lib3ds_io_read_float(io); } } for (int i = 0; i < 2; i++) { mesh.map_planar_size[i] = lib3ds_io_read_float(io); } mesh.map_cylinder_height = lib3ds_io_read_float(io); break; case Lib3dsChunks.CHK_TEX_VERTS: { ushort ntexcos = lib3ds_io_read_word(io); ushort nvertices = (mesh.nvertices >= ntexcos)?mesh.nvertices:ntexcos; if (mesh.texcos == null) { lib3ds_mesh_resize_vertices(mesh, nvertices, true, mesh.vflags != null); } for (int i = 0; i < ntexcos; i++) { mesh.texcos[i].s = lib3ds_io_read_float(io); mesh.texcos[i].t = lib3ds_io_read_float(io); } break; } default: lib3ds_chunk_unknown(chunk, io); break; } } if (lib3ds_matrix_det(mesh.matrix) < 0.0) { // Flip X coordinate of vertices if mesh matrix has negative determinant float[,] inv_matrix = new float[4, 4], M = new float[4, 4]; float[] tmp = new float[3]; lib3ds_matrix_copy(inv_matrix, mesh.matrix); lib3ds_matrix_inv(inv_matrix); lib3ds_matrix_copy(M, mesh.matrix); lib3ds_matrix_scale(M, -1.0f, 1.0f, 1.0f); lib3ds_matrix_mult(M, M, inv_matrix); for (int i = 0; i < mesh.nvertices; i++) { lib3ds_vector_transform(tmp, M, mesh.vertices[i]); lib3ds_vector_copy(mesh.vertices[i], tmp); } } lib3ds_chunk_read_end(c, io); }
public static void lib3ds_file_remove_camera(Lib3dsFile file, int index) { Debug.Assert(file!=null); file.cameras.RemoveAt(index); }
public static void lib3ds_mesh_write(Lib3dsFile file, Lib3dsMesh mesh, Lib3dsIo io) { Lib3dsChunk c_n_tri_object = new Lib3dsChunk(); c_n_tri_object.chunk = Lib3dsChunks.CHK_N_TRI_OBJECT; lib3ds_chunk_write_start(c_n_tri_object, io); point_array_write(mesh, io); texco_array_write(mesh, io); if (mesh.map_type != Lib3dsMapType.LIB3DS_MAP_NONE) { // ---- LIB3DS_MESH_TEXTURE_INFO ---- Lib3dsChunk c = new Lib3dsChunk(); c.chunk = Lib3dsChunks.CHK_MESH_TEXTURE_INFO; c.size = 92; lib3ds_chunk_write(c, io); lib3ds_io_write_word(io, (ushort)mesh.map_type); for (int i = 0; i < 2; i++) { lib3ds_io_write_float(io, mesh.map_tile[i]); } lib3ds_io_write_vector(io, mesh.map_pos); lib3ds_io_write_float(io, mesh.map_scale); for (int i = 0; i < 4; i++) { for (int j = 0; j < 3; j++) { lib3ds_io_write_float(io, mesh.map_matrix[i, j]); } } for (int i = 0; i < 2; i++) { lib3ds_io_write_float(io, mesh.map_planar_size[i]); } lib3ds_io_write_float(io, mesh.map_cylinder_height); } flag_array_write(mesh, io); { /*---- LIB3DS_MESH_MATRIX ----*/ Lib3dsChunk c = new Lib3dsChunk(); c.chunk = Lib3dsChunks.CHK_MESH_MATRIX; c.size = 54; lib3ds_chunk_write(c, io); for (int i = 0; i < 4; i++) { for (int j = 0; j < 3; j++) { lib3ds_io_write_float(io, mesh.matrix[i, j]); } } } if (mesh.color != 0) { // ---- LIB3DS_MESH_COLOR ---- Lib3dsChunk c = new Lib3dsChunk(); c.chunk = Lib3dsChunks.CHK_MESH_COLOR; c.size = 7; lib3ds_chunk_write(c, io); lib3ds_io_write_byte(io, mesh.color); } face_array_write(file, mesh, io); lib3ds_chunk_write_end(c_n_tri_object, io); }
static void ambient_read(Lib3dsFile file, Lib3dsIo io) { Lib3dsChunk c=new Lib3dsChunk(); Lib3dsChunks chunk; bool have_lin=false; lib3ds_chunk_read_start(c, Lib3dsChunks.CHK_AMBIENT_LIGHT, io); while((chunk=lib3ds_chunk_read_next(c, io))!=0) { switch(chunk) { case Lib3dsChunks.CHK_LIN_COLOR_F: for(int i=0; i<3; i++) file.ambient[i]=lib3ds_io_read_float(io); have_lin=true; break; case Lib3dsChunks.CHK_COLOR_F: // gamma corrected color chunk // replaced in 3ds R3 by LIN_COLOR_24 if(!have_lin) { for(int i=0; i<3; i++) file.ambient[i]=lib3ds_io_read_float(io); } break; default: lib3ds_chunk_unknown(chunk, io); break; } } lib3ds_chunk_read_end(c, io); }
// Function : open 3DS file. // Description : use locale::global to make sure we can read file from the path. // Input : 3DS file's path. // Output : nothing. public void OpenFile(string FileRoad) { OpenGL gl = new OpenGL(); MyModel = LIB3DS.lib3ds_file_open(FileRoad);//モデルデータ読み込み if (MyModel == null) { Console.WriteLine("Read 3DS file error!"); return; } }
static void mdata_read(Lib3dsFile file, Lib3dsIo io) { Lib3dsChunk c=new Lib3dsChunk(); Lib3dsChunks chunk; lib3ds_chunk_read_start(c, Lib3dsChunks.CHK_MDATA, io); while((chunk=lib3ds_chunk_read_next(c, io))!=0) { switch(chunk) { case Lib3dsChunks.CHK_MESH_VERSION: file.mesh_version=lib3ds_io_read_dword(io); break; case Lib3dsChunks.CHK_MASTER_SCALE: file.master_scale=lib3ds_io_read_float(io); break; case Lib3dsChunks.CHK_SHADOW_MAP_SIZE: case Lib3dsChunks.CHK_LO_SHADOW_BIAS: case Lib3dsChunks.CHK_HI_SHADOW_BIAS: case Lib3dsChunks.CHK_SHADOW_SAMPLES: case Lib3dsChunks.CHK_SHADOW_RANGE: case Lib3dsChunks.CHK_SHADOW_FILTER: case Lib3dsChunks.CHK_RAY_BIAS: lib3ds_chunk_read_reset(c, io); lib3ds_shadow_read(file.shadow, io); break; case Lib3dsChunks.CHK_VIEWPORT_LAYOUT: case Lib3dsChunks.CHK_DEFAULT_VIEW: lib3ds_chunk_read_reset(c, io); lib3ds_viewport_read(file.viewport, io); break; case Lib3dsChunks.CHK_O_CONSTS: for(int i=0; i<3; i++) file.construction_plane[i]=lib3ds_io_read_float(io); break; case Lib3dsChunks.CHK_AMBIENT_LIGHT: lib3ds_chunk_read_reset(c, io); ambient_read(file, io); break; case Lib3dsChunks.CHK_BIT_MAP: case Lib3dsChunks.CHK_SOLID_BGND: case Lib3dsChunks.CHK_V_GRADIENT: case Lib3dsChunks.CHK_USE_BIT_MAP: case Lib3dsChunks.CHK_USE_SOLID_BGND: case Lib3dsChunks.CHK_USE_V_GRADIENT: lib3ds_chunk_read_reset(c, io); lib3ds_background_read(file.background, io); break; case Lib3dsChunks.CHK_FOG: case Lib3dsChunks.CHK_LAYER_FOG: case Lib3dsChunks.CHK_DISTANCE_CUE: case Lib3dsChunks.CHK_USE_FOG: case Lib3dsChunks.CHK_USE_LAYER_FOG: case Lib3dsChunks.CHK_USE_DISTANCE_CUE: lib3ds_chunk_read_reset(c, io); lib3ds_atmosphere_read(file.atmosphere, io); break; case Lib3dsChunks.CHK_MAT_ENTRY: Lib3dsMaterial material=lib3ds_material_new(null); lib3ds_file_insert_material(file, material, -1); lib3ds_chunk_read_reset(c, io); lib3ds_material_read(material, io); break; case Lib3dsChunks.CHK_NAMED_OBJECT: lib3ds_chunk_read_reset(c, io); named_object_read(file, io); break; default: lib3ds_chunk_unknown(chunk, io); break; } } lib3ds_chunk_read_end(c, io); }
public void Export3DS(Lib3dsFile f) { foreach (StaticMeshCollectionActor stmca in STM_CA) stmca.Export3DS(f); foreach (StaticMeshActor stma in STM_A) stma.Export3DS(f); foreach (InterpActor ia in IA) ia.Export3DS(f); }
static void kfdata_read(Lib3dsFile file, Lib3dsIo io) { Lib3dsChunk c=new Lib3dsChunk(); Lib3dsChunks chunk; lib3ds_chunk_read_start(c, Lib3dsChunks.CHK_KFDATA, io); while((chunk=lib3ds_chunk_read_next(c, io))!=0) { switch(chunk) { case Lib3dsChunks.CHK_KFHDR: file.keyf_revision=lib3ds_io_read_word(io); file.name=lib3ds_io_read_string(io, 12+1); file.frames=lib3ds_io_read_intd(io); break; case Lib3dsChunks.CHK_KFSEG: file.segment_from=lib3ds_io_read_intd(io); file.segment_to=lib3ds_io_read_intd(io); break; case Lib3dsChunks.CHK_KFCURTIME: file.current_frame=lib3ds_io_read_intd(io); break; case Lib3dsChunks.CHK_VIEWPORT_LAYOUT: case Lib3dsChunks.CHK_DEFAULT_VIEW: lib3ds_chunk_read_reset(c, io); lib3ds_viewport_read(file.viewport_keyf, io); break; case Lib3dsChunks.CHK_AMBIENT_NODE_TAG: case Lib3dsChunks.CHK_OBJECT_NODE_TAG: case Lib3dsChunks.CHK_CAMERA_NODE_TAG: case Lib3dsChunks.CHK_TARGET_NODE_TAG: case Lib3dsChunks.CHK_LIGHT_NODE_TAG: case Lib3dsChunks.CHK_SPOTLIGHT_NODE_TAG: case Lib3dsChunks.CHK_L_TARGET_NODE_TAG: Lib3dsNodeType type; switch(chunk) { case Lib3dsChunks.CHK_AMBIENT_NODE_TAG: type=Lib3dsNodeType.LIB3DS_NODE_AMBIENT_COLOR; break; case Lib3dsChunks.CHK_OBJECT_NODE_TAG: type=Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE; break; case Lib3dsChunks.CHK_CAMERA_NODE_TAG: type=Lib3dsNodeType.LIB3DS_NODE_CAMERA; break; case Lib3dsChunks.CHK_TARGET_NODE_TAG: type=Lib3dsNodeType.LIB3DS_NODE_CAMERA_TARGET; break; case Lib3dsChunks.CHK_LIGHT_NODE_TAG: type=Lib3dsNodeType.LIB3DS_NODE_OMNILIGHT; break; case Lib3dsChunks.CHK_SPOTLIGHT_NODE_TAG: type=Lib3dsNodeType.LIB3DS_NODE_SPOTLIGHT; break; case Lib3dsChunks.CHK_L_TARGET_NODE_TAG: type=Lib3dsNodeType.LIB3DS_NODE_SPOTLIGHT_TARGET; break; default: throw new Exception("Unknown chunk type."); } Lib3dsNode node=lib3ds_node_new(type); file.nodes.Add(node); lib3ds_chunk_read_reset(c, io); lib3ds_node_read(node, io); break; default: lib3ds_chunk_unknown(chunk, io); break; } } // fehlende Node IDs vergeben List<Lib3dsNode> missingIDs=new List<Lib3dsNode>(); Dictionary<ushort, Lib3dsNode> hasIDs=new Dictionary<ushort, Lib3dsNode>(); foreach(Lib3dsNode node in file.nodes) { if(!node.hasNodeID) missingIDs.Add(node); else if(!hasIDs.ContainsKey(node.node_id)) hasIDs.Add(node.node_id, node); } ushort num_nodes=0; foreach(Lib3dsNode node in missingIDs) { while(hasIDs.ContainsKey(num_nodes)) { num_nodes++; if(num_nodes==65535) throw new Exception("Out of IDs."); } node.node_id=num_nodes; node.hasNodeID=true; hasIDs.Add(num_nodes, node); num_nodes++; if(num_nodes==65535) throw new Exception("Out of IDs."); } missingIDs.Clear(); foreach(Lib3dsNode node in file.nodes) { if(node.parent_id!=65535&&hasIDs.ContainsKey(node.parent_id)) { Lib3dsNode parent=hasIDs[node.parent_id]; parent.childs.Add(node); node.parent=parent; } } lib3ds_chunk_read_end(c, io); }