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); }
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; }
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; }
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; }
/*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); }