/// <summary>
 /// Postprocesser to convert the texture referenced by <paramref name="patch"/> into one used by GTKRadiant, if necessary.
 /// </summary>
 /// <param name="patch">The <see cref="MAPPatch"/> to have its texture parsed.</param>
 private void PostProcessQuake3Texture(MAPPatch patch)
 {
     if (patch.texture.Length >= 9 && patch.texture.Substring(0, 9).Equals("textures/", StringComparison.InvariantCultureIgnoreCase))
     {
         patch.texture = patch.texture.Substring(9);
     }
 }
 /// <summary>
 /// Process the data in a <see cref="MAPPatch"/> into the passed <see cref="StringBuilder"/>.
 /// </summary>
 /// <param name="patch">The <see cref="MAPPatch"/> to process.</param>
 /// <param name="sb">A <see cref="StringBuilder"/> object to append processed data from <paramref name="patch"/> to.</param>
 private void ParsePatch(MAPPatch patch, StringBuilder sb)
 {
     sb.Append(" {\r\n  patchDef2\r\n  {\r\n")
     .Append(patch.texture)
     .Append("\r\n( ")
     .Append((int)Math.Round(patch.dims.x))
     .Append(" ")
     .Append((int)Math.Round(patch.dims.y))
     .Append(" 0 0 0 )\r\n(\r\n");
     for (int i = 0; i < patch.dims.x; ++i)
     {
         sb.Append("( ");
         for (int j = 0; j < patch.dims.y; ++j)
         {
             Vertex vertex = patch.points[((int)Math.Round(patch.dims.x) * j) + i];
             sb.Append("( ")
             .Append(vertex.position.x.ToString("###0.#####", format))
             .Append(" ")
             .Append(vertex.position.y.ToString("###0.#####", format))
             .Append(" ")
             .Append(vertex.position.z.ToString("###0.#####", format))
             .Append(" ")
             .Append(vertex.uv0.x.ToString("###0.#####", format))
             .Append(" ")
             .Append(vertex.uv0.y.ToString("###0.#####", format))
             .Append(" ) ");
         }
         sb.Append(")\r\n");
     }
     sb.Append(")\r\n  }\r\n }\r\n");
 }
 /// <summary>
 /// Moves this <see cref="MAPPatch"/> object using the passed vector <paramref name="v"/>.
 /// </summary>
 /// <param name="mapBrushSide">This <see cref="MAPPatch"/>.</param>
 /// <param name="v">Translation vector.</param>
 public static void Translate(this MAPPatch mapPatch, Vector3 v)
 {
     for (int i = 0; i < mapPatch.points.Length; ++i)
     {
         VertexExtensions.Translate(mapPatch.points[i], v);
     }
 }
 /// <summary>
 /// Moves this <see cref="MAPPatch"/> object using the passed vector <paramref name="v"/>.
 /// </summary>
 /// <param name="mapBrushSide">This <see cref="MAPPatch"/>.</param>
 /// <param name="v">Translation vector.</param>
 public static void Translate(this MAPPatch mapPatch, Vector3d v)
 {
     for (int i = 0; i < mapPatch.points.Length; ++i)
     {
         mapPatch.points[i].Translate(v);
     }
 }
    public byte[] patchToByteArray(MAPPatch inData, int num)
    {
        string patch = "// Brush " + num + (char)0x0D + (char)0x0A + inData.ToString() + (char)0x0D + (char)0x0A;

        byte[] patchbytes = new byte[patch.Length];
        for (int i = 0; i < patch.Length; i++)
        {
            patchbytes[i] = (byte)patch[i];
        }
        return(patchbytes);
    }
Exemple #6
0
 /// <summary>
 /// Process the data in a <see cref="MAPPatch"/> into the passed <c>StringBuilder</c>.
 /// </summary>
 /// <param name="patch">The <see cref="MAPPatch"/> to process.</param>
 /// <param name="sb">A <c>StringBuilder</c> object to append processed data from <paramref name="patch"/> to.</param>
 private void ParsePatch(MAPPatch patch, StringBuilder sb)
 {
     sb.Append(" {\r\n  patchDef5\r\n  {\r\n   ")
     .Append(patch.texture)
     .Append("\r\n   ( ")
     .Append((int)Math.Round(patch.dims.X))
     .Append(" ")
     .Append((int)Math.Round(patch.dims.Y))
     .Append(" 0 0 0 0 8 )\r\n(\r\n");
     for (int i = 0; i < patch.dims.X; ++i)
     {
         sb.Append("( ");
         for (int j = 0; j < patch.dims.Y; ++j)
         {
             Vertex vertex = patch.points[((int)Math.Round(patch.dims.X) * j) + i];
             sb.Append("( ")
             .Append(vertex.position.X.ToString("###0.#####", format))
             .Append(" ")
             .Append(vertex.position.Y.ToString("###0.#####", format))
             .Append(" ")
             .Append(vertex.position.Z.ToString("###0.#####", format))
             .Append(" ")
             .Append(vertex.uv0.X.ToString("###0.#####", format))
             .Append(" ")
             .Append(vertex.uv0.Y.ToString("###0.#####", format))
             .Append(" ")
             .Append(vertex.color.R.ToString(format))
             .Append(" ")
             .Append(vertex.color.G.ToString(format))
             .Append(" ")
             .Append(vertex.color.B.ToString(format))
             .Append(" ")
             .Append(vertex.color.A.ToString(format))
             .Append(" 0 ) ");
         }
         sb.Append(")\r\n");
     }
     sb.Append(")\r\n  }\r\n }\r\n");
 }
Exemple #7
0
        /// <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");
            }
        }
Exemple #8
0
 public MAPBrush(MAPPatch patch)
 {
     this.patch = patch;
 }
    // METHODS

    // +decompile()
    // Attempts to convert the BSP file back 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 numTotalItems = 0;

        worldspawn = mapFile[mapFile.findAllWithAttribute("classname", "worldspawn")[0]];
        int onePercent = (int)((BSPObject.Brushes.Count + BSPObject.Entities.Count + BSPObject.Faces.Count) / 100);

        if (onePercent < 1)
        {
            onePercent = 1;
        }
        // I need to go through each entity and see if it's brush-based.
        // Worldspawn is brush-based as well as any entity with model *#.
        for (int i = 0; i < BSPObject.Entities.Count; i++)
        {
            // For each entity
            //DecompilerThread.OnMessage(this, "Entity " + i + ": " + mapFile[i]["classname"]);
            numBrshs = 0;             // Reset the brush count for each entity
            // 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.
                int firstBrush = BSPObject.Models[currentModel].FirstBrush;
                int numBrushes = BSPObject.Models[currentModel].NumBrushes;
                numBrshs = 0;
                for (int j = 0; j < numBrushes; j++)
                {
                    // For each brush
                    //Console.Write("Brush " + j);
                    decompileBrush(BSPObject.Brushes[j + firstBrush], i);                     // Decompile the brush
                    numBrshs++;
                    numTotalItems++;
                    if (numTotalItems % onePercent == 0)
                    {
                        parent.OnProgress(this, numTotalItems / (double)(BSPObject.Brushes.Count + BSPObject.Entities.Count + BSPObject.Faces.Count));
                    }
                }
            }
            numTotalItems++;
            if (numTotalItems % onePercent == 0)
            {
                parent.OnProgress(this, numTotalItems / (double)(BSPObject.Brushes.Count + BSPObject.Entities.Count + BSPObject.Faces.Count));
            }
        }
        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);
        }
        foreach (Face face in BSPObject.Faces)
        {
            if (face.Facetype == Face.faceType.PATCH)
            {
                MAPPatch mapPatch = new MAPPatch(face.PatchSize[0], face.PatchSize[1], BSPObject.Textures[face.Texture].Name);
                for (int i = 0; i < face.NumVertices; i++)
                {
                    mapPatch.Add(BSPObject.Vertices[face.FirstVertex + i]);
                }
                MAPBrush mapBrush = new MAPBrush(mapPatch);
                worldspawn.Brushes.Add(mapBrush);
            }
        }
        parent.OnProgress(this, 1.0);
        return(mapFile);
    }
	public byte[] patchToByteArray(MAPPatch inData, int num) {
		string patch = "// Brush " + num + (char) 0x0D + (char) 0x0A + inData.ToString() + (char) 0x0D + (char) 0x0A;
		byte[] patchbytes = new byte[patch.Length];
		for (int i = 0; i < patch.Length; i++) {
			patchbytes[i] = (byte) patch[i];
		}
		return patchbytes;
	}
	public MAPBrush(MAPPatch patch) {
		this.patch = patch;
	}
	// METHODS
	
	// +decompile()
	// Attempts to convert the BSP file back 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 numTotalItems = 0;
		worldspawn = mapFile[mapFile.findAllWithAttribute("classname", "worldspawn")[0]];
		int onePercent = (int)((BSPObject.Brushes.Count + BSPObject.Entities.Count + BSPObject.Faces.Count)/100);
		if(onePercent < 1) {
			onePercent = 1;
		}
		// I need to go through each entity and see if it's brush-based.
		// Worldspawn is brush-based as well as any entity with model *#.
		for (int i = 0; i < BSPObject.Entities.Count; i++) {
			// For each entity
			//DecompilerThread.OnMessage(this, "Entity " + i + ": " + mapFile[i]["classname"]);
			numBrshs = 0; // Reset the brush count for each entity
			// 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.
				int firstBrush = BSPObject.Models[currentModel].FirstBrush;
				int numBrushes = BSPObject.Models[currentModel].NumBrushes;
				numBrshs = 0;
				for (int j = 0; j < numBrushes; j++) {
					// For each brush
					//Console.Write("Brush " + j);
					decompileBrush(BSPObject.Brushes[j + firstBrush], i); // Decompile the brush
					numBrshs++;
					numTotalItems++;
					if(numTotalItems%onePercent == 0) {
						parent.OnProgress(this, numTotalItems/(double)(BSPObject.Brushes.Count + BSPObject.Entities.Count + BSPObject.Faces.Count));
					}
				}
			}
			numTotalItems++;
			if(numTotalItems%onePercent == 0) {
				parent.OnProgress(this, numTotalItems/(double)(BSPObject.Brushes.Count + BSPObject.Entities.Count + BSPObject.Faces.Count));
			}
		}
		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);
		}
		foreach(Face face in BSPObject.Faces) {
			if(face.Facetype == Face.faceType.PATCH) {
				MAPPatch mapPatch = new MAPPatch(face.PatchSize[0], face.PatchSize[1], BSPObject.Textures[face.Texture].Name);
				for(int i=0; i<face.NumVertices; i++) {
					mapPatch.Add(BSPObject.Vertices[face.FirstVertex+i]);
				}
				MAPBrush mapBrush = new MAPBrush(mapPatch);
				worldspawn.Brushes.Add(mapBrush);
			}
		}
		parent.OnProgress(this, 1.0);
		return mapFile;
	}