public static void lib3ds_mesh_resize_faces(Lib3dsMesh mesh, ushort nfaces) { Debug.Assert(mesh != null); if (nfaces > 0) { if (mesh.faces == null) { mesh.faces = new List <Lib3dsFace>(); } while (mesh.faces.Count < nfaces) { mesh.faces.Add(new Lib3dsFace()); mesh.faces[mesh.faces.Count - 1].material = -1; } if (mesh.faces.Count > nfaces) { mesh.faces.RemoveRange(nfaces, mesh.faces.Count - nfaces); } } else { mesh.faces = null; } mesh.nfaces = nfaces; }
public static void lib3ds_mesh_resize_vertices(Lib3dsMesh mesh, ushort nvertices, bool use_texcos, bool use_flags) { Debug.Assert(mesh!=null); if(nvertices>0) { if(mesh.vertices==null) mesh.vertices=new List<Lib3dsVertex>(); while(mesh.vertices.Count<nvertices) mesh.vertices.Add(new Lib3dsVertex()); if(mesh.vertices.Count>nvertices) mesh.vertices.RemoveRange(nvertices, mesh.vertices.Count-nvertices); } else mesh.vertices=null; ushort tmp=(ushort)(use_texcos?nvertices:(ushort)0); if(tmp>0) { if(mesh.texcos==null) mesh.texcos=new List<Lib3dsTexturecoordinate>(); while(mesh.texcos.Count<tmp) mesh.texcos.Add(new Lib3dsTexturecoordinate()); if(mesh.texcos.Count>tmp) mesh.texcos.RemoveRange(tmp, mesh.texcos.Count-tmp); } else mesh.texcos=null; tmp=(ushort)(use_flags?nvertices:(ushort)0); if(tmp>0) { if(mesh.vflags==null) mesh.vflags=new List<ushort>(); while(mesh.vflags.Count<tmp) mesh.vflags.Add(0); if(mesh.vflags.Count>tmp) mesh.vflags.RemoveRange(tmp, mesh.vflags.Count-tmp); } else mesh.vflags=null; mesh.nvertices=nvertices; }
public static Lib3dsMeshInstanceNode lib3ds_node_new_mesh_instance(Lib3dsMesh mesh, string instance_name, float[] pos0, float[] scl0, float[] rot0) { Lib3dsNode node = lib3ds_node_new(Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE); if (mesh != null) { node.name = mesh.name; } else { node.name = "$$$DUMMY"; } Lib3dsMeshInstanceNode n = (Lib3dsMeshInstanceNode)node; if (instance_name != null) { n.instance_name = instance_name; } else { n.instance_name = ""; } lib3ds_track_resize(n.pos_track, 1); if (pos0 != null) { lib3ds_vector_copy(n.pos_track.keys[0].value, pos0); } lib3ds_track_resize(n.scl_track, 1); if (scl0 != null) { lib3ds_vector_copy(n.scl_track.keys[0].value, scl0); } else { lib3ds_vector_make(n.scl_track.keys[0].value, 1, 1, 1); } lib3ds_track_resize(n.rot_track, 1); if (rot0 != null) { for (int i = 0; i < 4; i++) { n.rot_track.keys[0].value[i] = rot0[i]; } } else { for (int i = 0; i < 4; i++) { n.rot_track.keys[0].value[i] = 0; } } return(n); }
// Find the bounding box of a mesh object. // // \param mesh The mesh object // \param bmin Returned bounding box // \param bmax Returned bounding box public static void lib3ds_mesh_bounding_box(Lib3dsMesh mesh, float[] bmin, float[] bmax) { bmin[0] = bmin[1] = bmin[2] = float.MaxValue; bmax[0] = bmax[1] = bmax[2] = -float.MaxValue; for (int i = 0; i < mesh.nvertices; i++) { lib3ds_vector_min(bmin, mesh.vertices[i]); lib3ds_vector_max(bmax, mesh.vertices[i]); } }
public static void lib3ds_mesh_calculate_face_normals(Lib3dsMesh mesh, float[][] face_normals) { if (mesh.nfaces == 0) { return; } for (int i = 0; i < mesh.nfaces; i++) { lib3ds_vector_normal(face_normals[i], mesh.vertices[mesh.faces[i].index[0]], mesh.vertices[mesh.faces[i].index[1]], mesh.vertices[mesh.faces[i].index[2]]); } }
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 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); }
// Create and return a new empty mesh object. // // Mesh is initialized with the name and an identity matrix; all // other fields are zero. // // See Lib3dsFaceFlag for definitions of per-face flags. // // \param name Mesh name. Must not be NULL. Must be < 64 characters. // // \return mesh object or NULL on error. public static Lib3dsMesh lib3ds_mesh_new(string name) { Debug.Assert(name != null); Debug.Assert(name.Length < 64); try { Lib3dsMesh mesh = new Lib3dsMesh(); mesh.name = name; lib3ds_matrix_identity(mesh.matrix); mesh.map_type = Lib3dsMapType.LIB3DS_MAP_NONE; return(mesh); } catch { return(null); } }
// Create and return a new empty mesh object. // // Mesh is initialized with the name and an identity matrix; all // other fields are zero. // // See Lib3dsFaceFlag for definitions of per-face flags. // // \param name Mesh name. Must not be NULL. Must be < 64 characters. // // \return mesh object or NULL on error. public static Lib3dsMesh lib3ds_mesh_new(string name) { Debug.Assert(name!=null); Debug.Assert(name.Length<64); try { Lib3dsMesh mesh=new Lib3dsMesh(); mesh.name=name; lib3ds_matrix_identity(mesh.matrix); mesh.map_type=Lib3dsMapType.LIB3DS_MAP_NONE; return mesh; } catch { return null; } }
public static void lib3ds_mesh_resize_faces(Lib3dsMesh mesh, ushort nfaces) { Debug.Assert(mesh!=null); if(nfaces>0) { if(mesh.faces==null) mesh.faces=new List<Lib3dsFace>(); while(mesh.faces.Count<nfaces) { mesh.faces.Add(new Lib3dsFace()); mesh.faces[mesh.faces.Count-1].material=-1; } if(mesh.faces.Count>nfaces) mesh.faces.RemoveRange(nfaces, mesh.faces.Count-nfaces); } else mesh.faces=null; mesh.nfaces=nfaces; }
static void flag_array_write(Lib3dsMesh mesh, Lib3dsIo io) { if (mesh.vflags == null) { return; } Lib3dsChunk c = new Lib3dsChunk(); c.chunk = Lib3dsChunks.CHK_POINT_FLAG_ARRAY; c.size = 8 + 2u * mesh.nvertices; lib3ds_chunk_write(c, io); lib3ds_io_write_word(io, mesh.nvertices); for (int i = 0; i < mesh.nvertices; i++) { lib3ds_io_write_word(io, mesh.vflags[i]); } }
static void texco_array_write(Lib3dsMesh mesh, Lib3dsIo io) { if (mesh.texcos == null) { return; } Lib3dsChunk c = new Lib3dsChunk(); c.chunk = Lib3dsChunks.CHK_TEX_VERTS; c.size = 8 + 8u * mesh.nvertices; lib3ds_chunk_write(c, io); lib3ds_io_write_word(io, mesh.nvertices); for (int i = 0; i < mesh.nvertices; i++) { lib3ds_io_write_float(io, mesh.texcos[i].s); lib3ds_io_write_float(io, mesh.texcos[i].t); } }
static void point_array_write(Lib3dsMesh mesh, Lib3dsIo io) { Lib3dsChunk c = new Lib3dsChunk(); c.chunk = Lib3dsChunks.CHK_POINT_ARRAY; c.size = 8 + 12u * mesh.nvertices; lib3ds_chunk_write(c, io); lib3ds_io_write_word(io, mesh.nvertices); if (lib3ds_matrix_det(mesh.matrix) >= 0.0f) { for (int i = 0; i < mesh.nvertices; i++) { lib3ds_io_write_vector(io, mesh.vertices[i]); } } else { // 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_io_write_vector(io, tmp); } } }
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 BuildingObjectLib3DS CreateBuildingModel() { BuildingObjectLib3DS Building; Hashtable Textures = new Hashtable(); Lib3dsMesh test = new Lib3dsMesh(); OpenGLControl openglCtr = new SharpGL.OpenGLControl(); foreach (Lib3dsMaterial material in MyModel.materials) { Texture texture = new Texture(); try { texture.Create(openglCtr.OpenGL, "..\\Model\\" + material.name + ".jpg"); Textures.Add(material.name, texture); } catch { // Do not find the texture file } } Building = new BuildingObjectLib3DS(null, BuildingObjectType.Building, 0, MyModel, Textures); foreach (Lib3dsMeshInstanceNode node in MyModel.nodes) { if (node.type != Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE || node.childs == null) continue; Building.AddNewChild(node); } return Building; }
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); }
static void named_object_read(Lib3dsFile file, Lib3dsIo io) { Lib3dsChunk c = new Lib3dsChunk(); string name; Lib3dsChunks chunk; Lib3dsMesh mesh = null; Lib3dsCamera camera = null; Lib3dsLight light = null; Lib3dsObjectFlags object_flags = 0; lib3ds_chunk_read_start(c, Lib3dsChunks.CHK_NAMED_OBJECT, io); name = lib3ds_io_read_string(io, 64); lib3ds_io_log(io, Lib3dsLogLevel.LIB3DS_LOG_INFO, "NAME={0}", name); lib3ds_chunk_read_tell(c, io); while ((chunk = lib3ds_chunk_read_next(c, io)) != 0) { switch (chunk) { case Lib3dsChunks.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 Lib3dsChunks.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 Lib3dsChunks.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 Lib3dsChunks.CHK_OBJ_HIDDEN: object_flags |= Lib3dsObjectFlags.LIB3DS_OBJECT_HIDDEN; break; case Lib3dsChunks.CHK_OBJ_DOESNT_CAST: object_flags |= Lib3dsObjectFlags.LIB3DS_OBJECT_DOESNT_CAST; break; case Lib3dsChunks.CHK_OBJ_VIS_LOFTER: object_flags |= Lib3dsObjectFlags.LIB3DS_OBJECT_VIS_LOFTER; break; case Lib3dsChunks.CHK_OBJ_MATTE: object_flags |= Lib3dsObjectFlags.LIB3DS_OBJECT_MATTE; break; case Lib3dsChunks.CHK_OBJ_DONT_RCVSHADOW: object_flags |= Lib3dsObjectFlags.LIB3DS_OBJECT_DONT_RCVSHADOW; break; case Lib3dsChunks.CHK_OBJ_FAST: object_flags |= Lib3dsObjectFlags.LIB3DS_OBJECT_FAST; break; case Lib3dsChunks.CHK_OBJ_FROZEN: object_flags |= Lib3dsObjectFlags.LIB3DS_OBJECT_FROZEN; break; default: lib3ds_chunk_unknown(chunk, io); break; } } if (mesh != null) { mesh.object_flags = object_flags; } if (camera != null) { camera.object_flags = object_flags; } if (light != null) { light.object_flags = object_flags; } lib3ds_chunk_read_end(c, io); }
static void file_bounding_box_of_nodes_impl(Lib3dsNode node, Lib3dsFile file, bool include_meshes, bool include_cameras, bool include_lights, float[] bmin, float[] bmax, float[,] matrix) { switch (node.type) { case Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE: if (include_meshes) { Lib3dsMeshInstanceNode n = (Lib3dsMeshInstanceNode)node; int index = lib3ds_file_mesh_by_name(file, n.instance_name); if (index < 0) { index = lib3ds_file_mesh_by_name(file, node.name); } if (index >= 0) { float[,] inv_matrix = new float[4, 4], M = new float[4, 4]; float[] v = new float[3]; Lib3dsMesh mesh = file.meshes[index]; lib3ds_matrix_copy(inv_matrix, mesh.matrix); lib3ds_matrix_inv(inv_matrix); lib3ds_matrix_mult(M, matrix, node.matrixNode); lib3ds_matrix_translate(M, -n.pivot[0], -n.pivot[1], -n.pivot[2]); lib3ds_matrix_mult(M, M, inv_matrix); foreach (Lib3dsVertex vertex in mesh.vertices) { lib3ds_vector_transform(v, M, vertex); lib3ds_vector_min(bmin, v); lib3ds_vector_max(bmax, v); } } } break; case Lib3dsNodeType.LIB3DS_NODE_CAMERA: case Lib3dsNodeType.LIB3DS_NODE_CAMERA_TARGET: if (include_cameras) { float[] z = new float[3], v = new float[3]; float[,] M = new float[4, 4]; lib3ds_matrix_mult(M, matrix, node.matrixNode); lib3ds_vector_zero(z); lib3ds_vector_transform(v, M, z); lib3ds_vector_min(bmin, v); lib3ds_vector_max(bmax, v); } break; case Lib3dsNodeType.LIB3DS_NODE_OMNILIGHT: case Lib3dsNodeType.LIB3DS_NODE_SPOTLIGHT: case Lib3dsNodeType.LIB3DS_NODE_SPOTLIGHT_TARGET: if (include_lights) { float[] z = new float[3], v = new float[3]; float[,] M = new float[4, 4]; lib3ds_matrix_mult(M, matrix, node.matrixNode); lib3ds_vector_zero(z); lib3ds_vector_transform(v, M, z); lib3ds_vector_min(bmin, v); lib3ds_vector_max(bmax, v); } break; } foreach (Lib3dsNode p in node.childs) { file_bounding_box_of_nodes_impl(p, file, include_meshes, include_cameras, include_lights, bmin, bmax, matrix); } }
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 point_array_write(Lib3dsMesh mesh, Lib3dsIo io) { Lib3dsChunk c=new Lib3dsChunk(); c.chunk=Lib3dsChunks.CHK_POINT_ARRAY; c.size=8+12u*mesh.nvertices; lib3ds_chunk_write(c, io); lib3ds_io_write_word(io, mesh.nvertices); if(lib3ds_matrix_det(mesh.matrix)>=0.0f) { for(int i=0; i<mesh.nvertices; i++) lib3ds_io_write_vector(io, mesh.vertices[i]); } else { // 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_io_write_vector(io, tmp); } } }
static void texco_array_write(Lib3dsMesh mesh, Lib3dsIo io) { if(mesh.texcos==null) return; Lib3dsChunk c=new Lib3dsChunk(); c.chunk=Lib3dsChunks.CHK_TEX_VERTS; c.size=8+8u*mesh.nvertices; lib3ds_chunk_write(c, io); lib3ds_io_write_word(io, mesh.nvertices); for(int i=0; i<mesh.nvertices; i++) { lib3ds_io_write_float(io, mesh.texcos[i].s); lib3ds_io_write_float(io, mesh.texcos[i].t); } }
// Free a mesh object and all of its resources. // // \param mesh Mesh object to be freed. public static void lib3ds_mesh_free(Lib3dsMesh mesh) { lib3ds_mesh_resize_vertices(mesh, 0, false, false); lib3ds_mesh_resize_faces(mesh, 0); }
// Calculates the vertex normals corresponding to the smoothing group // settings for each face of a mesh. // // \param mesh A pointer to the mesh to calculate the normals for. // \param normals A pointer to a buffer to store the calculated // normals. The buffer must have the size: // 3*3*sizeof(float)*mesh.nfaces. // // To allocate the normal buffer do for example the following: // \code // Lib3dsVector *normals = malloc(3*3*sizeof(float)*mesh.nfaces); // \endcode // // To access the normal of the i-th vertex of the j-th face do the // following: // \code // normals[3*j+i] // \endcode public static void lib3ds_mesh_calculate_vertex_normals(Lib3dsMesh mesh, float[][] normals) { if(mesh.nfaces==0) return; Lib3dsFaces[] fl=new Lib3dsFaces[mesh.nvertices]; Lib3dsFaces[] fa=new Lib3dsFaces[3*mesh.nfaces]; for(int i=0; i<fa.Length; i++) fa[i]=new Lib3dsFaces(); for(int i=0; i<mesh.nfaces; i++) { for(int j=0; j<3; j++) { Lib3dsFaces l=fa[3*i+j]; float[] p=new float[3], q=new float[3], n=new float[3]; float len, weight; l.index=i; l.next=fl[mesh.faces[i].index[j]]; fl[mesh.faces[i].index[j]]=l; lib3ds_vector_sub(p, mesh.vertices[mesh.faces[i].index[j<2?j+1:0]], mesh.vertices[mesh.faces[i].index[j]]); lib3ds_vector_sub(q, mesh.vertices[mesh.faces[i].index[j>0?j-1:2]], mesh.vertices[mesh.faces[i].index[j]]); lib3ds_vector_cross(n, p, q); len=lib3ds_vector_length(n); if(len>0) { weight=(float)Math.Atan2(len, lib3ds_vector_dot(p, q)); lib3ds_vector_scalar_mul(l.normal, n, weight/len); } else lib3ds_vector_zero(l.normal); } } for(int i=0; i<mesh.nfaces; i++) { Lib3dsFace f=mesh.faces[i]; for(int j=0; j<3; j++) { float[] n=new float[3]; Lib3dsFaces p; Lib3dsFace pf; Debug.Assert(mesh.faces[i].index[j]<mesh.nvertices); if(f.smoothing_group!=0) { uint smoothing_group=f.smoothing_group; lib3ds_vector_zero(n); for(p=fl[mesh.faces[i].index[j]]; p!=null; p=p.next) { pf=mesh.faces[p.index]; if((pf.smoothing_group&f.smoothing_group)!=0) smoothing_group|=pf.smoothing_group; } for(p=fl[mesh.faces[i].index[j]]; p!=null; p=p.next) { pf=mesh.faces[p.index]; if((smoothing_group&pf.smoothing_group)!=0) lib3ds_vector_add(n, n, p.normal); } } else lib3ds_vector_copy(n, fa[3*i+j].normal); lib3ds_vector_normalize(n); lib3ds_vector_copy(normals[3*i+j], n); } } }
// Calculates the vertex normals corresponding to the smoothing group // settings for each face of a mesh. // // \param mesh A pointer to the mesh to calculate the normals for. // \param normals A pointer to a buffer to store the calculated // normals. The buffer must have the size: // 3*3*sizeof(float)*mesh.nfaces. // // To allocate the normal buffer do for example the following: // \code // Lib3dsVector *normals = malloc(3*3*sizeof(float)*mesh.nfaces); // \endcode // // To access the normal of the i-th vertex of the j-th face do the // following: // \code // normals[3*j+i] // \endcode public static void lib3ds_mesh_calculate_vertex_normals(Lib3dsMesh mesh, float[][] normals) { if (mesh.nfaces == 0) { return; } Lib3dsFaces[] fl = new Lib3dsFaces[mesh.nvertices]; Lib3dsFaces[] fa = new Lib3dsFaces[3 * mesh.nfaces]; for (int i = 0; i < fa.Length; i++) { fa[i] = new Lib3dsFaces(); } for (int i = 0; i < mesh.nfaces; i++) { for (int j = 0; j < 3; j++) { Lib3dsFaces l = fa[3 * i + j]; float[] p = new float[3], q = new float[3], n = new float[3]; float len, weight; l.index = i; l.next = fl[mesh.faces[i].index[j]]; fl[mesh.faces[i].index[j]] = l; lib3ds_vector_sub(p, mesh.vertices[mesh.faces[i].index[j < 2?j + 1:0]], mesh.vertices[mesh.faces[i].index[j]]); lib3ds_vector_sub(q, mesh.vertices[mesh.faces[i].index[j > 0?j - 1:2]], mesh.vertices[mesh.faces[i].index[j]]); lib3ds_vector_cross(n, p, q); len = lib3ds_vector_length(n); if (len > 0) { weight = (float)Math.Atan2(len, lib3ds_vector_dot(p, q)); lib3ds_vector_scalar_mul(l.normal, n, weight / len); } else { lib3ds_vector_zero(l.normal); } } } for (int i = 0; i < mesh.nfaces; i++) { Lib3dsFace f = mesh.faces[i]; for (int j = 0; j < 3; j++) { float[] n = new float[3]; Lib3dsFaces p; Lib3dsFace pf; Debug.Assert(mesh.faces[i].index[j] < mesh.nvertices); if (f.smoothing_group != 0) { uint smoothing_group = f.smoothing_group; lib3ds_vector_zero(n); for (p = fl[mesh.faces[i].index[j]]; p != null; p = p.next) { pf = mesh.faces[p.index]; if ((pf.smoothing_group & f.smoothing_group) != 0) { smoothing_group |= pf.smoothing_group; } } for (p = fl[mesh.faces[i].index[j]]; p != null; p = p.next) { pf = mesh.faces[p.index]; if ((smoothing_group & pf.smoothing_group) != 0) { lib3ds_vector_add(n, n, p.normal); } } } else { lib3ds_vector_copy(n, fa[3 * i + j].normal); } lib3ds_vector_normalize(n); lib3ds_vector_copy(normals[3 * i + j], n); } } }
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); }
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); }
/// <summary> /// Draw a mesh. /// </summary> /// <param name="gl">OpenGL handler.</param> /// <param name="buildingObj">The mesh.</param>BuildingObjectLib3DS _object, private void DrawMesh(OpenGL gl, Lib3dsMesh thisMesh, Hashtable textures, List<Lib3dsMaterial> matrials, DrawType type) { if (thisMesh == null || thisMesh.nfaces == 0) return; // Draw all the faces in this mesh. for (int j = 0; j < thisMesh.faces.Count; j++) { Lib3dsFace thisFace = thisMesh.faces[j]; float transparency = matrials[thisFace.material].transparency; //float[] fogColor = new float[4] { 0.5f, 0.5f, 0.5f, 1.0f }; //float[] LightAmbient = new float[4] { 0.5f, 0.5f, 0.5f, 1.0f }; //float[] LightDiffuse = new float[4] { 1.0f, 1.0f, 1.0f, 1.0f }; //float[] LightPosition = new float[4] { 0.0f, 0.0f, 2.0f, 1.0f }; switch (type) { case DrawType.WireFrame: gl.PolygonMode(OpenGL.GL_FRONT_AND_BACK, OpenGL.GL_LINE); IsDrawTexture = false; gl.Color(0.5f, 0.5f, 0.5f, 0.5f); gl.LineWidth(1.5f); break; case DrawType.Full: IsDrawTexture = BindTexture(gl, textures, matrials[thisFace.material].name); gl.PolygonMode(OpenGL.GL_FRONT_AND_BACK, OpenGL.GL_FILL); break; case DrawType.Face: gl.PolygonMode(OpenGL.GL_FRONT_AND_BACK, OpenGL.GL_FILL); IsDrawTexture = false; break; case DrawType.Translucent: IsDrawTexture = BindTexture(gl, textures, matrials[thisFace.material].name); gl.PolygonMode(OpenGL.GL_FRONT_AND_BACK, OpenGL.GL_FILL); gl.Enable(OpenGL.GL_BLEND); gl.BlendFunc(OpenGL.GL_SRC_ALPHA,OpenGL.GL_ONE_MINUS_SRC_ALPHA); //gl.Enable(OpenGL.GL_TEXTURE_2D); // Enable Texture Mapping //gl.ShadeModel(OpenGL.GL_SMOOTH); // Enable Smooth Shading //gl.ClearColor(0.5f,0.5f,0.5f,1.0f); // We'll Clear To The Color Of The Fog //gl.ClearDepth(1.0f); // Depth Buffer Setup //gl.Enable(OpenGL.GL_DEPTH_TEST); // Enables Depth Testing //gl.DepthFunc(OpenGL.GL_LEQUAL); // The Type Of Depth Testing To Do //gl.Hint(OpenGL.GL_PERSPECTIVE_CORRECTION_HINT, OpenGL.GL_NICEST); // Really Nice Perspective Calculations //gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_AMBIENT, LightAmbient); // Setup The Ambient Light //gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light //gl.Light(OpenGL.GL_LIGHT1, OpenGL.GL_POSITION,LightPosition); // Position The Light //gl.Enable(OpenGL.GL_LIGHT1); //gl.Fog(OpenGL.GL_FOG_COLOR, fogColor);//设置雾颜色,f是一个指定颜色的数组float f[4] //gl.Fog(OpenGL.GL_FOG_DENSITY, 0.85f); // 设置雾的密度 //gl.Hint(OpenGL.GL_FOG_HINT, OpenGL.GL_DONT_CARE); // 设置系统如何计算雾气 //gl.Fog(OpenGL.GL_FOG_START, 0.01f);//设置雾从多远开始 //gl.Fog(OpenGL.GL_FOG_END, 100.0f);//设置雾从多远结束 //gl.Fog(OpenGL.GL_FOG_MODE, OpenGL.GL_LINEAR);//设置使用哪种雾,共有三中雾化模式 //gl.Enable(OpenGL.GL_FOG);//打开雾效果 transparency = 0.2f; break; default: gl.PolygonMode(OpenGL.GL_FRONT_AND_BACK, OpenGL.GL_FILL); IsDrawTexture = false; break; } if (type != DrawType.WireFrame) { gl.Color(matrials[thisFace.material].diffuse[0], matrials[thisFace.material].diffuse[1], matrials[thisFace.material].diffuse[2], matrials[thisFace.material].transparency); } gl.Begin(OpenGL.GL_TRIANGLES); for (int k = 0; k != 3; ++k) { int index = thisFace.index[k]; if (IsDrawTexture) gl.TexCoord(thisMesh.texcos[index].s, thisMesh.texcos[index].t); gl.Vertex(thisMesh.vertices[index].x / 20, thisMesh.vertices[index].z / 20, -thisMesh.vertices[index].y / 20); } gl.End(); if(type == DrawType.Translucent) gl.Disable(OpenGL.GL_BLEND); } }
public static Lib3dsMeshInstanceNode lib3ds_node_new_mesh_instance(Lib3dsMesh mesh, string instance_name, float[] pos0, float[] scl0, float[] rot0) { Lib3dsNode node=lib3ds_node_new(Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE); if(mesh!=null) node.name=mesh.name; else node.name="$$$DUMMY"; Lib3dsMeshInstanceNode n=(Lib3dsMeshInstanceNode)node; if(instance_name!=null) n.instance_name=instance_name; else n.instance_name=""; lib3ds_track_resize(n.pos_track, 1); if(pos0!=null) lib3ds_vector_copy(n.pos_track.keys[0].value, pos0); lib3ds_track_resize(n.scl_track, 1); if(scl0!=null) lib3ds_vector_copy(n.scl_track.keys[0].value, scl0); else lib3ds_vector_make(n.scl_track.keys[0].value, 1, 1, 1); lib3ds_track_resize(n.rot_track, 1); if(rot0!=null) for(int i=0; i<4; i++) n.rot_track.keys[0].value[i]=rot0[i]; else for(int i=0; i<4; i++) n.rot_track.keys[0].value[i]=0; return n; }
public static void lib3ds_mesh_resize_vertices(Lib3dsMesh mesh, ushort nvertices, bool use_texcos, bool use_flags) { Debug.Assert(mesh != null); if (nvertices > 0) { if (mesh.vertices == null) { mesh.vertices = new List <Lib3dsVertex>(); } while (mesh.vertices.Count < nvertices) { mesh.vertices.Add(new Lib3dsVertex()); } if (mesh.vertices.Count > nvertices) { mesh.vertices.RemoveRange(nvertices, mesh.vertices.Count - nvertices); } } else { mesh.vertices = null; } ushort tmp = (ushort)(use_texcos?nvertices:0); if (tmp > 0) { if (mesh.texcos == null) { mesh.texcos = new List <Lib3dsTexturecoordinate>(); } while (mesh.texcos.Count < tmp) { mesh.texcos.Add(new Lib3dsTexturecoordinate()); } if (mesh.texcos.Count > tmp) { mesh.texcos.RemoveRange(tmp, mesh.texcos.Count - tmp); } } else { mesh.texcos = null; } tmp = (ushort)(use_flags?nvertices:0); if (tmp > 0) { if (mesh.vflags == null) { mesh.vflags = new List <ushort>(); } while (mesh.vflags.Count < tmp) { mesh.vflags.Add(0); } if (mesh.vflags.Count > tmp) { mesh.vflags.RemoveRange(tmp, mesh.vflags.Count - tmp); } } else { mesh.vflags = null; } mesh.nvertices = nvertices; }
public static void lib3ds_mesh_calculate_face_normals(Lib3dsMesh mesh, float[][] face_normals) { if(mesh.nfaces==0) return; for(int i=0; i<mesh.nfaces; i++) { lib3ds_vector_normal(face_normals[i], mesh.vertices[mesh.faces[i].index[0]], mesh.vertices[mesh.faces[i].index[1]], mesh.vertices[mesh.faces[i].index[2]]); } }
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_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_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 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); }
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); } } }
static void flag_array_write(Lib3dsMesh mesh, Lib3dsIo io) { if(mesh.vflags==null) return; Lib3dsChunk c=new Lib3dsChunk(); c.chunk=Lib3dsChunks.CHK_POINT_FLAG_ARRAY; c.size=8+2u*mesh.nvertices; lib3ds_chunk_write(c, io); lib3ds_io_write_word(io, mesh.nvertices); for(int i=0; i<mesh.nvertices; i++) lib3ds_io_write_word(io, mesh.vflags[i]); }
static void mesh_dump(Lib3dsMesh mesh) { Debug.Assert(mesh!=null); Console.WriteLine(" {0} vertices={1} faces={2}", mesh.name, mesh.nvertices, mesh.nfaces); Console.WriteLine(" matrix:"); matrix_dump(mesh.matrix); Lib3dsVertex p=new Lib3dsVertex(); Console.WriteLine(" vertices (x, y, z, u, v):"); for(int i=0; i<mesh.nvertices; i++) { LIB3DS.lib3ds_vector_copy(p, mesh.vertices[i]); Console.Write(" {0,10:F5} {1,10:F5} {2,10:F5}", p.x, p.y, p.z); if(mesh.texcos!=null) Console.Write(" {0,10:F5} {1,10:F5}", mesh.texcos[i].s, mesh.texcos[i].t); Console.WriteLine(); } Console.WriteLine(" facelist:"); for(int i=0; i<mesh.nfaces; i++) Console.WriteLine(" {0,4} {1,4} {2,4} flags:{3:X} smoothing:{4:X} material:\"{5}\"\n", mesh.faces[i].index[0], mesh.faces[i].index[1], mesh.faces[i].index[2], mesh.faces[i].flags, mesh.faces[i].smoothing_group, mesh.faces[i].material); }
// Find the bounding box of a mesh object. // // \param mesh The mesh object // \param bmin Returned bounding box // \param bmax Returned bounding box public static void lib3ds_mesh_bounding_box(Lib3dsMesh mesh, float[] bmin, float[] bmax) { bmin[0]=bmin[1]=bmin[2]=float.MaxValue; bmax[0]=bmax[1]=bmax[2]=-float.MaxValue; for(int i=0; i<mesh.nvertices; i++) { lib3ds_vector_min(bmin, mesh.vertices[i]); lib3ds_vector_max(bmax, mesh.vertices[i]); } }