예제 #1
0
        public override void parse(NIFFile file, NIFObject baseo, BinaryReader ds)
        {
            base.parse(file, baseo, ds);

            loadRenderable(file, ds);
            meshPrimType  = ds.readInt();
            numSubMeshes  = ds.readUnsignedShort();
            isInstanced   = ds.readUnsignedByte() > 0;
            boundsCenter  = new Point3f(ds.readFloat(), ds.readFloat(), ds.readFloat());
            boundsRad     = ds.readFloat();
            numStreamRefs = ds.readInt();
            streamRefs    = new List <NifMeshStream>();

            for (int i = 0; i < numStreamRefs; i++)
            {
                NifMeshStream meshStream = new NifMeshStream();
                meshStream.parse(file, baseo, ds);
                streamRefs.Add(meshStream);
            }

            modLinks = loadLinkIDs(ds);
            file.addMesh(this);
        }
예제 #2
0
        public static MeshData prepareMesh(NIFFile nf, NiMesh mesh)
        {
            bool IS_TERRAIN = (nf.getStringTable().Contains("terrainL1"));

            StreamAndElement indexStreamObj = mesh.getStreamAndElement(nf, "INDEX", -1);
            NifMeshStream    indexStreamRef = indexStreamObj.streamRef;
            NiDataStream     indexStream    = indexStreamObj.dataStream;
            NifStreamElement indexElem      = indexStreamObj.elem;

            StreamAndElement nStreamObj = mesh.getStreamAndElement(nf, "NORMAL", -1);
            NifMeshStream    nStreamRef = nStreamObj.streamRef;
            NiDataStream     nStream    = nStreamObj.dataStream;
            NifStreamElement nElem      = nStreamObj.elem;

            StreamAndElement uvStreamObj  = mesh.getStreamAndElement(nf, "TEXCOORD", -1);
            StreamAndElement uv2StreamObj = mesh.getStreamAndElement(nf, "TEXCOORD", 1);


            StreamAndElement positionStreamObj = mesh.getStreamAndElement(nf, "POSITION", -1);
            NifMeshStream    posStreamRef      = positionStreamObj.streamRef;
            NiDataStream     posStream         = positionStreamObj.dataStream;
            NifStreamElement posElem           = positionStreamObj.elem;
            DataType         indexDataType     = typeForNifDataType(indexStreamObj.elem.dataType);
            DataType         posDataType       = typeForNifDataType(positionStreamObj.elem.dataType);

            if (posDataType != DataType.FLOAT)
            {
                throw new Exception("Unknown position types");
            }

            MeshData           meshData    = new MeshData();
            List <Vector3>     verts       = meshData.verts;
            List <Vector2>     uvs         = meshData.uvs;
            List <List <int> > triangles   = meshData.triangles;
            List <Vector3>     inNormals   = meshData.inNormals;
            List <BoneWeight>  boneWeights = meshData.boneWeights;

            for (int i = 0; i < mesh.numSubMeshes; i++)
            {
                List <int> bonePalette = new List <int>();

                int vOffset = verts.Count;
                /** vertices */
                StreamRegion posRegion     = posStream.streamRegions[posStreamRef.submeshRegionMap[i]];
                int          posOfs        = posRegion.a * posStream.elemStride;
                int          posEnd        = posOfs + posRegion.b * posStream.elemStride;
                byte[]       posStreamData = posStream.streamData;
                using (BinaryReader dis = new BinaryReader(new MemoryStream(posStreamData, posOfs, posEnd - posOfs)))
                {
                    // Debug.Log("\tverts:" + posRegion.b);
                    for (int v = 0; v < (posEnd - posOfs) / posStream.elemStride; v++)
                    {
                        float x = dis.readFloat();
                        float y = dis.readFloat();
                        float z = dis.readFloat();
                        verts.Add(new Vector3(x, y, z));
                    }
                    //Debug.Log("pos: left over: " + (dis.BaseStream.Length - dis.BaseStream.Position));
                }


                /** faces */
                StreamRegion idxRegion     = indexStream.streamRegions[indexStreamRef.submeshRegionMap[i]];
                int          idxOfs        = idxRegion.a * indexStream.elemStride;
                DataType     idxType       = typeForNifDataType(indexStreamObj.elem.dataType);
                int          idxEnd        = idxOfs + idxRegion.b * indexStream.elemStride;
                byte[]       idxStreamData = indexStream.streamData;

                List <int> tris = new List <int>();
                using (BinaryReader dis = new BinaryReader(new MemoryStream(idxStreamData, idxOfs, idxEnd - idxOfs)))
                {
                    for (int idx = 0; idx < (idxEnd - idxOfs) / indexStream.elemStride; idx++)
                    {
                        int v1x = (dis.readUnsignedShort()) + vOffset;
                        tris.Add(v1x);
                    }
                    //Debug.Log("idx left over:" + (dis.BaseStream.Length - dis.BaseStream.Position));
                }
                triangles.Add(tris);
                {
                    /** uvs */
                    if (uvStreamObj != null)
                    {
                        NiDataStream uvStream     = uvStreamObj.dataStream;
                        StreamRegion uvRegion     = uvStreamObj.dataStream.streamRegions[uvStreamObj.streamRef.submeshRegionMap[i]];
                        DataType     uvType       = typeForNifDataType(uvStreamObj.elem.dataType);
                        int          uvOfs        = uvRegion.a * uvStream.elemStride;
                        int          uvEnd        = uvOfs + uvRegion.b * uvStream.elemStride;
                        byte[]       uvStreamData = uvStream.streamData;
                        //Debug.Log("uv datatype:" + uvType + ":" + uvStream.elemStride);
                        using (BinaryReader dis = new BinaryReader(new MemoryStream(uvStreamData, uvOfs, uvEnd - uvOfs)))
                        {
                            for (int uv = 0; uv < (uvEnd - uvOfs) / uvStream.elemStride; uv++)
                            {
                                float u = dis.readFloat();
                                float v = dis.readFloat();
                                uvs.Add(new Vector2(u, v));
                            }
                        }
                    }

                    /** normals */
                    if (nStreamObj != null)
                    {
                        StreamRegion nRegion     = nStreamObj.dataStream.streamRegions[nStreamObj.streamRef.submeshRegionMap[i]];
                        DataType     nType       = typeForNifDataType(nStreamObj.elem.dataType);
                        int          nOfs        = nRegion.a * nStream.elemStride;
                        int          nEnd        = nOfs + nRegion.b * nStream.elemStride;
                        byte[]       nStreamData = nStream.streamData;
                        using (BinaryReader dis = new BinaryReader(new MemoryStream(nStreamData, nOfs, nEnd - nOfs)))
                        {
                            for (int n = 0; n < (nEnd - nOfs) / nStream.elemStride; n++)
                            {
                                float x = dis.readFloat();
                                float y = dis.readFloat();
                                float z = dis.readFloat();
                                inNormals.Add(new Vector3(x, y, z));
                            }
                        }
                    }

                    /** bone palette */
                    {
                        StreamAndElement bonePalStreamObj = mesh.getStreamAndElement(nf, "BONE_PALETTE", -1);
                        if (bonePalStreamObj != null)
                        {
                            NifMeshStream    bonePalStreamRef = bonePalStreamObj.streamRef;
                            NiDataStream     bonePalStream    = bonePalStreamObj.dataStream;
                            NifStreamElement bonePalElem      = bonePalStreamObj.elem;

                            StreamRegion bonePalRegion     = bonePalStreamObj.dataStream.streamRegions[bonePalStreamObj.streamRef.submeshRegionMap[i]];
                            DataType     bonePalType       = typeForNifDataType(bonePalStreamObj.elem.dataType);
                            int          bonePalOfs        = bonePalRegion.a * bonePalStream.elemStride;
                            int          bonePalEnd        = bonePalOfs + bonePalRegion.b * bonePalStream.elemStride;
                            byte[]       bonePalStreamData = bonePalStream.streamData;
                            using (BinaryReader dis = new BinaryReader(new MemoryStream(bonePalStreamData, bonePalOfs, bonePalEnd - bonePalOfs)))
                            {
                                for (int n = 0; n < (bonePalEnd - bonePalOfs) / bonePalStream.elemStride; n++)
                                {
                                    bonePalette.Add(dis.readUnsignedShort());
                                }
                            }
                        }
                    }
                    {
                        /** blend indicies */
                        StreamAndElement StreamObj = mesh.getStreamAndElement(nf, "BLENDINDICES", -1);
                        if (StreamObj != null)
                        {
                            NifMeshStream StreamRef = StreamObj.streamRef;
                            NiDataStream  Stream    = StreamObj.dataStream;

                            StreamRegion Region     = StreamObj.dataStream.streamRegions[StreamObj.streamRef.submeshRegionMap[i]];
                            DataType     type       = typeForNifDataType(StreamObj.elem.dataType);
                            int          Ofs        = Region.a * Stream.elemStride;
                            int          End        = Ofs + Region.b * Stream.elemStride;
                            byte[]       StreamData = Stream.streamData;
                            //Debug.Log("blendi stride:" + Stream.elemStride + ": type:" + type);

                            // each vertex has a blend index
                            using (BinaryReader dis = new BinaryReader(new MemoryStream(StreamData, Ofs, End - Ofs)))
                            {
                                for (int n = 0; n < (End - Ofs) / Stream.elemStride; n++)
                                {
                                    byte       idx1   = dis.ReadByte();
                                    byte       idx2   = dis.ReadByte();
                                    byte       idx3   = dis.ReadByte();
                                    byte       idx4   = dis.ReadByte();
                                    BoneWeight weight = new BoneWeight();
                                    weight.boneIndex0 = bonePalette[idx1];
                                    weight.boneIndex1 = bonePalette[idx2];
                                    weight.boneIndex2 = bonePalette[idx3];
                                    weight.boneIndex3 = bonePalette[idx4];

                                    boneWeights.Add(weight);
                                }
                                //Debug.Log("blend: left over: " + (dis.BaseStream.Length - dis.BaseStream.Position));
                            }
                        }
                    }
                    {
                        /** blend weights */
                        StreamAndElement StreamObj = mesh.getStreamAndElement(nf, "BLENDWEIGHT", -1);
                        if (StreamObj != null)
                        {
                            NifMeshStream StreamRef = StreamObj.streamRef;
                            NiDataStream  Stream    = StreamObj.dataStream;

                            StreamRegion Region     = StreamObj.dataStream.streamRegions[StreamObj.streamRef.submeshRegionMap[i]];
                            DataType     type       = typeForNifDataType(StreamObj.elem.dataType);
                            int          Ofs        = Region.a * Stream.elemStride;
                            int          End        = Ofs + Region.b * Stream.elemStride;
                            byte[]       StreamData = Stream.streamData;

                            using (BinaryReader dis = new BinaryReader(new MemoryStream(StreamData, Ofs, End - Ofs)))
                            {
                                int total = (End - Ofs) / Stream.elemStride;
                                // each vertex has weights
                                for (int n = 0; n < total; n++)
                                {
                                    BoneWeight w = boneWeights[n + vOffset];
                                    w.weight0 = dis.readFloat();
                                    w.weight1 = dis.readFloat();
                                    w.weight2 = dis.readFloat();
                                    w.weight3 = 0;
                                    boneWeights[n + vOffset] = w;
                                }
                            }
                        }
                    }
                }
            }

            if (IS_TERRAIN && uvs.Count == 0)
            {
                for (int i = 0; i < verts.Count; i++)
                {
                    Vector3 vert = verts[i];
                    float   x    = vert.x;
                    float   z    = vert.z;

                    float u = (x / 256.0f);
                    float v = (z / 256.0f);
                    uvs.Add(new Vector2(u, v));
                }
            }

            List <int> trisList = new List <int>();

            for (int i = 0; i < triangles.Count; i++)
            {
                List <int> tris = triangles[i];
                trisList.AddRange(tris);
            }
            meshData.tristest = trisList.ToArray();
            return(meshData);
        }
예제 #3
0
 public StreamAndElement(NifMeshStream streamRef, NifStreamElement elem2, NiDataStream dataStream)
 {
     this.streamRef  = streamRef;
     elem            = elem2;
     this.dataStream = dataStream;
 }