public override void readData()
        {
            BinaryReader file = binaryFile.openReader();

            //holds references
            int reference;
            //Holds length of lists
            uint listLength;

            //Positions
            Vector3[] verts;
            //1st channel uvs
            Vector2[] uvs;
            //second channel (lightmap) uvs
            Vector2[] luvs;

            //Make sure this is not a FX mesh (instance stream is 0)

            file.BaseStream.Seek(binaryFile.dataOffset + binaryFile.structs[0].fields[5].index, SeekOrigin.Begin);
            if (file.ReadByte() != 0)
            {
                chunks = new MeshChunk[0];
                return;
            }

            //seek to the beginning of the data part of the file
            file.BaseStream.Seek(binaryFile.dataOffset, SeekOrigin.Begin);

            //get the reference to the name of the mesh
            //get the name of the mesh
            name = IOUtilities.readECString(file, binaryFile.dataOffset + file.ReadInt32());

            //Get the reference to the list of chunks
            file.BaseStream.Seek(binaryFile.dataOffset + binaryFile.structs[0].fields[1].index, SeekOrigin.Begin);
            reference = file.ReadInt32();

            file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin);
            listLength = file.ReadUInt32();

            //Save the current position for the loop
            long startPosition = file.BaseStream.Position;
            //Make an array of chunks of the correct size
            chunks = new MeshChunk[listLength];
            int triangleNum = 0;

            //Create all the chunks
            for (int i = 0; i < listLength; i++)
            {
                file.BaseStream.Seek(startPosition + (i * 4), SeekOrigin.Begin);
                file.BaseStream.Seek(binaryFile.dataOffset + file.ReadInt32(), SeekOrigin.Begin);
                chunks[i] = new MeshChunk(file, binaryFile.dataOffset, binaryFile.structs[4], binaryFile.structs[1]);
                triangleNum += (int)chunks[i].indexCount / 3;
            }

            triangleNum = 0;

            //Seek to the vertex data position
            file.BaseStream.Seek(binaryFile.dataOffset + binaryFile.structs[0].fields[2].index, SeekOrigin.Begin);
            //Get the reference to the list
            long vertexOffset = file.ReadUInt32() + binaryFile.dataOffset + 4;

            //Seek to the index data position
            file.BaseStream.Seek(binaryFile.dataOffset + binaryFile.structs[0].fields[3].index, SeekOrigin.Begin);
            //Get the reference to the list
            long indexOffset = file.ReadUInt32() + binaryFile.dataOffset + 4;
            //Index variables for triangles
            ushort index1, index2, index3;

            //For each chunk read in vertex data
            for (int i = 0; i < chunks.Length; i++)
            {
                verts = new Vector3[chunks[i].vertexCount];
                uvs = new Vector2[chunks[i].vertexCount];
                luvs = new Vector2[chunks[i].vertexCount];
                //Read in the vertex data
                for (int j = 0; j < chunks[i].vertexCount; j++)
                {
                    int vertArrayIndex = j * (chunks[i].vertexElementCount);
                    int positionIndex = vertArrayIndex;
                    int normalIndex = vertArrayIndex + 3;
                    int uvIndex = vertArrayIndex + 6;

                    long currentIndex = vertexOffset + chunks[i].vertexOffset + (chunks[i].vertexSize * j);
                    //Read in the positions
                    file.BaseStream.Seek(currentIndex + chunks[i].positionOffset, SeekOrigin.Begin);
                    //Put them in the vert array
                    verts[j] = new Vector3(IOUtilities.readFloat16(file), IOUtilities.readFloat16(file), IOUtilities.readFloat16(file));
                    //Put them in the chunk for easy rendering
                    chunks[i].verts[positionIndex] = verts[j].X;
                    chunks[i].verts[positionIndex + 1] = verts[j].Y;
                    chunks[i].verts[positionIndex + 2] = verts[j].Z;

                    //Read in the normals for rendering only, we make our own normals later
                    file.BaseStream.Seek(currentIndex + chunks[i].normalOffset, SeekOrigin.Begin);
                    chunks[i].verts[normalIndex] = IOUtilities.readFloat16(file);
                    chunks[i].verts[normalIndex + 1] = IOUtilities.readFloat16(file);
                    chunks[i].verts[normalIndex + 2] = IOUtilities.readFloat16(file);


                    //Read in the uvs
                    file.BaseStream.Seek(currentIndex + chunks[i].textureOffset, SeekOrigin.Begin);
                    uvs[j] = new Vector2(IOUtilities.readFloat16(file), IOUtilities.readFloat16(file));
                    //Put them in the chunk for easy rendering
                    chunks[i].verts[uvIndex] = uvs[j].X;
                    chunks[i].verts[uvIndex + 1] = uvs[j].Y;

                    //If there are a second set, read them in too
                    if (chunks[i].usesTwoTexCoords)
                    {
                        file.BaseStream.Seek(currentIndex + chunks[i].texture2Offset, SeekOrigin.Begin);
                        luvs[j] = new Vector2(IOUtilities.readFloat16(file), IOUtilities.readFloat16(file));
                    }
                }

                //Seek to index data (skipping the length int at beginning)
                file.BaseStream.Seek(indexOffset, SeekOrigin.Begin);
                for (int j = 0; j < chunks[i].indexCount / 3; j++)
                {
                    int indexIndex = j * 3;
                    //Read in the indices
                    index1 = file.ReadUInt16();
                    index2 = file.ReadUInt16();
                    index3 = file.ReadUInt16();

                    chunks[i].indices[indexIndex] = index1;
                    chunks[i].indices[indexIndex + 1] = index2;
                    chunks[i].indices[indexIndex + 2] = index3;

                    //If lightmap coords are specified make a triangle with them 
                    if (chunks[i].usesTwoTexCoords)
                        chunks[i].tris[j] = new Triangle(verts[index1], verts[index2], verts[index3], uvs[index1], uvs[index2], uvs[index3], luvs[index1], luvs[index2], luvs[index3]);
                    else
                        //Otherwise make one without them
                        chunks[i].tris[j] = new Triangle(verts[index1], verts[index2], verts[index3], uvs[index1], uvs[index2], uvs[index3]);

                    //Calculate the area of the triangle and add it to the total area of the mesh
                    chunks[i].area += 0.5 * Vector3.Cross(chunks[i].tris[j].y - chunks[i].tris[j].x, chunks[i].tris[j].z - chunks[i].tris[j].x).Length;
 
                    //Increase offset by 3 indices (2 bytes each)
                    indexOffset += 6;
                }
            }


            //Close the file
            file.Close();
        }
        public override void  readData()
        {
            int reference, length;
            long startOfList;

            //Get the binary reader
            BinaryReader file = binaryFile.openReader();
            //Set up the struct definitions
            setStructDefinitions();

            //Get the sector ID
            file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[SECTOR_ID_INDEX].index, SeekOrigin.Begin);
            _sectorID = file.ReadInt32();

            name = "Sector " + sectorID;




            /*----------MAP VERTS----------*/
            //Get the reference to the map vertex list and go there
            file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[MAP_VERTEX_LIST_INDEX].index, SeekOrigin.Begin);
            reference = file.ReadInt32();
            file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin);

            //Fill the map vertex list with all the map verts
            length = file.ReadInt32();
            _mapVerts = new List<TerrainMapVertex>(length);
            startOfList = file.BaseStream.Position;
            for (int i = 0; i < length; i++)
            {
                //Seek to the next struct in the list
                file.BaseStream.Seek(startOfList + (i * mapVertexStruct.structSize), SeekOrigin.Begin);
                //Add it to the list
                _mapVerts.Add(new TerrainMapVertex(mapVertexStruct, file));
            }




            /*----------MAP EDGES----------*/
            //Get the reference to the map edge list and go there
            file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[MAP_EDGE_LIST_INDEX].index, SeekOrigin.Begin);
            reference = file.ReadInt32();
            file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin);

            //Fill the map edge list with all the map edges
            length = file.ReadInt32();
            _mapEdges = new List<TerrainMapEdge>(length);
            startOfList = file.BaseStream.Position;
            TerrainMapEdge tempEdge;

            for (int i = 0; i < length; i++)
            {
                //Seek to the next struct in the list
                file.BaseStream.Seek(startOfList + (i * mapEdgeStruct.structSize), SeekOrigin.Begin);
                //Create the edge
                tempEdge = new TerrainMapEdge(mapEdgeStruct, file);
                //Get the actual index in the array of the map vert
                for (int j = 0; j < _mapVerts.Count; j++)
                {
                    if (_mapVerts[j].id == tempEdge.startVertexIndex)
                    {
                        tempEdge.startVertexIndex = j;
                        break;
                    }
                }
                //Add it to the list
                _mapEdges.Add(tempEdge);
            }




            /*----------MAP FACES----------*/
            //Get the reference to the map face list and go there
            file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[MAP_FACE_LIST_INDEX].index, SeekOrigin.Begin);
            reference = file.ReadInt32();
            file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin);

            //Fill the map face list with all the map faces
            length = file.ReadInt32();
            _mapFaces = new List<TerrainMapFace>(length);
            startOfList = file.BaseStream.Position;
            TerrainMapFace tempFace;

            for (int i = 0; i < length; i++)
            {
                //Seek to the next struct in the list
                file.BaseStream.Seek(startOfList + (i * mapFaceStruct.structSize), SeekOrigin.Begin);
                //Create the face
                tempFace = new TerrainMapFace(mapFaceStruct, file);
                //Find the actual edge indices
                for (int edgeIndex = 0; edgeIndex < 3; edgeIndex++)
                {
                    for (int j = 0; j < _mapEdges.Count; j++)
                    {
                        if (tempFace[edgeIndex] == _mapEdges[j].id)
                        {
                            tempFace[edgeIndex] = j;
                            break;
                        }
                    }
                }
                //Add it to the list
                _mapFaces.Add(tempFace);
            }




            /*----------MESH VERTS----------*/
            //Get the reference to the mesh vertex list and go there
            file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[MESH_VERTEX_LIST_INDEX].index, SeekOrigin.Begin);
            reference = file.ReadInt32();
            file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin);

            //Fill the vertex list with all the vertex
            length = file.ReadInt32();
            _verts = new List<TerrainMeshVertex>(length);
            startOfList = file.BaseStream.Position;
            for (int i = 0; i < length; i++)
            {
                //Seek to the next struct in the list
                file.BaseStream.Seek(startOfList + (i * meshVertexStruct.structSize), SeekOrigin.Begin);
                //Add it to the list
                _verts.Add(new TerrainMeshVertex(meshVertexStruct, file));
            }



            /*----------MESH EDGES----------*/
            //Get the reference to the mesh edge list and go there
            file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[MESH_EDGE_LIST_INDEX].index, SeekOrigin.Begin);
            reference = file.ReadInt32();
            file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin);

            //Fill the edge list with all the edge
            length = file.ReadInt32();
            _edges = new List<TerrainMeshEdge>(length);
            startOfList = file.BaseStream.Position;
            TerrainMeshEdge tempMeshEdge;

            for (int i = 0; i < length; i++)
            {
                //Seek to the next struct in the list
                file.BaseStream.Seek(startOfList + (i * meshEdgeStruct.structSize), SeekOrigin.Begin);
                //Create the edge
                tempMeshEdge = new TerrainMeshEdge(meshEdgeStruct, file);
                //Get the actual index in the array of the mesh vert
                for (int j = 0; j < _mapVerts.Count; j++)
                {
                    if (_verts[j].id == tempMeshEdge.startVertexIndex)
                    {
                        tempMeshEdge.startVertexIndex = j;
                        break;
                    }
                }
                //Add it to the list
                _edges.Add(tempMeshEdge);
            }




            /*----------MESH FACES----------*/
            //Get the reference to the mesh face list and go there
            file.BaseStream.Seek(binaryFile.dataOffset + infoStruct.fields[MESH_FACE_LIST_INDEX].index, SeekOrigin.Begin);
            reference = file.ReadInt32();
            file.BaseStream.Seek(binaryFile.dataOffset + reference, SeekOrigin.Begin);
            //Fill the face list with all the faces
            length = file.ReadInt32();
            _faces = new List<TerrainMeshFace>(length);
            startOfList = file.BaseStream.Position;
            TerrainMeshFace tempMeshFace;

            for (int i = 0; i < length; i++)
            {
                //Seek to the next struct in the list
                file.BaseStream.Seek(startOfList + (i * meshFaceStruct.structSize), SeekOrigin.Begin);
                //Make the face
                tempMeshFace = new TerrainMeshFace(meshFaceStruct, file);

                //Find the actual edge indices
                for (int edgeIndex = 0; edgeIndex < 3; edgeIndex++)
                {
                    for (int j = 0; j < _edges.Count; j++)
                    {
                        if (tempMeshFace[edgeIndex] == _edges[j].id)
                        {
                            tempMeshFace[edgeIndex] = j;
                            break;
                        }
                    }
                }
                //Find the actual map face index
                for (int j = 0; j < _mapFaces.Count; j++)
                {
                    if (tempMeshFace.mapId == _mapFaces[j].id)
                    {
                        tempMeshFace.mapId = j;
                        break;
                    }
                }
                //Add it to the list
                _faces.Add(tempMeshFace);
            }
            file.Close();

            chunks = new MeshChunk[1]; 
            Triangle[] tris = new Triangle[faces.Count];
            //Hold temporary vertex values
            Vector3 x, y, z;
            Vector2 u, v, w;

            //For each faces make a triangle
            for (int i = 0; i < faces.Count; i++)
            {
                //Get the mesh coordinates
                x = verts[edges[faces[i].edges[0]].startVertexIndex].position;
                y = verts[edges[faces[i].edges[1]].startVertexIndex].position;
                z = verts[edges[faces[i].edges[2]].startVertexIndex].position;

                //Get the map coordinates (lightmap coordinates are the same)
                u = mapVerts[mapEdges[mapFaces[faces[i].mapId].edges[0]].startVertexIndex].position.Xy;
                v = mapVerts[mapEdges[mapFaces[faces[i].mapId].edges[1]].startVertexIndex].position.Xy;
                w = mapVerts[mapEdges[mapFaces[faces[i].mapId].edges[2]].startVertexIndex].position.Xy;

                //Make the triangle
                tris[i] = new Triangle(x, y, z, u, v, w, u, v, w);
            }
            chunks[0] = new MeshChunk(tris);
            chunks[0].casts = true;
            chunks[0].receives = true;
        }
 public ModelMesh(MeshChunk[] meshChunks)
     : base()
 {
     chunks = meshChunks;
 }