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 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 static void AddMeshTo3DS(Lib3dsFile res, PSKFile f, Matrix m) { Lib3dsMesh mesh = new Lib3dsMesh(); string name = "Box00" + res.meshes.Count; 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); }
public bool Parse3DSMesh(Lib3dsFile file, Lib3dsMesh mesh) { foreach (Lib3dsVertex vert in mesh.vertices) { Vertices.Add(new P3DVertex(vert.x, vert.z, vert.y)); } foreach (Lib3dsFace face in mesh.faces) { if (face.index.Length > 3) { //MessageBox.Show("SHIT."); } TexturePolygon texPoly = new TexturePolygon(); texPoly.Texture = GetTextureFrom3dsID(file, face.material).Name; texPoly.Material = MaterialFrom3DS(file.materials[face.material], (face.smoothing_group != 0)); texPoly.SGFrom3DS = face.smoothing_group; texPoly.U1 = mesh.texcos[face.index[0]].s; texPoly.U2 = mesh.texcos[face.index[2]].s; texPoly.U3 = mesh.texcos[face.index[1]].s; texPoly.V1 = mesh.texcos[face.index[0]].t; texPoly.V2 = mesh.texcos[face.index[2]].t; texPoly.V3 = mesh.texcos[face.index[1]].t; texPoly.P1 = Convert.ToInt16(face.index[0]); texPoly.P2 = Convert.ToInt16(face.index[2]); texPoly.P3 = Convert.ToInt16(face.index[1]); Polygons.Add(texPoly); } Name = mesh.name; Application.Current.Dispatcher.BeginInvoke((Action)(() => ((P3DElementView)TreeItem.Header).content.Text = Name)); Size = 1; Flags = FlagFrom3DSName(mesh.name); NumVertices = Convert.ToInt16(Vertices.Count); NumPolys = Convert.ToInt16(Polygons.Count); LocalPos = new P3DVertex(mesh.matrix[3, 0], mesh.matrix[3, 1], mesh.matrix[3, 2]); Length = 0; Height = 0; Depth = 0; return(true); }
/// <summary> /// Draw a object. /// </summary> /// <param name="gl">OpenGL handler.</param> /// <param name="buildingObj">The object.</param> private void DrawObject(OpenGL gl, BuildingObjectLib3DS buildingObj, DrawType type) { Lib3dsMeshInstanceNode thisMeshInst = buildingObj.Object; if (thisMeshInst.childs.Count == 0) { // Maybe this object only have one mesh. Lib3dsMesh thisMesh = FindLib3dsMeshByName(thisMeshInst.name, buildingObj.Model.meshes); DrawMesh(gl, thisMesh, buildingObj.Textures, buildingObj.Model.materials, type); } else { // Draw all the meshes in this object. foreach (Lib3dsNode node in thisMeshInst.childs) { Lib3dsMesh thisMesh = FindLib3dsMeshByName(node.name, buildingObj.Model.meshes); DrawMesh(gl, thisMesh, buildingObj.Textures, buildingObj.Model.materials, type); } } }
/// <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 void ExportP3D(P3D p3d, string path) { Lib3dsFile file = LIB3DS.lib3ds_file_new(); //file.frames = 0; // Lib3dsMaterial mat = LIB3DS.lib3ds_material_new("c_white"); // //LIB3DS.lib3ds_file_insert_material(file, mat, -1); // mat.diffuse[0] = 1; // mat.diffuse[1] = 1; // mat.diffuse[2] = 1; foreach (Mesh P3Dmesh in p3d.MeshesChunk.Meshes) { Lib3dsMesh mesh = LIB3DS.lib3ds_mesh_new(P3Dmesh.Name); Lib3dsMeshInstanceNode inst; LIB3DS.lib3ds_file_insert_mesh(file, mesh, -1); LIB3DS.lib3ds_mesh_resize_vertices(mesh, (ushort)P3Dmesh.NumVertices, true, false); for (int i = 0; i < P3Dmesh.NumVertices; i++) { mesh.vertices[i].x = P3Dmesh.Vertices[i].x; mesh.vertices[i].z = P3Dmesh.Vertices[i].y; mesh.vertices[i].y = P3Dmesh.Vertices[i].z; mesh.texcos[i].s = findVerticeU(i, P3Dmesh); mesh.texcos[i].t = findVerticeV(i, P3Dmesh); } LIB3DS.lib3ds_mesh_resize_faces(mesh, (ushort)P3Dmesh.NumPolys); for (int i = 0; i < P3Dmesh.NumPolys; i++) { mesh.faces[i].index[2] = (ushort)P3Dmesh.Polygons[i].P1; mesh.faces[i].index[1] = (ushort)P3Dmesh.Polygons[i].P2; mesh.faces[i].index[0] = (ushort)P3Dmesh.Polygons[i].P3; mesh.faces[i].material = _3dsMaterials.Instance.GetMaterial(P3Dmesh.Polygons[i].Texture, P3Dmesh.Polygons[i].Material, file); mesh.faces[i].smoothing_group = (uint)1; } float[] pos = { P3Dmesh.LocalPos.x, P3Dmesh.LocalPos.z, P3Dmesh.LocalPos.y }; inst = LIB3DS.lib3ds_node_new_mesh_instance(mesh, String.Empty, pos, null, null); LIB3DS.lib3ds_file_append_node(file, inst, null); } foreach (Light p3dlight in p3d.LightsChunk.Lights) { Lib3dsLight light = LIB3DS.lib3ds_light_new(p3dlight.Name); LIB3DS.lib3ds_file_insert_light(file, light, -1); light.color[0] = Convert.ToSingle(p3dlight.GetColorRed()) / 255; light.color[1] = Convert.ToSingle(p3dlight.GetColorGreen()) / 255; light.color[2] = Convert.ToSingle(p3dlight.GetColorBlue()) / 255; float[] pos = { p3dlight.Position.x, p3dlight.Position.z, p3dlight.Position.y }; light.position = pos; light.inner_range = p3dlight.Radius; light.multiplier = 1.5f; Lib3dsOmnilightNode inst = LIB3DS.lib3ds_node_new_omnilight(light); LIB3DS.lib3ds_file_append_node(file, inst, null); } if (!LIB3DS.lib3ds_file_save(file, path)) { MessageBox.Show("ERROR: Saving 3ds file failed!"); } LIB3DS.lib3ds_file_free(file); }
/// <summary> /// Calculate this object 's Location /// </summary> public void CalculateLocation() { // If this object just contain one mesh if (this.Type != BuildingObjectType.Outside && this.Type != BuildingObjectType.Object) { foreach (BuildingObjectLib3DS child in Childs.Values) { child.CalculateLocation(); this.Coordinate.x += child.Coordinate.x; this.Coordinate.y += child.Coordinate.y; this.Coordinate.z += child.Coordinate.z; } this.Coordinate.x /= Childs.Count; this.Coordinate.y /= Childs.Count; this.Coordinate.z /= Childs.Count; } // Maybe not just one mesh else { int allCount = 0; // If have children then calculate childre. if (Object.childs.Count != 0) { foreach (Lib3dsNode node in Object.childs) { Lib3dsMesh mesh = FindLib3dsMeshByName(node.name, Model.meshes); if (mesh != null) { foreach (Lib3dsVertex vertex in mesh.vertices) { this.Coordinate.x += vertex.x; this.Coordinate.y += vertex.y; this.Coordinate.z += vertex.z; allCount++; } } } } // If do not have children, then calculate itself. else { Lib3dsMesh mesh = FindLib3dsMeshByName(Object.name, Model.meshes); if (mesh != null) { foreach (Lib3dsVertex vertex in mesh.vertices) { this.Coordinate.x += vertex.x; this.Coordinate.y += vertex.y; this.Coordinate.z += vertex.z; allCount++; } } } this.Coordinate.x /= allCount; this.Coordinate.y /= allCount; this.Coordinate.z /= allCount; } this.Coordinate.x /= 20; this.Coordinate.y /= 20; this.Coordinate.z /= 20; }
//写3DS文件 protected virtual bool writeToFile() { if (mDbVertices == null || mDbTextureCoors == null || uFacesIndex == null) { return(false); } //新建LIB3DS文件对象 Lib3dsFile file = LIB3DS.lib3ds_file_new(); file.frames = 360; //新建网格节点 Lib3dsMesh mesh = LIB3DS.lib3ds_mesh_new("mesh"); Lib3dsMeshInstanceNode inst; LIB3DS.lib3ds_file_insert_mesh(file, mesh, -1); //一、将顶点写入网格 int nVertices = mDbVertices.GetLength(0); LIB3DS.lib3ds_mesh_resize_vertices(mesh, (ushort)nVertices, true, false); for (int i = 0; i < nVertices; i++) { Lib3dsVertex vertexTmp = new Lib3dsVertex(mDbVertices[i, 0], mDbVertices[i, 1], mDbVertices[i, 2]); LIB3DS.lib3ds_vector_copy(mesh.vertices[i], vertexTmp); //将纹理坐标写入网格 mesh.texcos[i] = new Lib3dsTexturecoordinate(mDbTextureCoors[i, 0], mDbTextureCoors[i, 1]); } //二、将纹理信息写入文件 Lib3dsMaterial mat = LIB3DS.lib3ds_material_new("material1"); LIB3DS.lib3ds_file_insert_material(file, mat, -1); //如果没有指定纹理,则默认为灰色材质 if (String.IsNullOrEmpty(mSzTextureFilename)) { mat.diffuse[0] = 0.5f; mat.diffuse[1] = 0.5f; mat.diffuse[2] = 0.5f; } else { mat.texture1_map.name = mSzTextureFilename; mat.texture1_map.percent = 1.0f; } //三、将三角化后的面的顶点索引号写入网格 int nFaces = uFacesIndex.GetLength(0); LIB3DS.lib3ds_mesh_resize_faces(mesh, (ushort)nFaces); for (int i = 0; i < nFaces; i++) { for (int j = 0; j < 3; j++) { mesh.faces[i].index[j] = uFacesIndex[i, j]; } //指定每个三角化后的面的材质 mesh.faces[i].material = 0; } inst = LIB3DS.lib3ds_node_new_mesh_instance(mesh, "01", null, null, null); LIB3DS.lib3ds_file_append_node(file, inst, null); if (!LIB3DS.lib3ds_file_save(file, mSzOutputFilename)) { LIB3DS.lib3ds_file_free(file); return(false); } LIB3DS.lib3ds_file_free(file); return(true); }