예제 #1
0
 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);
 }
예제 #2
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);
                }
            }
        }