コード例 #1
0
ファイル: BSPParser.cs プロジェクト: oxters168/ProjectMoretz
    public ddispinfo_t[] GetDispInfo()
    {
        lump_t lump = lumps[26];

        ddispinfo_t[] displacementInfo = new ddispinfo_t[lump.filelen / 86];
        stream.Position = lump.fileofs;

        for (int i = 0; i < displacementInfo.Length; i++)
        {
            displacementInfo[i].startPosition               = new Vector3(FileReader.readFloat(stream), FileReader.readFloat(stream), FileReader.readFloat(stream));
            displacementInfo[i].DispVertStart               = FileReader.readInt(stream);
            displacementInfo[i].DispTriStart                = FileReader.readInt(stream);
            displacementInfo[i].power                       = FileReader.readInt(stream);
            displacementInfo[i].minTess                     = FileReader.readInt(stream);
            displacementInfo[i].smoothingAngle              = FileReader.readFloat(stream);
            displacementInfo[i].contents                    = FileReader.readInt(stream);
            displacementInfo[i].MapFace                     = FileReader.readUShort(stream);
            displacementInfo[i].LightmapAlphaStart          = FileReader.readInt(stream);
            displacementInfo[i].LightmapSamplePositionStart = FileReader.readInt(stream);
            stream.Position += 90;
            displacementInfo[i].AllowedVerts = new uint[10] {
                FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream)
            };
        }

        lumpData[26] = displacementInfo;
        return(displacementInfo);
    }
コード例 #2
0
ファイル: BSPParser.cs プロジェクト: oxters168/ProjectMoretz
    public ddispinfo_t[] GetDispInfo()
    {
        lump_t lump = lumps[26];
        ddispinfo_t[] displacementInfo = new ddispinfo_t[lump.filelen / 86];
        stream.Position = lump.fileofs;

        for (int i = 0; i < displacementInfo.Length; i++)
        {
            displacementInfo[i].startPosition = new Vector3(FileReader.readFloat(stream), FileReader.readFloat(stream), FileReader.readFloat(stream));
            displacementInfo[i].DispVertStart = FileReader.readInt(stream);
            displacementInfo[i].DispTriStart = FileReader.readInt(stream);
            displacementInfo[i].power = FileReader.readInt(stream);
            displacementInfo[i].minTess = FileReader.readInt(stream);
            displacementInfo[i].smoothingAngle = FileReader.readFloat(stream);
            displacementInfo[i].contents = FileReader.readInt(stream);
            displacementInfo[i].MapFace = FileReader.readUShort(stream);
            displacementInfo[i].LightmapAlphaStart = FileReader.readInt(stream);
            displacementInfo[i].LightmapSamplePositionStart = FileReader.readInt(stream);
            stream.Position += 90;
            displacementInfo[i].AllowedVerts = new uint[10] { FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream), FileReader.readUInt(stream) };
        }

        lumpData[26] = displacementInfo;
        return displacementInfo;
    }
コード例 #3
0
ファイル: SourceParser.cs プロジェクト: maesse/CubeHags
        static void createDispSurface(Face face, ddispinfo_t dispInfo, World map, int faceIndex)
        {
            face.HasDisplacement = true;
            Face actualFace = face;
            int ndx = faceIndex;
            while (actualFace.face_t.origFace > 0 && actualFace.face_t.origFace != ndx)
            {
                ndx = actualFace.face_t.origFace;
                actualFace = world.faces_t[actualFace.face_t.origFace].face;
            }
            actualFace.HasDisplacement = true;
            actualFace.DisplaceFaces = new int[] { faceIndex };

            face.displace_offset = world.verts.Count;

            //// Get the texture vectors and offsets.  These are used to calculate
            //// texture coordinates
            Vector3 texU = new Vector3(face.texinfo.textureVecs[0].X,
                     face.texinfo.textureVecs[0].Y,
                     face.texinfo.textureVecs[0].Z);
            float texUOffset = face.texinfo.textureVecs[0].W;

            Vector3 texV = new Vector3(face.texinfo.textureVecs[1].X,
                     face.texinfo.textureVecs[1].Y,
                     face.texinfo.textureVecs[1].Z);
            float texVOffset = face.texinfo.textureVecs[1].W;

            // Get the base vertices for this face
            Vector3[] vertices = new Vector3[face.nVerts];
            for (int i = 0; i < face.nVerts; i++)
            {
                vertices[i] = world.verts[face.VertexOffset + i].position;
            }

            // Rotate the base coordinates for the surface until the first vertex
            // matches the start position
            float minDist = float.MaxValue;
            int minIndex = 0;
            for (int i = 0; i < 4; i++)
            {
                // Calculate the distance of the start position from this vertex
                float dist = (world.verts[face.VertexOffset + i].position - dispInfo.startPosition).Length();// * 0.0254f).Length();

                // If this is the smallest distance we've seen, remember it
                if (dist < minDist)
                {
                    minDist = dist;
                    minIndex = i;
                }
            }

            // Rotate the displacement surface quad until we get the starting vertex
            // in the 0th position
            for (int i = 0; i < minIndex; i++)
            {
                Vector3 temp = vertices[0];
                vertices[0] = vertices[1];
                vertices[1] = vertices[2];
                vertices[2] = vertices[3];
                vertices[3] = temp;
            }

            // Calculate the vectors for the left and right edges of the surface
            // (remembering that the surface is wound clockwise)
            Vector3 leftEdge = vertices[1] - vertices[0];
            Vector3 rightEdge = vertices[2] - vertices[3];

            // Calculate the number of vertices along each edge of the surface
            int numEdgeVertices = (1 << dispInfo.power) + 1;

            // Calculate the subdivide scale, which will tell us how far apart to
            // put each vertex (relative to the length of the surface's edges)
            double subdivideScale = 1.0f / (double)(numEdgeVertices - 1);

            // Calculate the step size between vertices on the left and right edges
            Vector3 leftEdgeStep = Vector3.Multiply(leftEdge, (float)subdivideScale);
            Vector3 rightEdgeStep = Vector3.Multiply(rightEdge, (float)subdivideScale);

            // Remember the first vertex index in the vertex array
            uint firstVertex = (uint)world.verts.Count;

            float lightdeltaU = (1f) / (numEdgeVertices - 1);
            float lightdeltaV = (1f) / (numEdgeVertices - 1);

            float texUScale = 1.0f / (float)face.texinfo.texdata_t.width;
            float texVScale = 1.0f / (float)face.texinfo.texdata_t.height;

            // Temporary lists for accumulating the pars of a full VertexPositionTexturedNormalLightmap
            List<Vector3> verts = new List<Vector3>();
            List<Vector2> texcoords = new List<Vector2>();
            List<Vector2> lightcoords = new List<Vector2>();

            // Generate the displaced vertices (this technique comes from the
            // Source SDK)
            for (int i = 0; i < numEdgeVertices; i++)
            {
                // Calculate the two endpoints for this section of the surface
                Vector3 leftEnd = Vector3.Multiply(leftEdgeStep, i);
                leftEnd += vertices[0];
                Vector3 rightEnd = Vector3.Multiply(rightEdgeStep, i);
                rightEnd += vertices[3];

                // Now, get the vector from left to right, and subdivide it as well
                Vector3 leftRightSeg = rightEnd - leftEnd;
                Vector3 leftRightStep = Vector3.Multiply(leftRightSeg, (float)subdivideScale);

                // Generate the vertices for this section
                for (int j = 0; j < numEdgeVertices; j++)
                {
                    // Get the displacement info for this vertex
                    uint dispVertIndex = (uint)Math.Abs(dispInfo.DispVertStart);
                    dispVertIndex += (uint)(i * numEdgeVertices + j);
                    dDispVert dispVertInfo = world.dispVerts[(int)dispVertIndex];

                    // Calculate the flat vertex
                    Vector3 flatVertex = leftRightStep;
                    flatVertex = Vector3.Multiply(flatVertex, j) + leftEnd;

                    // Calculate the displaced vertex
                    Vector3 dispVertex = dispVertInfo.vec;
                    dispVertex = Vector3.Multiply(dispVertex, (float)(dispVertInfo.dist)) + flatVertex;
                    verts.Add(dispVertex);

                    // Calculate the texture coordinates for this vertex.  Texture
                    // coordinates are calculated using a planar projection, so we need
                    // to use the non-displaced vertex position here
                    float u = Vector3.Dot(texU, flatVertex) + texUOffset;
                    u *= texUScale;
                    float v = Vector3.Dot(texV, flatVertex) + texVOffset;
                    v *= texVScale;
                    Vector2 texCoord = new Vector2(u, v);
                    texcoords.Add(texCoord);

                    // Generate lightmap coordinates
                    float lightmapU = (lightdeltaU * j * face.face_t.LightmapTextureSizeInLuxels[0]) + face.lightOffsetX + 0.5f; // pixel space
                    float lightmapV = (lightdeltaV * i * face.face_t.LightmapTextureSizeInLuxels[1]) + face.lightOffsetY + 0.5f; // pixel space
                    lightmapU /= LightmapSize.Width;
                    lightmapV /= LightmapSize.Height;
                    lightcoords.Add(new Vector2(lightmapU, lightmapV));

                    // Get the texture blend parameter for this vertex as well
                    //float eh = (float)(dispVertInfo.alpha / 255.0);
                }
            }

            List<Vector3> normals = new List<Vector3>();
            // Calculate normals at each vertex (this is adapted from the Source SDK,
            // including the two helper functions)
            for (int i = 0; i < numEdgeVertices; i++)
            {
                for (int j = 0; j < numEdgeVertices; j++)
                {
                    // See which of the 4 possible edges (left, up, right, or down) are
                    // incident on this vertex
                    byte edgeBits = 0;
                    for (int k = 0; k < 4; k++)
                    {
                        if (doesEdgeExist(j, i, (int)k, numEdgeVertices))
                            edgeBits |= (byte)(1 << (byte)k);
                    }

                    // Calculate the normal based on the adjacent edges
                    Vector3 normal = getNormalFromEdges(j, i, edgeBits,
                                                numEdgeVertices, verts);

                    // Add the normal to the normal array
                    normals.Add(normal);
                }
            }

            Vector3[] BBox = new Vector3[2];
            BBox[0] = Vector3.Zero;
            BBox[1] = Vector3.Zero;
            // Build real vertices && BBox
            for (int i = 0; i < verts.Count; i++)
            {
                BBox[0] = Vector3.Minimize(verts[i], BBox[0]);
                BBox[1] = Vector3.Maximize(verts[i], BBox[1]);
                VertexPositionNormalTexturedLightmap vert = new VertexPositionNormalTexturedLightmap(verts[i], normals[i], texcoords[i], lightcoords[i]);
                world.verts.Add(vert);
            }

            face.BBox = BBox;

            // Build indices
            List<uint> indices = new List<uint>();
            // Now, triangulate the surface (this technique comes from the Source SDK)
            for (int i = 0; i < numEdgeVertices - 1; i++)
            {
                for (int j = 0; j < numEdgeVertices - 1; j++)
                {
                    // Get the current vertex index (local to this surface)
                    uint index = (uint)(i * numEdgeVertices + j);
                    //if (index + numEdgeVertices + 1 + firstVertex > map.disp_vertex_array.Count - 1 || index + firstVertex < firstVertex)
                    //{
                    //    int test = 2;
                    //}
                    // See if this index is odd
                    if ((index % 2) == 1)
                    {
                        // Add the vertex offset (so we reference this surface's
                        // vertices in the array)
                        index += firstVertex;

                        // Create two triangles on this vertex from top-left to
                        // bottom-right
                        indices.Add((uint) index + 1);
                        indices.Add((uint) index);

                        indices.Add((uint) index + (uint)numEdgeVertices);
                        indices.Add((uint) index + (uint)numEdgeVertices + 1);
                        indices.Add((uint) index + 1);

                        indices.Add((uint)index + (uint)numEdgeVertices);
                    }
                    else
                    {
                        // Add the vertex offset (so we reference this surface's
                        // vertices in the array)
                        index += firstVertex;

                        // Create two triangles on this vertex from bottom-left to
                        // top-right
                        indices.Add((uint) index + (uint)numEdgeVertices + 1);
                        indices.Add((uint)index);

                        indices.Add((uint)index + (uint)numEdgeVertices);
                        indices.Add((uint)index + 1);
                        indices.Add((uint) index);

                        indices.Add((uint)index + (uint)numEdgeVertices + 1);
                    }
                }
                //face.VertexOffset = firstVertex;

            }

            face.nVerts = world.verts.Count - (int)firstVertex;
            face.indices = indices.ToArray();

            //face.nDisplace = map.disp_primitive_set.Count - face.displace_offset;
        }
コード例 #4
0
ファイル: SourceParser.cs プロジェクト: maesse/CubeHags
        static void LoadDisplacement(BinaryReader br, Header header)
        {
            // Read DispInfo
            br.BaseStream.Seek(header.lumps[26].fileofs, SeekOrigin.Begin);
            int nDispInfo = header.lumps[26].filelen / 176;
            world.DispIndexToFaceIndex = new int[nDispInfo];
            ddispinfo_t[] ddispinfos = new ddispinfo_t[nDispInfo];
            for (int i = 0; i < nDispInfo; i++)
            {
                br.BaseStream.Seek(header.lumps[26].fileofs + (i * 176), SeekOrigin.Begin);
                ddispinfo_t info = new ddispinfo_t();
                info.startPosition = SwapZY(new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()));
                info.DispVertStart = (int)br.ReadUInt32();
                info.DispTriStart = br.ReadInt32();
                info.power = br.ReadInt32();
                info.minTess = br.ReadInt32();
                info.smoothingAngle = br.ReadSingle();
                info.contents = br.ReadInt32();
                info.MapFace = br.ReadUInt16();

                info.LightmapAlphaStart = br.ReadInt32();
                info.LightmapSamplePositionStart = br.ReadInt32();

                info.EdgeNeighbors = new DisplaceNeighbor[4];
                for (int j = 0; j < 4; j++)
                {
                    DisplaceNeighbor dispNei = new DisplaceNeighbor();
                    dispNei.sub_neighbors = new DisplaceSubNeighbor[2];
                    for (int h = 0; h < 2; h++)
                    {
                        DisplaceSubNeighbor subNei = new DisplaceSubNeighbor();
                        subNei.neighbor_index = br.ReadUInt16();
                        subNei.neighbor_orient = br.ReadByte();
                        subNei.local_span = br.ReadByte();
                        subNei.neighbor_span = br.ReadByte();

                        dispNei.sub_neighbors[h] = subNei;
                    }

                    info.EdgeNeighbors[j] = dispNei;
                }
                info.CornerNeighbors = new DisplaceCornerNeighbor[4];
                for (int j = 0; j < 4; j++)
                {
                    DisplaceCornerNeighbor corner = new DisplaceCornerNeighbor();
                    corner.neighbor_indices = new ushort[] { br.ReadUInt16(), br.ReadUInt16(), br.ReadUInt16(), br.ReadUInt16() }; // 4
                    corner.neighbor_count = br.ReadByte();
                    info.CornerNeighbors[j] = corner;
                }
                info.AllowedVerts = new ulong[10];
                for (int j = 0; j < info.AllowedVerts.Length; j++)
                {
                    info.AllowedVerts[j] = br.ReadUInt64();
                }

                ddispinfos[i] = info;
            }
            world.ddispinfos = ddispinfos;

            // Read DispLIghtmapSamples
            br.BaseStream.Seek(header.lumps[34].fileofs, SeekOrigin.Begin);
            int nSamples = header.lumps[34].filelen;
            byte[] dispLightmapSamples = new byte[nSamples];
            for (int i = 0; i < nSamples; i++)
            {
                dispLightmapSamples[i] = br.ReadByte();
            }
            world.dispLightmapSamples = dispLightmapSamples;

            // Read DispVerts
            br.BaseStream.Seek(header.lumps[33].fileofs, SeekOrigin.Begin);
            int nDispVerts = header.lumps[33].filelen / 20;
            dDispVert[] dispVerts = new dDispVert[nDispVerts];
            for (int i = 0; i < nDispVerts; i++)
            {
                dDispVert vert = new dDispVert();
                vert.vec = SwapZY(new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()));
                vert.dist = br.ReadSingle();
                vert.alpha = br.ReadSingle();
                dispVerts[i] = vert;
            }
            world.dispVerts = dispVerts;

            // Read DispTris
            br.BaseStream.Seek(header.lumps[48].fileofs, SeekOrigin.Begin);
            int nDispTris = header.lumps[48].filelen / 2;
            dDispTri[] dispTris = new dDispTri[nDispTris];
            for (int i = 0; i < nDispTris; i++)
            {
                dDispTri vert = new dDispTri();
                vert.Tags = br.ReadUInt16();
                dispTris[i] = vert;
            }
            world.dispTris = dispTris;
        }
コード例 #5
0
ファイル: BSPMap.cs プロジェクト: skmasq/ProjectDeagle
    /*private string PatchName(string original)
     * {
     *  string prep = original.Replace("\\", "/");
     *  string directory = "";
     *  List<string> extensions = new List<string>();
     *  string patched = "";
     *  if (prep.LastIndexOf("/") > -1) directory = prep.Substring(0, prep.LastIndexOf("/") + 1);
     *  if (prep.LastIndexOf(".") > -1) extensions.Add(prep.Substring(prep.LastIndexOf(".") + 1));
     *  if (prep.LastIndexOf("/") > -1) patched = prep.Substring(prep.LastIndexOf("/") + 1);
     *  if (patched.LastIndexOf(".") > -1) patched = patched.Substring(0, patched.LastIndexOf("."));
     *  if (extensions.Count > 0 && extensions[0].Equals("vmt", System.StringComparison.InvariantCultureIgnoreCase)) extensions.Add("txt");
     *  //if (!Directory.Exists(directory)) Debug.Log(directory);
     *  while (patched.Length > 0)
     *  {
     *      try
     *      {
     *          //if(extension.Equals("vmt", System.StringComparison.InvariantCultureIgnoreCase)
     *          bool found = false;
     *          foreach (string extension in extensions)
     *          {
     *              if (File.Exists(directory + "/" + patched + "." + extension)) { prep = directory + "/" + patched + "." + extension; found = true; break; }
     *          }
     *          if (found) break;
     *          //string[] matches = new string[0];
     *          //if (Directory.Exists(directory)) matches = Directory.GetFiles(directory, patched + "." + extension);
     *          //else break;
     *          //if (matches.Length == 1) return matches[0].Replace("\\", "/").ToLower();
     *          //else if (matches.Length > 1) break;
     *      }
     *      catch (System.Exception e)
     *      {
     *          Debug.Log(e.Message);
     *      }
     *      patched = patched.Substring(0, patched.Length - 1);
     *  }
     *
     *  //if (!File.Exists(prep)) prep = original.Replace("\\", "/");
     *  return prep;
     * }*/
    /*private string PatchName(string rootPath, string original, string ext)
     * {
     *  string path = rootPath.Replace("\\", "/").ToLower();
     *  string prep = original.Replace("\\", "/").ToLower();
     *
     *  string subDir = "";
     *  List<string> extensions = new List<string>();
     *  string patched = "";
     *  extensions.Add(ext);
     *
     *  if (prep.LastIndexOf("/") > -1) subDir = prep.Substring(0, prep.LastIndexOf("/") + 1);
     *  if (prep.LastIndexOf("/") > -1) patched = prep.Substring(prep.LastIndexOf("/") + 1);
     *  else patched = prep;
     *
     *  if (extensions.Count > 0 && extensions[0].Equals("vmt", System.StringComparison.InvariantCultureIgnoreCase)) extensions.Add("txt");
     *
     *  while (patched.Length > 0)
     *  {
     *      try
     *      {
     *          bool found = false;
     *          foreach (string extension in extensions)
     *          {
     *              if (File.Exists(path + subDir + "/" + patched + "." + extension)) { prep = subDir + "/" + patched; found = true; break; }
     *          }
     *          if (found) break;
     *      }
     *      catch (System.Exception e)
     *      {
     *          Debug.Log(e.Message);
     *      }
     *
     *      patched = patched.Substring(0, patched.Length - 1);
     *  }
     *
     *  return prep;
     * }
     * private string PatchName(string original, string ext)
     * {
     *  //string path = rootPath.Replace("\\", "/").ToLower();
     *  string prep = original.Replace("\\", "/").ToLower();
     *
     *  string subDir = "";
     *  List<string> extensions = new List<string>();
     *  string patched = "";
     *  extensions.Add(ext);
     *
     *  if (prep.LastIndexOf("/") > -1) subDir = prep.Substring(0, prep.LastIndexOf("/") + 1);
     *  if (prep.LastIndexOf("/") > -1) patched = prep.Substring(prep.LastIndexOf("/") + 1);
     *  else patched = prep;
     *
     *  if (extensions.Count > 0 && extensions[0].Equals("vmt", System.StringComparison.InvariantCultureIgnoreCase)) extensions[0] = "txt";
     *
     *  while (patched.Length > 0)
     *  {
     *      try
     *      {
     *          bool found = false;
     *          //foreach (string extension in extensions)
     *          //{
     *              if (Resources.Load(subDir + "/" + patched) != null) { prep = subDir + "/" + patched; found = true; break; }
     *          //}
     *          if (found) break;
     *      }
     *      catch (System.Exception e)
     *      {
     *          Debug.Log(e.Message);
     *      }
     *
     *      patched = patched.Substring(0, patched.Length - 1);
     *  }
     *
     *  return prep;
     * }
     * private string RemoveMisleadingPath(string original)
     * {
     *  string goodPath = original.Substring(0);
     *  if (goodPath.IndexOf("maps/") > -1)
     *  {
     *      goodPath = goodPath.Substring(goodPath.IndexOf("maps/") + ("maps/").Length);
     *      goodPath = goodPath.Substring(goodPath.IndexOf("/") + 1);
     *      while (goodPath.LastIndexOf("_") > -1 && (goodPath.Substring(goodPath.LastIndexOf("_") + 1).StartsWith("-") || char.IsDigit(goodPath.Substring(goodPath.LastIndexOf("_") + 1)[0])))
     *      {
     *          goodPath = goodPath.Substring(0, goodPath.LastIndexOf("_"));
     *      }
     *  }
     *
     *  return goodPath.ToString();
     * }
     * public void DecreaseTextureSize(Texture2D texture, float maxSize)
     * {
     *  if (Mathf.Max(texture.width, texture.height) > maxSize)
     *  {
     *      float ratio = Mathf.Max(texture.width, texture.height) / maxSize;
     *      int decreasedWidth = (int)(texture.width / ratio), decreasedHeight = (int)(texture.height / ratio);
     *
     *      TextureScale.Point(texture, decreasedWidth, decreasedHeight);
     *  }
     * }
     * public void AverageTexture(Texture2D original)
     * {
     *  Color allColorsInOne = new Color();
     *  Color[] originalColors = original.GetPixels();
     *
     *  foreach (Color color in originalColors)
     *  {
     *      allColorsInOne.r += color.r;
     *      allColorsInOne.g += color.g;
     *      allColorsInOne.b += color.b;
     *      allColorsInOne.a += color.a;
     *  }
     *
     *  allColorsInOne.r /= originalColors.Length;
     *  allColorsInOne.g /= originalColors.Length;
     *  allColorsInOne.b /= originalColors.Length;
     *  allColorsInOne.a /= originalColors.Length;
     *
     *  original.Resize(16, 16);
     *  Color[] newColors = original.GetPixels();
     *  for (int i = 0; i < newColors.Length; i++)
     *  {
     *      newColors[i] = allColorsInOne;
     *  }
     *
     *  original.wrapMode = TextureWrapMode.Clamp;
     *  original.SetPixels(newColors);
     *  original.Apply();
     * }*/

    public Mesh MakeFace(dface_t face)
    {
        Mesh mesh = null;

        //texflags textureFlag = texflags.SURF_NODRAW;
        //try { textureFlag = ((texflags)texInfo[face.texinfo].flags); }
        //catch (System.Exception) { }

        #region Get all vertices of face
        List <Vector3> surfaceVertices  = new List <Vector3>();
        List <Vector3> originalVertices = new List <Vector3>();
        for (int i = 0; i < face.numedges; i++)
        {
            ushort[] currentEdge = edges[Mathf.Abs(surfedges[face.firstedge + i])].v;
            Vector3  point1 = vertices[currentEdge[0]], point2 = vertices[currentEdge[1]];
            point1 = new Vector3(point1.x, point1.z, point1.y);
            point2 = new Vector3(point2.x, point2.z, point2.y);

            if (surfedges[face.firstedge + i] >= 0)
            {
                if (surfaceVertices.IndexOf(point1) < 0)
                {
                    surfaceVertices.Add(point1);
                }
                originalVertices.Add(point1);
                if (surfaceVertices.IndexOf(point2) < 0)
                {
                    surfaceVertices.Add(point2);
                }
                originalVertices.Add(point2);
            }
            else
            {
                if (surfaceVertices.IndexOf(point2) < 0)
                {
                    surfaceVertices.Add(point2);
                }
                originalVertices.Add(point2);
                if (surfaceVertices.IndexOf(point1) < 0)
                {
                    surfaceVertices.Add(point1);
                }
                originalVertices.Add(point1);
            }
        }
        #endregion

        #region Apply Displacement
        if (face.dispinfo > -1)
        {
            ddispinfo_t disp  = dispInfo[face.dispinfo];
            int         power = Mathf.RoundToInt(Mathf.Pow(2, disp.power));

            List <Vector3> dispVertices = new List <Vector3>();
            Vector3        startingPosition = surfaceVertices[0];
            Vector3        topCorner = surfaceVertices[1], topRightCorner = surfaceVertices[2], rightCorner = surfaceVertices[3];

            #region Setting Orientation
            Vector3 dispStartingVertex = disp.startPosition;
            dispStartingVertex = new Vector3(dispStartingVertex.x, dispStartingVertex.z, dispStartingVertex.y);
            if (Vector3.Distance(dispStartingVertex, topCorner) < 0.01f)
            {
                Vector3 tempCorner = startingPosition;

                startingPosition = topCorner;
                topCorner        = topRightCorner;
                topRightCorner   = rightCorner;
                rightCorner      = tempCorner;
            }
            else if (Vector3.Distance(dispStartingVertex, rightCorner) < 0.01f)
            {
                Vector3 tempCorner = startingPosition;

                startingPosition = rightCorner;
                rightCorner      = topRightCorner;
                topRightCorner   = topCorner;
                topCorner        = tempCorner;
            }
            else if (Vector3.Distance(dispStartingVertex, topRightCorner) < 0.01f)
            {
                Vector3 tempCorner = startingPosition;

                startingPosition = topRightCorner;
                topRightCorner   = tempCorner;
                tempCorner       = rightCorner;
                rightCorner      = topCorner;
                topCorner        = tempCorner;
            }
            #endregion

            int orderNum = 0;
            #region Method 13 (The one and only two)
            Vector3 leftSide = (topCorner - startingPosition), rightSide = (topRightCorner - rightCorner);
            float   leftSideLineSegmentationDistance = leftSide.magnitude / power, rightSideLineSegmentationDistance = rightSide.magnitude / power;
            for (int line = 0; line < (power + 1); line++)
            {
                for (int point = 0; point < (power + 1); point++)
                {
                    Vector3 leftPoint      = (leftSide.normalized * line * leftSideLineSegmentationDistance) + startingPosition;
                    Vector3 rightPoint     = (rightSide.normalized * line * rightSideLineSegmentationDistance) + rightCorner;
                    Vector3 currentLine    = rightPoint - leftPoint;
                    Vector3 pointDirection = currentLine.normalized;
                    float   pointSideSegmentationDistance = currentLine.magnitude / power;

                    Vector3 pointA = leftPoint + (pointDirection * pointSideSegmentationDistance * point);

                    Vector3 dispDirectionA = dispVerts[disp.DispVertStart + orderNum].vec;
                    dispDirectionA = new Vector3(dispDirectionA.x, dispDirectionA.z, dispDirectionA.y);
                    dispVertices.Add(pointA + (dispDirectionA * dispVerts[disp.DispVertStart + orderNum].dist));
                    //Debug.DrawRay(pointA, dispDirectionA * dispVerts[disp.DispVertStart + orderNum].dist, Color.yellow, 1000000f);
                    orderNum++;
                }
            }
            #endregion

            #region Debug
            Vector3 centerPoint = Vector3.zero;
            for (int i = 0; i < surfaceVertices.Count; i++)
            {
                //Vector3 direction = dispVerts[dispVertIndex].vec;
                //Vector3 displaced = surfaceVertices[i] + direction * dispVerts[dispVertIndex].dist;
                //surfaceVertices[i] = displaced;
                //dispVertIndex++;

                centerPoint += surfaceVertices[i];
            }
            centerPoint /= surfaceVertices.Count;
            //surfaceVertices.Add(centerPoint);

            //Debug.DrawRay(centerPoint, faceUp * 500f, Color.green, 1000000f);
            //Debug.DrawRay(centerPoint, faceForward * 500f, Color.blue, 1000000f);
            //Debug.DrawRay(centerPoint, faceRight * 500f, Color.red, 1000000f);
            //Debug.Log("Starting Vert: " + dispVertIndex + " Center: " + centerPoint);

            //Debug.DrawRay(surfaceVertices[0], (new Vector3(dispVerts[disp.DispVertStart].vec.x, dispVerts[disp.DispVertStart].vec.z, dispVerts[disp.DispVertStart].vec.y)) * dispVerts[disp.DispVertStart].dist, Color.yellow, 1000000f);
            #endregion

            surfaceVertices = dispVertices;
        }
        #endregion

        #region Triangulate
        List <int> triangleIndices = new List <int>();

        if (face.dispinfo > -1)
        {
            ddispinfo_t disp  = dispInfo[face.dispinfo];
            int         power = Mathf.RoundToInt(Mathf.Pow(2, disp.power));

            #region Method 12 Triangulation
            for (int row = 0; row < power; row++)
            {
                for (int col = 0; col < power; col++)
                {
                    int currentLine   = row * (power + 1);
                    int nextLineStart = (row + 1) * (power + 1);

                    triangleIndices.Add(currentLine + col);
                    triangleIndices.Add(nextLineStart + col);
                    triangleIndices.Add(currentLine + col + 1);

                    triangleIndices.Add(currentLine + col + 1);
                    triangleIndices.Add(nextLineStart + col);
                    triangleIndices.Add(nextLineStart + col + 1);
                }
            }
            #endregion
        }
        else
        {
            for (int i = 0; i < (originalVertices.Count / 2) - 0; i++)
            {
                int firstOrigIndex = (i * 2), secondOrigIndex = (i * 2) + 1, thirdOrigIndex = 0;
                int firstIndex  = surfaceVertices.IndexOf(originalVertices[firstOrigIndex]);
                int secondIndex = surfaceVertices.IndexOf(originalVertices[secondOrigIndex]);
                int thirdIndex  = surfaceVertices.IndexOf(originalVertices[thirdOrigIndex]);

                triangleIndices.Add(firstIndex);
                triangleIndices.Add(secondIndex);
                triangleIndices.Add(thirdIndex);
            }
        }
        #endregion

        #region Get UV Points
        Vector3 s = Vector3.zero, t = Vector3.zero;
        float   xOffset = 0, yOffset = 0;

        try
        {
            s       = new Vector3(texInfo[face.texinfo].textureVecs[0][0], texInfo[face.texinfo].textureVecs[0][2], texInfo[face.texinfo].textureVecs[0][1]);
            t       = new Vector3(texInfo[face.texinfo].textureVecs[1][0], texInfo[face.texinfo].textureVecs[1][2], texInfo[face.texinfo].textureVecs[1][1]);
            xOffset = texInfo[face.texinfo].textureVecs[0][3];
            yOffset = texInfo[face.texinfo].textureVecs[1][3];
        }
        catch (System.Exception) { }

        Vector2[] uvPoints = new Vector2[surfaceVertices.Count];
        int       textureWidth = 0, textureHeight = 0;

        try { textureWidth = texData[texInfo[face.texinfo].texdata].width; textureHeight = texData[texInfo[face.texinfo].texdata].height; }
        catch (System.Exception) { }

        for (int i = 0; i < uvPoints.Length; i++)
        {
            uvPoints[i] = new Vector2((Vector3.Dot(surfaceVertices[i], s) + xOffset) / textureWidth, (textureHeight - (Vector3.Dot(surfaceVertices[i], t) + yOffset)) / textureHeight);
        }
        #endregion

        #region Make Mesh
        mesh           = new Mesh();
        mesh.name      = "Custom Mesh";
        mesh.vertices  = surfaceVertices.ToArray();
        mesh.triangles = triangleIndices.ToArray();
        mesh.uv        = uvPoints;
        mesh.RecalculateNormals();
        #endregion

        return(mesh);
    }