int addFaceVerts(GEOMETRY_T geometry, dface_t face, Vector3[] verts, Vector2[] uvs, int verts_ofs, MIPTEX_DIRECTORY_ENTRY_T miptex_entry) { var edge_list = geometry.edge_list; var edges = geometry.edges; var vertices = geometry.vertices; var texinfo = geometry.texinfos[face.texinfo_id]; var tex_width = miptex_entry.width; var tex_height = miptex_entry.height; var vert_ids = new DynamicArray <int>(); var start = face.edge_id; var end = start + face.num_edges; int i; for (i = start; i < end; ++i) { var edge_id = edge_list[i]; var edge = edges[Math.Abs(edge_id)]; if (edge_id > 0) { vert_ids[vert_ids.length] = edge.v1; } else { vert_ids[vert_ids.length] = edge.v2; } } var num_tris = vert_ids.length - 2; for (i = 0; i < num_tris; ++i) { // reverse winding order to have correct normals var c = vert_ids[0]; var b = vert_ids[i + 1]; var a = vert_ids[i + 2]; int vi = (verts_ofs + i) * 3; int uvi = (verts_ofs + i) * 3; Vector3 vert = vertices[a]; verts[vi] = vert; uvs[uvi].x = (Vector3.Dot(vert, texinfo.vec_s) + texinfo.dist_s) / tex_width; uvs[uvi].y = -(Vector3.Dot(vert, texinfo.vec_t) + texinfo.dist_t) / tex_height; vert = vertices[b]; verts[vi + 1] = vert; uvs[uvi + 1].x = (Vector3.Dot(vert, texinfo.vec_s) + texinfo.dist_s) / tex_width; uvs[uvi + 1].y = -(Vector3.Dot(vert, texinfo.vec_t) + texinfo.dist_t) / tex_height; vert = vertices[c]; verts[vi + 2] = vert; uvs[uvi + 2].x = (Vector3.Dot(vert, texinfo.vec_s) + texinfo.dist_s) / tex_width; uvs[uvi + 2].y = -(Vector3.Dot(vert, texinfo.vec_t) + texinfo.dist_t) / tex_height; } return(verts_ofs + i); // next position in verts }
Vector3[] getVertices(GEOMETRY_T geometry, dface_t face) { // get number of triangles required to build model var num_tris = face.num_edges - 2; var verts = new Vector3[num_tris * 3]; // 3 vertices, xyz per tri this.getVertices(geometry, face, verts); return(verts); }
void getVertices(GEOMETRY_T geometry, dface_t face, Vector3[] verts) { var edge_list = geometry.edge_list; var edges = geometry.edges; var vertices = geometry.vertices; var vert_ids = new DynamicArray <int>(); var start = face.edge_id; var end = start + face.num_edges; int i; for (i = start; i < end; ++i) { var edge_id = edge_list[i]; var edge = edges[Math.Abs(edge_id)]; if (edge_id > 0) { vert_ids[vert_ids.length] = edge.v1; } else { vert_ids[vert_ids.length] = edge.v2; } } var num_tris = vert_ids.length - 2; for (i = 0; i < num_tris; ++i) { // reverse winding order to have correct normals var c = vert_ids[0]; var b = vert_ids[i + 1]; var a = vert_ids[i + 2]; int vi = i * 3; Vector3 vert = vertices[a]; verts[vi] = vert; vert = vertices[b]; verts[vi + 1] = vert; vert = vertices[c]; verts[vi + 2] = vert; } }
public dface_t[] GetFaces() { lump_t lump = lumps[7]; dface_t[] faces = new dface_t[lump.filelen / 56]; stream.Position = lump.fileofs; for (int i = 0; i < faces.Length; i++) { faces[i].planenum = FileReader.readUShort(stream); faces[i].side = FileReader.readByte(stream); faces[i].onNode = FileReader.readByte(stream); faces[i].firstedge = FileReader.readInt(stream); faces[i].numedges = FileReader.readShort(stream); faces[i].texinfo = FileReader.readShort(stream); faces[i].dispinfo = FileReader.readShort(stream); faces[i].surfaceFogVolumeID = FileReader.readShort(stream); faces[i].styles = new byte[4] { FileReader.readByte(stream), FileReader.readByte(stream), FileReader.readByte(stream), FileReader.readByte(stream) }; faces[i].lightofs = FileReader.readInt(stream); faces[i].area = FileReader.readFloat(stream); faces[i].LightmapTextureMinsInLuxels = new int[2] { FileReader.readInt(stream), FileReader.readInt(stream) }; faces[i].LightmapTextureSizeInLuxels = new int[2] { FileReader.readInt(stream), FileReader.readInt(stream) }; faces[i].origFace = FileReader.readInt(stream); faces[i].numPrims = FileReader.readUShort(stream); faces[i].firstPrimID = FileReader.readUShort(stream); faces[i].smoothingGroups = FileReader.readUInt(stream); } lumpData[7] = faces; return(faces); }
public virtual void Mod_LoadFaces(lump_t l) { qfiles.dface_t in_renamed; msurface_t[] out_renamed; Int32 i, count, surfnum; Int32 planenum, side; Int32 ti; if ((l.filelen % qfiles.dface_t.SIZE) != 0) { Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name); } count = l.filelen / qfiles.dface_t.SIZE; out_renamed = new msurface_t[count]; loadmodel.surfaces = out_renamed; loadmodel.numsurfaces = count; ByteBuffer bb = ByteBuffer.Wrap(mod_base, l.fileofs, l.filelen); bb.Order = ByteOrder.LittleEndian; currentmodel = loadmodel; GL_BeginBuildingLightmaps(loadmodel); for (surfnum = 0; surfnum < count; surfnum++) { in_renamed = new dface_t(bb); out_renamed[surfnum] = new msurface_t(); out_renamed[surfnum].firstedge = in_renamed.firstedge; out_renamed[surfnum].numedges = in_renamed.numedges; out_renamed[surfnum].flags = 0; out_renamed[surfnum].polys = null; planenum = in_renamed.planenum; side = in_renamed.side; if (side != 0) { out_renamed[surfnum].flags |= Defines.SURF_PLANEBACK; } out_renamed[surfnum].plane = loadmodel.planes[planenum]; ti = in_renamed.texinfo; if (ti < 0 || ti >= loadmodel.numtexinfo) { Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: bad texinfo number"); } out_renamed[surfnum].texinfo = loadmodel.texinfo[ti]; CalcSurfaceExtents(out_renamed[surfnum]); for (i = 0; i < Defines.MAXLIGHTMAPS; i++) { out_renamed[surfnum].styles[i] = in_renamed.styles[i]; } i = in_renamed.lightofs; if (i == -1) { out_renamed[surfnum].samples = null; } else { ByteBuffer pointer = ByteBuffer.Wrap(loadmodel.lightdata); pointer.Position = i; pointer = pointer.Slice(); pointer.Mark(); out_renamed[surfnum].samples = pointer; } if ((out_renamed[surfnum].texinfo.flags & Defines.SURF_WARP) != 0) { out_renamed[surfnum].flags |= Defines.SURF_DRAWTURB; for (i = 0; i < 2; i++) { out_renamed[surfnum].extents[i] = 16384; out_renamed[surfnum].texturemins[i] = -8192; } GL_SubdivideSurface(out_renamed[surfnum]); } if ((out_renamed[surfnum].texinfo.flags & (Defines.SURF_SKY | Defines.SURF_TRANS33 | Defines.SURF_TRANS66 | Defines.SURF_WARP)) == 0) { GL_CreateSurfaceLightmap(out_renamed[surfnum]); } if ((out_renamed[surfnum].texinfo.flags & Defines.SURF_WARP) == 0) { GL_BuildPolygonFromSurface(out_renamed[surfnum]); } } GL_EndBuildingLightmaps(); }
private Mesh MakeFaceMesh(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[Math.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 Triangulate List <int> triangleIndices = new List <int>(); 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; #endregion return(mesh); }
/*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); }
static void CreateModels() { BSP_Brushes = new List <GameObject>(); for (Int32 Index = 0; Index < BSP_Models.Length; Index++) { GameObject Model = new GameObject("*" + Index); Model.transform.parent = BSP_WorldSpawn.transform; Dictionary <Int32, List <Int32> > MeshInfo = new Dictionary <Int32, List <Int32> >(); for (Int32 i = BSP_Models[Index].FirstFace; i < BSP_Models[Index].FirstFace + BSP_Models[Index].NumFaces; i++) { if (!MeshInfo.ContainsKey(BSP_TexData[BSP_TexInfo[BSP_Faces[i].TexInfo].TexData].NameStringTableID)) { MeshInfo.Add(BSP_TexData[BSP_TexInfo[BSP_Faces[i].TexInfo].TexData].NameStringTableID, new List <Int32>()); } MeshInfo[BSP_TexData[BSP_TexInfo[BSP_Faces[i].TexInfo].TexData].NameStringTableID].Add(i); MeshInfo[BSP_TexData[BSP_TexInfo[BSP_Faces[i].TexInfo].TexData].NameStringTableID].Add(i); } for (Int32 i = 0; i < BSP_TextureStringData.Length; i++) { if (!MeshInfo.ContainsKey(i)) { continue; } List <Face> Faces = new List <Face>(); List <Vector3> Vertices = new List <Vector3>(); List <Color32> Colors = new List <Color32>(); List <Int32> Triangles = new List <Int32>(); List <Vector2> UV = new List <Vector2>(); for (Int32 j = 0; j < MeshInfo[i].Count; j++) { dface_t CFace = BSP_Faces[MeshInfo[i][j]]; if (CFace.DispInfo == -1) { Faces.Add(BSP_CFaces[MeshInfo[i][j]]); Int32 PointOffset = Vertices.Count; for (Int32 n = 0; n < Faces[j].Triangles.Length; n++) { Triangles.Add(Faces[j].Triangles[n] + PointOffset); } Vertices.AddRange(Faces[j].Vertices); Colors.AddRange(Faces[j].Colors); UV.AddRange(Faces[j].UV); } } GameObject MeshObject = new GameObject(BSP_TextureStringData[i]); MeshObject.transform.parent = Model.transform; MeshObject.isStatic = true; MeshRenderer MeshRenderer = MeshObject.AddComponent <MeshRenderer>(); MeshRenderer.sharedMaterial = MaterialLoader.Load(BSP_TextureStringData[i]); MeshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.TwoSided; MeshRenderer.lightmapIndex = ConfigLoader.CurrentLightmap; if (MaterialLoader.HasAnimation) { AnimatedTexture AnimationControlScript = MeshObject.AddComponent <AnimatedTexture>(); MaterialLoader.SetupAnimations(ref AnimationControlScript); } Mesh Mesh = MeshObject.AddComponent <MeshFilter>().sharedMesh = new Mesh(); Mesh.SetVertices(Vertices); Mesh.SetTriangles(Triangles, 0); Mesh.SetColors(Colors); Mesh.SetUVs(0, UV); if (BSP_TextureStringData[i].Contains("TOOLS/")) { MeshRenderer.enabled = false; BSP_Brushes.Add(MeshObject); } else { MeshObject.AddComponent <MeshCollider>(); List <Vector2> UV2 = new List <Vector2>(); Texture2D Lightmap_tex = new Texture2D(1, 1); CreateLightMap(Faces, ref Lightmap_tex, ref UV2); if (ConfigLoader.LoadLightmapsAsTextureShader) { if (MeshRenderer.sharedMaterial != null) { MeshRenderer.sharedMaterial.SetTexture("_LightMap", Lightmap_tex); } } Mesh.SetUVs(1, UV2); } Mesh.RecalculateNormals(); } } }
static void CreateFaces() { BSP_CFaces = new Face[BSP_Faces.Length]; for (Int32 Index = 0; Index < BSP_Faces.Length; Index++) { dface_t CFace = BSP_Faces[Index]; Vector3[] FaceVertices = new Vector3[CFace.NumEdges]; Vector2[] TextureUV = new Vector2[CFace.NumEdges], LightmapUV = new Vector2[CFace.NumEdges]; Color32[] VertColors = new Color32[CFace.NumEdges]; texinfo_t CTexinfo = BSP_TexInfo[CFace.TexInfo]; dtexdata_t CTexdata = BSP_TexData[CTexinfo.TexData]; for (Int32 i = CFace.FirstEdge, k = 0; i < CFace.FirstEdge + CFace.NumEdges; i++, k++) { FaceVertices[k] = BSP_Surfedges[i] > 0 ? BSP_Vertices[BSP_Edges[Mathf.Abs(BSP_Surfedges[i])].V[0]] : BSP_Vertices[BSP_Edges[Mathf.Abs(BSP_Surfedges[i])].V[1]]; VertColors[k] = new Color32(0, 0, 0, 0); } Int32[] FaceIndices = new int[(FaceVertices.Length - 1) * 3]; for (Int32 i = 1, k = 0; i < FaceVertices.Length - 1; i++, k += 3) { FaceIndices[k] = 0; FaceIndices[k + 1] = i; FaceIndices[k + 2] = i + 1; } Vector3 tS = new Vector3(-CTexinfo.TextureVecs[0].x, CTexinfo.TextureVecs[0].z, -CTexinfo.TextureVecs[0].y); Vector3 tT = new Vector3(-CTexinfo.TextureVecs[1].x, CTexinfo.TextureVecs[1].z, -CTexinfo.TextureVecs[1].y); /*for (Int32 i = 0; i < FaceVertices.Length; i++) * { * Single DecalS = (Vector3.Dot(FaceVertices[i], tS) + CTexinfo.TextureVecs[0].w * Configuration.WorldScale) / (CTexdata.View_Width * Configuration.WorldScale); * Single DecalT = (Vector3.Dot(FaceVertices[i], tT) + CTexinfo.TextureVecs[1].w * Configuration.WorldScale) / (CTexdata.View_Height * Configuration.WorldScale); * TextureUV[i] = new Vector2(DecalS, DecalT); * }*/ for (Int32 i = 0; i < FaceVertices.Length; i++) { Single NODRAWS = (Vector3.Dot(FaceVertices[i], tS) + CTexinfo.TextureVecs[0].w * ConfigLoader.WorldScale) / (CTexdata.View_Width * ConfigLoader.WorldScale); Single NODRAWT = (Vector3.Dot(FaceVertices[i], tT) + CTexinfo.TextureVecs[1].w * ConfigLoader.WorldScale) / (CTexdata.View_Height * ConfigLoader.WorldScale); TextureUV[i] = new Vector2(NODRAWS, NODRAWT); } Vector3 lS = new Vector3(-CTexinfo.LightmapVecs[0].x, CTexinfo.LightmapVecs[0].z, -CTexinfo.LightmapVecs[0].y); Vector3 lT = new Vector3(-CTexinfo.LightmapVecs[1].x, CTexinfo.LightmapVecs[1].z, -CTexinfo.LightmapVecs[1].y); for (Int32 i = 0; i < FaceVertices.Length; i++) { Single DecalS = (Vector3.Dot(FaceVertices[i], lS) + (CTexinfo.LightmapVecs[0].w + 0.5f - CFace.LightmapTextureMinsInLuxels[0]) * ConfigLoader.WorldScale) / ((CFace.LightmapTextureSizeInLuxels[0] + 1) * ConfigLoader.WorldScale); Single DecalT = (Vector3.Dot(FaceVertices[i], lT) + (CTexinfo.LightmapVecs[1].w + 0.5f - CFace.LightmapTextureMinsInLuxels[1]) * ConfigLoader.WorldScale) / ((CFace.LightmapTextureSizeInLuxels[1] + 1) * ConfigLoader.WorldScale); LightmapUV[i] = new Vector2(DecalS, DecalT); } BSP_CFaces[Index] = new Face { TexInfo = CTexinfo, TexData = CTexdata, Vertices = FaceVertices, Triangles = FaceIndices, Colors = VertColors, UV = TextureUV, UV2 = LightmapUV, LightOfs = CFace.LightOfs, LightMapW = CFace.LightmapTextureSizeInLuxels[0] + 1, LightMapH = CFace.LightmapTextureSizeInLuxels[1] + 1 }; } }
public dface_t[] GetOriginalFaces() { lump_t lump = lumps[27]; dface_t[] faces = new dface_t[lump.filelen / 56]; stream.Position = lump.fileofs; for (int i = 0; i < faces.Length; i++) { faces[i].planenum = FileReader.readUShort(stream); faces[i].side = FileReader.readByte(stream); faces[i].onNode = FileReader.readByte(stream); faces[i].firstedge = FileReader.readInt(stream); faces[i].numedges = FileReader.readShort(stream); faces[i].texinfo = FileReader.readShort(stream); faces[i].dispinfo = FileReader.readShort(stream); faces[i].surfaceFogVolumeID = FileReader.readShort(stream); faces[i].styles = new byte[4] { FileReader.readByte(stream), FileReader.readByte(stream), FileReader.readByte(stream), FileReader.readByte(stream) }; faces[i].lightofs = FileReader.readInt(stream); faces[i].area = FileReader.readFloat(stream); faces[i].LightmapTextureMinsInLuxels = new int[2] { FileReader.readInt(stream), FileReader.readInt(stream) }; faces[i].LightmapTextureSizeInLuxels = new int[2] { FileReader.readInt(stream), FileReader.readInt(stream) }; faces[i].origFace = FileReader.readInt(stream); faces[i].numPrims = FileReader.readUShort(stream); faces[i].firstPrimID = FileReader.readUShort(stream); faces[i].smoothingGroups = FileReader.readUInt(stream); } lumpData[27] = faces; return faces; }
// I'm not the author of this method. I translated it on С#. // http://trac.openscenegraph.org/projects/osg/browser/OpenSceneGraph/branches/OpenSceneGraph-osgWidget-dev/src/osgPlugins/bsp/VBSPGeometry.cpp?rev=9236 private static face CreateDispSurface(int dispIndex) { List <Vector3> faceVertices = new List <Vector3>(); List <Vector3> dispVertices = new List <Vector3>(); List <Int32> dispIndices = new List <int>(); List <Vector2> textureCoordinates = new List <Vector2>(); // List<Vector2> lightmapCoordinates = new List<Vector2>(); dface_t faceInfo = BSP_Faces[BSP_DispInfo[dispIndex].MapFace]; int minIndex = 0; for (int i = faceInfo.firstedge; i < (faceInfo.firstedge + faceInfo.numedges); i++) { faceVertices.Add((BSP_Surfedges[i] > 0 ? BSP_Vertices[BSP_Edges[Mathf.Abs(BSP_Surfedges[i])].v[0]] : BSP_Vertices[BSP_Edges[Mathf.Abs(BSP_Surfedges[i])].v[1]]) * WorldController.WorldScale); } float minDist = 1.0e9f; for (int i = 0; i < 4; i++) { float dist = (faceVertices[i] - BSP_DispInfo[dispIndex].startPosition * WorldController.WorldScale).magnitude; if (dist < minDist) { minDist = dist; minIndex = i; } } for (int i = 0; i < minIndex; i++) { Vector3 temp = faceVertices[0]; faceVertices[0] = faceVertices[1]; faceVertices[1] = faceVertices[2]; faceVertices[2] = faceVertices[3]; faceVertices[3] = temp; } Vector3 leftEdge = faceVertices[1] - faceVertices[0]; Vector3 rightEdge = faceVertices[2] - faceVertices[3]; int numEdgeVertices = (1 << BSP_DispInfo[dispIndex].power) + 1; float subdivideScale = 1.0f / (numEdgeVertices - 1); Vector3 leftEdgeStep = leftEdge * subdivideScale; Vector3 rightEdgeStep = rightEdge * subdivideScale; for (int i = 0; i < numEdgeVertices; i++) { Vector3 leftEnd = leftEdgeStep * i; leftEnd += faceVertices[0]; Vector3 rightEnd = rightEdgeStep * i; rightEnd += faceVertices[3]; Vector3 leftRightSeg = rightEnd - leftEnd; Vector3 leftRightStep = leftRightSeg * subdivideScale; for (int j = 0; j < numEdgeVertices; j++) { int dispVertIndex = BSP_DispInfo[dispIndex].DispVertStart; dispVertIndex += i * numEdgeVertices + j; dDispVert dispVertInfo = BSP_DispVerts[dispVertIndex]; Vector3 flatVertex = leftEnd + (leftRightStep * j); Vector3 dispVertex = dispVertInfo.vec * (dispVertInfo.dist * WorldController.WorldScale); dispVertex += flatVertex; texinfo_t faceTexinfo = BSP_Texinfo[faceInfo.texinfo]; float fU = Vector3.Dot(new Vector3(faceTexinfo.textureVecs[0].x, faceTexinfo.textureVecs[0].y, faceTexinfo.textureVecs[0].z), flatVertex) + faceTexinfo.textureVecs[0].w * WorldController.WorldScale; float fV = Vector3.Dot(new Vector3(faceTexinfo.textureVecs[1].x, faceTexinfo.textureVecs[1].y, faceTexinfo.textureVecs[1].z), flatVertex) + faceTexinfo.textureVecs[1].w * WorldController.WorldScale; fU /= (BSP_Texdata[faceTexinfo.texdata].width * WorldController.WorldScale); fV /= (BSP_Texdata[faceTexinfo.texdata].height * WorldController.WorldScale); textureCoordinates.Add(new Vector2(fU, fV)); dispVertices.Add(new Vector3(-dispVertex.x, dispVertex.z, dispVertex.y)); } } for (int i = 0; i < numEdgeVertices - 1; i++) { for (int j = 0; j < numEdgeVertices - 1; j++) { int index = i * numEdgeVertices + j; if ((index % 2) == 1) { dispIndices.Add(index); dispIndices.Add(index + 1); dispIndices.Add(index + numEdgeVertices); dispIndices.Add(index + 1); dispIndices.Add(index + numEdgeVertices + 1); dispIndices.Add(index + numEdgeVertices); } else { dispIndices.Add(index); dispIndices.Add(index + numEdgeVertices + 1); dispIndices.Add(index + numEdgeVertices); dispIndices.Add(index); dispIndices.Add(index + 1); dispIndices.Add(index + numEdgeVertices + 1); } } } return(new face() { index = BSP_DispInfo[dispIndex].MapFace, points = dispVertices.ToArray(), triangles = dispIndices.ToArray(), uv = textureCoordinates.ToArray() }); }
private Mesh MakeFaceMesh(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[Math.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 Triangulate List<int> triangleIndices = new List<int>(); 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; #endregion return mesh; }