Exemplo n.º 1
0
        public static Lib3dsFile Export(List <Group> groups, List <Lib3dsVertex> vertices, List <ushort[]> allFaces, short[] faceGroupIds)
        {
            var file          = LIB3DS.lib3ds_file_new();
            var textureGroups = new Dictionary <int, List <Group> >();

            foreach (var group in groups)
            {
                var groupId = (int)group[ModelField.TextureGroup];
                if (groupId == -1 || !textureGroups.TryGetValue(groupId, out var textureGroup))
                {
                    textureGroup = new List <Group>();
                    if (groupId != -1)
                    {
                        textureGroups.Add(groupId, textureGroup);
                    }
                }

                textureGroup.Add(group);
                group.TextureGroup = textureGroup;

                // TODO: Hierarchy of object
                var node = LIB3DS.lib3ds_node_new(Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE);
                node.name    = group[ModelField.GroupName].ToString();
                node.node_id = (ushort)file.nodes.Count;
                file.nodes.Add(node);
            }

            var objectIndices = (faceGroupIds == null ? Enumerable.Range(0, groups.Count) :
                                 faceGroupIds.Distinct().Select(b => (int)b)).ToArray();

            MaterialExporter.Export(groups, file);

            var facesByObject = TriangleExporter.Export(allFaces, faceGroupIds, objectIndices);

            foreach (var i in objectIndices)
            {
                var group = groups[i];
                var faces = facesByObject[i];

                var mesh = LIB3DS.lib3ds_mesh_new(group[ModelField.GroupName].ToString());
                mesh.vertices  = vertices;
                mesh.nvertices = (ushort)vertices.Count;
                mesh.texcos    = new List <Lib3dsTexturecoordinate>();
                file.meshes.Add(mesh);

                if (faces.Count != 0)
                {
                    var usedVertices = group.TextureGroup
                                       .Select(g => groups.IndexOf(g))
                                       .SelectMany(g => facesByObject[g])
                                       .SelectMany(f => f.index)
                                       .Distinct()
                                       .Select(v => vertices[v])
                                       .ToArray();

                    var minX = usedVertices.Min(v => v.x);
                    var minY = usedVertices.Min(v => v.y);
                    var minZ = usedVertices.Min(v => v.z);
                    var maxX = usedVertices.Max(v => v.x);
                    var maxY = usedVertices.Max(v => v.y);
                    var maxZ = usedVertices.Max(v => v.z);

                    var objectMin   = new Vector3(minX, minY, minZ);
                    var objectScale = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);

                    if (objectScale.X < 0.001f)
                    {
                        objectScale.X = 1;
                    }
                    if (objectScale.Y < 0.001f)
                    {
                        objectScale.Y = 1;
                    }
                    if (objectScale.Z < 0.001f)
                    {
                        objectScale.Z = 1;
                    }

                    var quaternionX = Quaternion.CreateFromYawPitchRoll(0, -(float)group[ModelField.TextureRotateX], 0);
                    var quaternionY = Quaternion.CreateFromYawPitchRoll(-(float)group[ModelField.TextureRotateY], 0, 0);
                    var quaternionZ = Quaternion.CreateFromYawPitchRoll(0, 0, -(float)group[ModelField.TextureRotateZ]);

                    var quaternion = Quaternion.Multiply(quaternionX, quaternionY);
                    var rotation   = Matrix4x4.CreateFromQuaternion(Quaternion.Multiply(quaternion, quaternionZ));

                    for (int v = 0; v < vertices.Count; v++)
                    {
                        var vector = new Vector3(vertices[v].x, vertices[v].y, vertices[v].z);
                        vector -= objectMin;
                        vector /= objectScale;
                        vector  = Vector3.Transform(vector, rotation);

                        mesh.texcos.Add(new Lib3dsTexturecoordinate(vector.X, vector.Y));
                    }

                    foreach (var face in faces)
                    {
                        face.material = i;
                    }

                    mesh.faces  = faces;
                    mesh.nfaces = (ushort)faces.Count;
                }
            }

            return(file);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        //写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);
        }