public MAPBrushSide(MAPBrushSide copy) { plane = new Plane(copy.Plane); triangle[0] = new Vector3D(copy.Triangle[0]); triangle[1] = new Vector3D(copy.Triangle[1]); triangle[2] = new Vector3D(copy.Triangle[2]); texture = copy.Texture; textureS = new Vector3D(copy.TextureS); textureT = new Vector3D(copy.TextureT); textureShiftS = copy.TextureShiftS; textureShiftT = copy.TextureShiftT; texRot = copy.TexRot; texScaleX = copy.TexScaleX; texScaleY = copy.TexScaleY; flags = copy.Flags; material = copy.Material; lgtScale = copy.LgtScale; lgtRot = copy.LgtRot; planeDefined = copy.DefinedByPlane; triangleDefined = copy.DefinedByTriangle; disp = copy.Displacement; }
/// <summary> /// Processes an <see cref="Entity"/> into a state where it can be output into a file that map editors can read. /// </summary> /// <param name="entity">The <see cref="Entity"/> to process.</param> /// <remarks>This method does not return anything, since the <see cref="Entity"/> object is modified by reference.</remarks> private void ProcessEntity(Entity entity) { int modelNumber = entity.modelNumber; // If this Entity has no modelNumber, then this is a no-op. No processing is needed. // A modelnumber of 0 indicates the world entity. if (modelNumber >= 0) { Model model = _bsp.models[modelNumber]; if (_bsp.brushes != null) { List <Brush> brushes = _bsp.GetBrushesInModel(model); if (brushes != null) { foreach (Brush brush in brushes) { MAPBrush result = ProcessBrush(brush, entity.origin); result.isWater |= (entity.className == "func_water"); if (_master.settings.brushesToWorld) { _bsp.entities.GetWithAttribute("classname", "worldspawn").brushes.Add(result); } else { entity.brushes.Add(result); } ++_itemsProcessed; ReportProgress(); } } } if (model.numLeafPatches > 0 && _bsp.markSurfaces != null && _bsp.patches != null) { HashSet <Patch> patches = new HashSet <Patch>(); List <long> leafPatchesInModel = _bsp.GetReferencedObjects <long>(model, "markSurfaces"); foreach (long leafPatch in leafPatchesInModel) { if (leafPatch >= 0) { patches.Add(_bsp.patches[(int)leafPatch]); } } foreach (Patch patch in patches) { if (_bsp.version != MapType.CoD || patch.patchType == 0) { MAPPatch mappatch = ProcessPatch(patch); MAPBrush newBrush = new MAPBrush(); newBrush.patch = mappatch; entity.brushes.Add(newBrush); } } } if (_bsp.faces != null) { List <Face> surfaces = _bsp.GetFacesInModel(model); foreach (Face face in surfaces) { if (face.displacement >= 0) { if (modelNumber != 0) { _master.Print("WARNING: Displacement not part of world in " + _bsp.MapNameNoExtension); } MAPDisplacement displacement = ProcessDisplacement(_bsp.dispInfos[face.displacement]); MAPBrush newBrush = face.CreateBrush(_bsp, 32); newBrush.sides[0].displacement = displacement; // If we are not decompiling to VMF, vis will need to skip this brush. newBrush.isDetail = true; entity.brushes.Add(newBrush); } else if (face.flags == 2) { MAPPatch patch = ProcessPatch(face); MAPBrush newBrush = new MAPBrush(); newBrush.patch = patch; entity.brushes.Add(newBrush); } else if ((_bsp.version == MapType.STEF2 || _bsp.version == MapType.STEF2Demo) && face.flags == 5) { if (modelNumber != 0) { _master.Print("WARNING: Terrain not part of world in " + _bsp.MapNameNoExtension); } MAPTerrainEF2 terrain = ProcessEF2Terrain(face); MAPBrush newBrush = new MAPBrush(); newBrush.ef2Terrain = terrain; entity.brushes.Add(newBrush); } } } // If this is model 0 (worldspawn) there are other things that need to be taken into account. if (modelNumber == 0) { if (_bsp.lodTerrains != null) { foreach (LODTerrain lodTerrain in _bsp.lodTerrains) { MAPTerrainMoHAA terrain = ProcessTerrainMoHAA(lodTerrain); MAPBrush newBrush = new MAPBrush(); newBrush.mohTerrain = terrain; entity.brushes.Add(newBrush); } } } entity.Remove("model"); } }
private string displacementToString(MAPDisplacement inDisplacement) { string output = " dispinfo" + (char) 0x0D + (char) 0x0A + " {" + (char) 0x0D + (char) 0x0A; output += (" \"power\" \"" + inDisplacement.Power + "\"" + (char) 0x0D + (char) 0x0A); output += (" \"startposition\" \"[" + inDisplacement.Start.X + " " + inDisplacement.Start.Y + " " + inDisplacement.Start.Z + "]\"" + (char) 0x0D + (char) 0x0A); output += (" \"elevation\" \"0\"" + (char) 0x0D + (char) 0x0A + " \"subdiv\" \"0\"" + (char) 0x0D + (char) 0x0A); string normals = " normals" + (char) 0x0D + (char) 0x0A + " {" + (char) 0x0D + (char) 0x0A; string distances = " distances" + (char) 0x0D + (char) 0x0A + " {" + (char) 0x0D + (char) 0x0A; string alphas = " alphas" + (char) 0x0D + (char) 0x0A + " {" + (char) 0x0D + (char) 0x0A; for (int i = 0; i < System.Math.Pow(2, inDisplacement.Power) + 1; i++) { normals += (" \"row" + i + "\" \""); distances += (" \"row" + i + "\" \""); alphas += (" \"row" + i + "\" \""); for (int j = 0; j < System.Math.Pow(2, inDisplacement.Power) + 1; j++) { normals += Math.Round(inDisplacement.getNormal(i, j).X, 6) + " " + Math.Round(inDisplacement.getNormal(i, j).Y, 6) + " " + Math.Round(inDisplacement.getNormal(i, j).Z, 6); distances += inDisplacement.getDist(i, j); alphas += inDisplacement.getAlpha(i, j); if (j < System.Math.Pow(2, inDisplacement.Power)) { normals += " "; distances += " "; alphas += " "; } } normals += ("\"" + (char) 0x0D + (char) 0x0A); distances += ("\"" + (char) 0x0D + (char) 0x0A); alphas += ("\"" + (char) 0x0D + (char) 0x0A); } output += (normals + " }" + (char) 0x0D + (char) 0x0A); output += (distances + " }" + (char) 0x0D + (char) 0x0A); output += (alphas + " }" + (char) 0x0D + (char) 0x0A); output += (" triangle_tags" + (char) 0x0D + (char) 0x0A + " {" + (char) 0x0D + (char) 0x0A + " }" + (char) 0x0D + (char) 0x0A); output += (" allowed_verts" + (char) 0x0D + (char) 0x0A + " {" + (char) 0x0D + (char) 0x0A + " \"10\" \""); for (int i = 0; i < 10; i++) { output += inDisplacement.AllowedVerts[i]; if (i < 9) { output += " "; } } output += ("\"" + (char) 0x0D + (char) 0x0A + " }" + (char) 0x0D + (char) 0x0A); output += (" }" + (char) 0x0D + (char) 0x0A); return output; }
private void ParseDisplacement(MAPDisplacement displacement, StringBuilder sb) { int numVertices = displacement.power * displacement.power; sb.Append("\t\t\tdispinfo\r\n\t\t\t{\r\n\t\t\t\t\"power\" \"") .Append(displacement.power) .Append("\"\r\n\t\t\t\t\"startposition\" \"[") .Append(displacement.start.x.ToString("###0.######", format)) .Append(" ") .Append(displacement.start.y.ToString("###0.######", format)) .Append(" ") .Append(displacement.start.z.ToString("###0.######", format)) .Append("]\"\r\n\t\t\t\t\"elevation\" \"0\"\r\n\t\t\t\t\"subdiv\" \"0\"\r\n\t\t\t\tnormals\r\n\t\t\t\t{\r\n"); for (int i = 0; i < displacement.normals.GetLength(0); ++i) { sb.Append("\t\t\t\t\t\"row") .Append(i) .Append("\" \""); for (int j = 0; j < displacement.normals.GetLength(1); ++j) { if (j > 0) { sb.Append(" "); } sb.Append(displacement.normals[i, j].x.ToString("###0.######", format)); sb.Append(" "); sb.Append(displacement.normals[i, j].y.ToString("###0.######", format)); sb.Append(" "); sb.Append(displacement.normals[i, j].z.ToString("###0.######", format)); } sb.Append("\"\r\n"); } sb.Append("\t\t\t\t}\r\n\t\t\t\tdistances\r\n\t\t\t\t{\r\n"); for (int i = 0; i < displacement.distances.GetLength(0); ++i) { sb.Append("\t\t\t\t\t\"row") .Append(i) .Append("\" \""); for (int j = 0; j < displacement.distances.GetLength(1); ++j) { if (j > 0) { sb.Append(" "); } sb.Append(displacement.distances[i, j].ToString("###0.####", format)); } sb.Append("\"\r\n"); } sb.Append("\t\t\t\t}\r\n\t\t\t\talphas\r\n\t\t\t\t{\r\n"); for (int i = 0; i < displacement.alphas.GetLength(0); ++i) { sb.Append("\t\t\t\t\t\"row") .Append(i) .Append("\" \""); for (int j = 0; j < displacement.alphas.GetLength(1); ++j) { if (j > 0) { sb.Append(" "); } sb.Append(displacement.alphas[i, j].ToString(format)); } sb.Append("\"\r\n"); } sb.Append("\t\t\t\t}\r\n\t\t\t\ttriangle_tags\r\n\t\t\t\t{\r\n\t\t\t\t}\r\n\t\t\t\ttriangle_tags\r\n\t\t\t\t{\r\n\t\t\t\t\t\"10\" \"-1 -1 -1 -1 -1 -1 -1 -1 -1 -1\"\r\n\t\t\t\t}\r\n\t\t\t}\r\n"); }
// METHODS // Attempt to turn the BSP into a .MAP file public virtual Entities decompile() { DecompilerThread.OnMessage(this, "Decompiling..."); // In the decompiler, it is not necessary to copy all entities to a new object, since // no writing is ever done back to the BSP file. mapFile = BSPObject.Entities; //int numAreaPortals=0; int numTotalItems = 0; int onePercent = (int)((BSPObject.Brushes.Count + BSPObject.Entities.Count)/100); if(onePercent < 1) { onePercent = 1; } int originalNumEntities = BSPObject.Entities.Count; // Need to keep track of this in this algorithm, since I create more entities on the fly for (int i = 0; i < originalNumEntities; i++) { // For each entity //DecompilerThread.OnMessage(this, "Entity " + i + ": " + mapFile[i]["classname"]); // getModelNumber() returns 0 for worldspawn, the *# for brush based entities, and -1 for everything else int currentModel = mapFile[i].ModelNumber; if (currentModel > - 1) { // If this is still -1 then it's strictly a point-based entity. Move on to the next one. Leaf[] leaves = BSPObject.getLeavesInModel(currentModel); int numLeaves = leaves.Length; bool[] brushesUsed = new bool[BSPObject.Brushes.Count]; // Keep a list of brushes already in the model, since sometimes the leaves lump references one brush several times numBrshs = 0; // Reset the brush count for each entity for (int j = 0; j < numLeaves; j++) { // For each leaf in the bunch Leaf currentLeaf = leaves[j]; int firstMarkBrushIndex = currentLeaf.FirstMarkBrush; int numBrushIndices = currentLeaf.NumMarkBrushes; if (numBrushIndices > 0) { // A lot of leaves reference no brushes. If this is one, this iteration of the j loop is finished for (int k = 0; k < numBrushIndices; k++) { // For each brush referenced long currentBrushIndex = BSPObject.MarkBrushes[firstMarkBrushIndex + k]; if (!brushesUsed[(int) currentBrushIndex]) { // If the current brush has NOT been used in this entity //Console.Write("Brush " + numBrshs); brushesUsed[(int) currentBrushIndex] = true; Brush brush = BSPObject.Brushes[(int) currentBrushIndex]; decompileBrush(brush, i); // Decompile the brush numBrshs++; numTotalItems++; if(numTotalItems%onePercent == 0) { parent.OnProgress(this, numTotalItems/(double)(BSPObject.Brushes.Count + BSPObject.Entities.Count)); } } } } } } numTotalItems++; // This entity if(numTotalItems%onePercent == 0) { parent.OnProgress(this, numTotalItems/(double)(BSPObject.Brushes.Count + BSPObject.Entities.Count)); } } // Find displacement faces and generate brushes for them for (int i = 0; i < BSPObject.Faces.Count; i++) { Face face = BSPObject.Faces[i]; if (face.Displacement > - 1) { SourceDispInfo disp = BSPObject.DispInfos[face.Displacement]; TexInfo currentTexInfo; if (face.Texture > - 1) { currentTexInfo = BSPObject.TexInfo[face.Texture]; } else { Vector3D[] axes = TexInfo.textureAxisFromPlane(BSPObject.Planes[face.Plane]); currentTexInfo = new TexInfo(axes[0], 0, axes[1], 0, 0, BSPObject.findTexDataWithTexture("tools/toolsclip")); } SourceTexData currentTexData = BSPObject.TexDatas[currentTexInfo.Texture]; string texture = BSPObject.Textures.getTextureAtOffset((uint)BSPObject.TexTable[currentTexData.StringTableIndex]); double[] textureU = new double[3]; double[] textureV = new double[3]; // Get the lengths of the axis vectors double SAxisLength = System.Math.Sqrt(System.Math.Pow((double) currentTexInfo.SAxis.X, 2) + System.Math.Pow((double) currentTexInfo.SAxis.Y, 2) + System.Math.Pow((double) currentTexInfo.SAxis.Z, 2)); double TAxisLength = System.Math.Sqrt(System.Math.Pow((double) currentTexInfo.TAxis.X, 2) + System.Math.Pow((double) currentTexInfo.TAxis.Y, 2) + System.Math.Pow((double) currentTexInfo.TAxis.Z, 2)); // In compiled maps, shorter vectors=longer textures and vice versa. This will convert their lengths back to 1. We'll use the actual scale values for length. double texScaleU = (1 / SAxisLength); // Let's use these values using the lengths of the U and V axes we found above. double texScaleV = (1 / TAxisLength); textureU[0] = ((double) currentTexInfo.SAxis.X / SAxisLength); textureU[1] = ((double) currentTexInfo.SAxis.Y / SAxisLength); textureU[2] = ((double) currentTexInfo.SAxis.Z / SAxisLength); //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextSettingsIndex'&keyword='jlca1042'" double textureShiftU = (double) currentTexInfo.SShift; textureV[0] = ((double) currentTexInfo.TAxis.X / TAxisLength); textureV[1] = ((double) currentTexInfo.TAxis.Y / TAxisLength); textureV[2] = ((double) currentTexInfo.TAxis.Z / TAxisLength); //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextSettingsIndex'&keyword='jlca1042'" double textureShiftV = (double) currentTexInfo.TShift; if (face.NumEdges != 4) { DecompilerThread.OnMessage(this, "Displacement face with " + face.NumEdges + " edges!"); } // Turn vertices and edges into arrays of vectors Vector3D[] froms = new Vector3D[face.NumEdges]; Vector3D[] tos = new Vector3D[face.NumEdges]; for (int j = 0; j < face.NumEdges; j++) { if (BSPObject.SurfEdges[face.FirstEdge + j] > 0) { froms[j] = BSPObject.Vertices[BSPObject.Edges[(int)BSPObject.SurfEdges[face.FirstEdge + j]].FirstVertex].Vector; tos[j] = BSPObject.Vertices[BSPObject.Edges[(int)BSPObject.SurfEdges[face.FirstEdge + j]].SecondVertex].Vector; } else { tos[j] = BSPObject.Vertices[BSPObject.Edges[(int) BSPObject.SurfEdges[face.FirstEdge + j] * (- 1)].FirstVertex].Vector; froms[j] = BSPObject.Vertices[BSPObject.Edges[(int) BSPObject.SurfEdges[face.FirstEdge + j] * (- 1)].SecondVertex].Vector; } } MAPBrush displacementBrush = MAPBrush.createBrushFromWind(froms, tos, texture, "TOOLS/TOOLSNODRAW", currentTexInfo); MAPDisplacement mapdisp = new MAPDisplacement(disp, BSPObject.DispVerts.getVertsInDisp(disp.DispVertStart, disp.Power)); displacementBrush[0].Displacement = mapdisp; mapFile[0].Brushes.Add(displacementBrush); } } for (int i = 0; i < BSPObject.StaticProps.Count; i++) { Entity newStaticProp = new Entity("prop_static"); SourceStaticProp currentProp = BSPObject.StaticProps[i]; newStaticProp["model"] = BSPObject.StaticProps.Dictionary[currentProp.DictionaryEntry]; newStaticProp["skin"] = currentProp.Skin + ""; newStaticProp["origin"] = currentProp.Origin.X + " " + currentProp.Origin.Y + " " + currentProp.Origin.Z; newStaticProp["angles"] = currentProp.Angles.X + " " + currentProp.Angles.Y + " " + currentProp.Angles.Z; newStaticProp["solid"] = currentProp.Solidity + ""; newStaticProp["fademindist"] = currentProp.MinFadeDist + ""; newStaticProp["fademaxdist"] = currentProp.MaxFadeDist + ""; newStaticProp["fadescale"] = currentProp.ForcedFadeScale + ""; if (currentProp.Targetname != null) { newStaticProp["targetname"] = currentProp.Targetname; } mapFile.Add(newStaticProp); } for (int i = 0; i < BSPObject.Cubemaps.Count; i++) { Entity newCubemap = new Entity("env_cubemap"); SourceCubemap currentCube = BSPObject.Cubemaps[i]; newCubemap["origin"] = currentCube.Origin.X + " " + currentCube.Origin.Y + " " + currentCube.Origin.Z; newCubemap["cubemapsize"] = currentCube.Size + ""; mapFile.Add(newCubemap); } if (!Settings.skipPlaneFlip) { DecompilerThread.OnMessage(this, "Num simple corrected brushes: " + numSimpleCorrects); DecompilerThread.OnMessage(this, "Num advanced corrected brushes: " + numAdvancedCorrects); DecompilerThread.OnMessage(this, "Num good brushes: " + numGoodBrushes); } parent.OnProgress(this, 1.0); return mapFile; }
// METHODS // Attempt to turn the BSP into a .MAP file public virtual Entities decompile() { DecompilerThread.OnMessage(this, "Decompiling..."); // In the decompiler, it is not necessary to copy all entities to a new object, since // no writing is ever done back to the BSP file. mapFile = BSPObject.Entities; //int numAreaPortals=0; int numTotalItems = 0; int onePercent = (int)((BSPObject.Brushes.Count + BSPObject.Entities.Count) / 100); if (onePercent < 1) { onePercent = 1; } int originalNumEntities = BSPObject.Entities.Count; // Need to keep track of this in this algorithm, since I create more entities on the fly for (int i = 0; i < originalNumEntities; i++) { // For each entity //DecompilerThread.OnMessage(this, "Entity " + i + ": " + mapFile[i]["classname"]); // getModelNumber() returns 0 for worldspawn, the *# for brush based entities, and -1 for everything else int currentModel = mapFile[i].ModelNumber; if (currentModel > -1) // If this is still -1 then it's strictly a point-based entity. Move on to the next one. { Leaf[] leaves = BSPObject.getLeavesInModel(currentModel); int numLeaves = leaves.Length; bool[] brushesUsed = new bool[BSPObject.Brushes.Count]; // Keep a list of brushes already in the model, since sometimes the leaves lump references one brush several times numBrshs = 0; // Reset the brush count for each entity for (int j = 0; j < numLeaves; j++) { // For each leaf in the bunch Leaf currentLeaf = leaves[j]; int firstMarkBrushIndex = currentLeaf.FirstMarkBrush; int numBrushIndices = currentLeaf.NumMarkBrushes; if (numBrushIndices > 0) { // A lot of leaves reference no brushes. If this is one, this iteration of the j loop is finished for (int k = 0; k < numBrushIndices; k++) { // For each brush referenced long currentBrushIndex = BSPObject.MarkBrushes[firstMarkBrushIndex + k]; if (!brushesUsed[(int)currentBrushIndex]) { // If the current brush has NOT been used in this entity //Console.Write("Brush " + numBrshs); brushesUsed[(int)currentBrushIndex] = true; Brush brush = BSPObject.Brushes[(int)currentBrushIndex]; decompileBrush(brush, i); // Decompile the brush numBrshs++; numTotalItems++; if (numTotalItems % onePercent == 0) { parent.OnProgress(this, numTotalItems / (double)(BSPObject.Brushes.Count + BSPObject.Entities.Count)); } } } } } } numTotalItems++; // This entity if (numTotalItems % onePercent == 0) { parent.OnProgress(this, numTotalItems / (double)(BSPObject.Brushes.Count + BSPObject.Entities.Count)); } } // Find displacement faces and generate brushes for them for (int i = 0; i < BSPObject.Faces.Count; i++) { Face face = BSPObject.Faces[i]; if (face.Displacement > -1) { SourceDispInfo disp = BSPObject.DispInfos[face.Displacement]; TexInfo currentTexInfo; if (face.Texture > -1) { currentTexInfo = BSPObject.TexInfo[face.Texture]; } else { Vector3D[] axes = TexInfo.textureAxisFromPlane(BSPObject.Planes[face.Plane]); currentTexInfo = new TexInfo(axes[0], 0, axes[1], 0, 0, BSPObject.findTexDataWithTexture("tools/toolsclip")); } SourceTexData currentTexData = BSPObject.TexDatas[currentTexInfo.Texture]; string texture = BSPObject.Textures.getTextureAtOffset((uint)BSPObject.TexTable[currentTexData.StringTableIndex]); double[] textureU = new double[3]; double[] textureV = new double[3]; // Get the lengths of the axis vectors double SAxisLength = System.Math.Sqrt(System.Math.Pow((double)currentTexInfo.SAxis.X, 2) + System.Math.Pow((double)currentTexInfo.SAxis.Y, 2) + System.Math.Pow((double)currentTexInfo.SAxis.Z, 2)); double TAxisLength = System.Math.Sqrt(System.Math.Pow((double)currentTexInfo.TAxis.X, 2) + System.Math.Pow((double)currentTexInfo.TAxis.Y, 2) + System.Math.Pow((double)currentTexInfo.TAxis.Z, 2)); // In compiled maps, shorter vectors=longer textures and vice versa. This will convert their lengths back to 1. We'll use the actual scale values for length. double texScaleU = (1 / SAxisLength); // Let's use these values using the lengths of the U and V axes we found above. double texScaleV = (1 / TAxisLength); textureU[0] = ((double)currentTexInfo.SAxis.X / SAxisLength); textureU[1] = ((double)currentTexInfo.SAxis.Y / SAxisLength); textureU[2] = ((double)currentTexInfo.SAxis.Z / SAxisLength); //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextSettingsIndex'&keyword='jlca1042'" double textureShiftU = (double)currentTexInfo.SShift; textureV[0] = ((double)currentTexInfo.TAxis.X / TAxisLength); textureV[1] = ((double)currentTexInfo.TAxis.Y / TAxisLength); textureV[2] = ((double)currentTexInfo.TAxis.Z / TAxisLength); //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextSettingsIndex'&keyword='jlca1042'" double textureShiftV = (double)currentTexInfo.TShift; if (face.NumEdges != 4) { DecompilerThread.OnMessage(this, "Displacement face with " + face.NumEdges + " edges!"); } // Turn vertices and edges into arrays of vectors Vector3D[] froms = new Vector3D[face.NumEdges]; Vector3D[] tos = new Vector3D[face.NumEdges]; for (int j = 0; j < face.NumEdges; j++) { if (BSPObject.SurfEdges[face.FirstEdge + j] > 0) { froms[j] = BSPObject.Vertices[BSPObject.Edges[(int)BSPObject.SurfEdges[face.FirstEdge + j]].FirstVertex].Vector; tos[j] = BSPObject.Vertices[BSPObject.Edges[(int)BSPObject.SurfEdges[face.FirstEdge + j]].SecondVertex].Vector; } else { tos[j] = BSPObject.Vertices[BSPObject.Edges[(int)BSPObject.SurfEdges[face.FirstEdge + j] * (-1)].FirstVertex].Vector; froms[j] = BSPObject.Vertices[BSPObject.Edges[(int)BSPObject.SurfEdges[face.FirstEdge + j] * (-1)].SecondVertex].Vector; } } MAPBrush displacementBrush = MAPBrush.createBrushFromWind(froms, tos, texture, "TOOLS/TOOLSNODRAW", currentTexInfo); MAPDisplacement mapdisp = new MAPDisplacement(disp, BSPObject.DispVerts.getVertsInDisp(disp.DispVertStart, disp.Power)); displacementBrush[0].Displacement = mapdisp; mapFile[0].Brushes.Add(displacementBrush); } } for (int i = 0; i < BSPObject.StaticProps.Count; i++) { Entity newStaticProp = new Entity("prop_static"); SourceStaticProp currentProp = BSPObject.StaticProps[i]; newStaticProp["model"] = BSPObject.StaticProps.Dictionary[currentProp.DictionaryEntry]; newStaticProp["skin"] = currentProp.Skin + ""; newStaticProp["origin"] = currentProp.Origin.X + " " + currentProp.Origin.Y + " " + currentProp.Origin.Z; newStaticProp["angles"] = currentProp.Angles.X + " " + currentProp.Angles.Y + " " + currentProp.Angles.Z; newStaticProp["solid"] = currentProp.Solidity + ""; newStaticProp["fademindist"] = currentProp.MinFadeDist + ""; newStaticProp["fademaxdist"] = currentProp.MaxFadeDist + ""; newStaticProp["fadescale"] = currentProp.ForcedFadeScale + ""; if (currentProp.Targetname != null) { newStaticProp["targetname"] = currentProp.Targetname; } mapFile.Add(newStaticProp); } for (int i = 0; i < BSPObject.Cubemaps.Count; i++) { Entity newCubemap = new Entity("env_cubemap"); SourceCubemap currentCube = BSPObject.Cubemaps[i]; newCubemap["origin"] = currentCube.Origin.X + " " + currentCube.Origin.Y + " " + currentCube.Origin.Z; newCubemap["cubemapsize"] = currentCube.Size + ""; mapFile.Add(newCubemap); } if (!Settings.skipPlaneFlip) { DecompilerThread.OnMessage(this, "Num simple corrected brushes: " + numSimpleCorrects); DecompilerThread.OnMessage(this, "Num advanced corrected brushes: " + numAdvancedCorrects); DecompilerThread.OnMessage(this, "Num good brushes: " + numGoodBrushes); } parent.OnProgress(this, 1.0); return(mapFile); }
public MAPBrushSide(MAPBrushSide copy) { plane = new Plane(copy.Plane); triangle[0] = new Vector3D(copy.Triangle[0]); triangle[1] = new Vector3D(copy.Triangle[1]); triangle[2] = new Vector3D(copy.Triangle[2]); texture = copy.Texture; textureS = new Vector3D(copy.TextureS); textureT = new Vector3D(copy.TextureT); textureShiftS = copy.TextureShiftS; textureShiftT = copy.TextureShiftT; texRot = copy.TexRot; texScaleX = copy.TexScaleX; texScaleY = copy.TexScaleY; flags = copy.Flags; material = copy.Material; lgtScale = copy.LgtScale; lgtRot = copy.LgtRot; planeDefined = copy.DefinedByPlane; triangleDefined = copy.DefinedByTriangle; disp = copy.Displacement; }