mirror of
https://github.com/celisej567/LibBSP.git
synced 2026-09-23 20:08:40 +03:00
All lump structures store their source data as a byte array now, so even unknown parts of structures are stored when they were discarded before. This means lumps can be read and written without losing any information. New extension methods for Vector2d, 3d and 4d, Vertex, Plane and Color to get their components as bytes for easy storage. Add support for most Call of Duty 2 structures. There's still some missing.
155 lines
6.9 KiB
C#
155 lines
6.9 KiB
C#
#if UNITY_3_4 || UNITY_3_5 || UNITY_4_0 || UNITY_4_0_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5 || UNITY_5_3_OR_NEWER
|
|
#define UNITY
|
|
#endif
|
|
|
|
using System.Collections.Generic;
|
|
using System;
|
|
using System.Globalization;
|
|
#if UNITY
|
|
using UnityEngine;
|
|
#endif
|
|
|
|
namespace LibBSP {
|
|
#if UNITY
|
|
using Vector2d = Vector2;
|
|
using Vector3d = Vector3;
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Class containing data for a brush side. Please note vertices must be set manually or generated through CSG.
|
|
/// </summary>
|
|
[Serializable] public class MAPBrushSide {
|
|
|
|
private static IFormatProvider _format = CultureInfo.CreateSpecificCulture("en-US");
|
|
|
|
public Vector3d[] vertices;
|
|
public Plane plane;
|
|
public string texture;
|
|
public TextureInfo textureInfo;
|
|
public string material;
|
|
public double lgtScale;
|
|
public double lgtRot;
|
|
public MAPDisplacement displacement;
|
|
|
|
/// <summary>
|
|
/// Creates a new empty <see cref="MAPBrushSide"/> object. Internal data will have to be set manually.
|
|
/// </summary>
|
|
public MAPBrushSide() { }
|
|
|
|
/// <summary>
|
|
/// Constructs a <see cref="MAPBrushSide"/> object using the provided <c>string</c> array as the data.
|
|
/// </summary>
|
|
/// <param name="lines">Data to parse.</param>
|
|
public MAPBrushSide(string[] lines) {
|
|
// If lines.Length is 1, then this line contains all data for a brush side
|
|
if (lines.Length == 1) {
|
|
string[] tokens = lines[0].SplitUnlessInContainer(' ', '\"', StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
float dist = 0;
|
|
|
|
// If this succeeds, assume brushDef3
|
|
if (float.TryParse(tokens[4], out dist)) {
|
|
plane = new Plane(new Vector3d(float.Parse(tokens[1], _format), float.Parse(tokens[2], _format), float.Parse(tokens[3], _format)), dist);
|
|
textureInfo = new TextureInfo(new Vector3d(float.Parse(tokens[8], _format), float.Parse(tokens[9], _format), float.Parse(tokens[10], _format)),
|
|
new Vector3d(float.Parse(tokens[13], _format), float.Parse(tokens[14], _format), float.Parse(tokens[15], _format)),
|
|
Vector2d.zero,
|
|
Vector2d.one,
|
|
0, 0, 0);
|
|
texture = tokens[18];
|
|
} else {
|
|
Vector3d v1 = new Vector3d(float.Parse(tokens[1], _format), float.Parse(tokens[2], _format), float.Parse(tokens[3], _format));
|
|
Vector3d v2 = new Vector3d(float.Parse(tokens[6], _format), float.Parse(tokens[7], _format), float.Parse(tokens[8], _format));
|
|
Vector3d v3 = new Vector3d(float.Parse(tokens[11], _format), float.Parse(tokens[12], _format), float.Parse(tokens[13], _format));
|
|
vertices = new Vector3d[] { v1, v2, v3 };
|
|
plane = new Plane(v1, v2, v3);
|
|
texture = tokens[15];
|
|
// GearCraft
|
|
if (tokens[16] == "[") {
|
|
textureInfo = new TextureInfo(new Vector3d(float.Parse(tokens[17], _format), float.Parse(tokens[18], _format), float.Parse(tokens[19], _format)),
|
|
new Vector3d(float.Parse(tokens[23], _format), float.Parse(tokens[24], _format), float.Parse(tokens[25], _format)),
|
|
new Vector2d(float.Parse(tokens[20], _format), float.Parse(tokens[26], _format)),
|
|
new Vector2d(float.Parse(tokens[29], _format), float.Parse(tokens[30], _format)),
|
|
int.Parse(tokens[31]), 0, double.Parse(tokens[28], _format));
|
|
material = tokens[32];
|
|
} else {
|
|
//<x_shift> <y_shift> <rotation> <x_scale> <y_scale> <content_flags> <surface_flags> <value>
|
|
Vector3d[] axes = TextureInfo.TextureAxisFromPlane(plane);
|
|
textureInfo = new TextureInfo(axes[0],
|
|
axes[1],
|
|
new Vector2d(float.Parse(tokens[16], _format), float.Parse(tokens[17], _format)),
|
|
new Vector2d(float.Parse(tokens[19], _format), float.Parse(tokens[20], _format)),
|
|
int.Parse(tokens[22]), 0, double.Parse(tokens[18], _format));
|
|
}
|
|
}
|
|
} else {
|
|
bool inDispInfo = false;
|
|
int braceCount = 0;
|
|
textureInfo = new TextureInfo();
|
|
List<string> child = new List<string>(37);
|
|
foreach (string line in lines) {
|
|
if (line == "{") {
|
|
++braceCount;
|
|
} else if (line == "}") {
|
|
--braceCount;
|
|
if (braceCount == 1) {
|
|
child.Add(line);
|
|
displacement = new MAPDisplacement(child.ToArray());
|
|
child = new List<string>(37);
|
|
inDispInfo = false;
|
|
}
|
|
} else if (line == "dispinfo") {
|
|
inDispInfo = true;
|
|
continue;
|
|
}
|
|
|
|
if (braceCount == 1) {
|
|
string[] tokens = line.SplitUnlessInContainer(' ', '\"', StringSplitOptions.RemoveEmptyEntries);
|
|
switch (tokens[0]) {
|
|
case "material": {
|
|
texture = tokens[1];
|
|
break;
|
|
}
|
|
case "plane": {
|
|
string[] points = tokens[1].SplitUnlessBetweenDelimiters(' ', '(', ')', StringSplitOptions.RemoveEmptyEntries);
|
|
string[] components = points[0].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
Vector3d v1 = new Vector3d(float.Parse(components[0], _format), float.Parse(components[1], _format), float.Parse(components[2], _format));
|
|
components = points[1].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
Vector3d v2 = new Vector3d(float.Parse(components[0], _format), float.Parse(components[1], _format), float.Parse(components[2], _format));
|
|
components = points[2].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
Vector3d v3 = new Vector3d(float.Parse(components[0], _format), float.Parse(components[1], _format), float.Parse(components[2], _format));
|
|
plane = new Plane(v1, v2, v3);
|
|
break;
|
|
}
|
|
case "uaxis": {
|
|
string[] split = tokens[1].SplitUnlessBetweenDelimiters(' ', '[', ']', StringSplitOptions.RemoveEmptyEntries);
|
|
textureInfo.scale = new Vector2d(float.Parse(split[1], _format), textureInfo.scale.y);
|
|
split = split[0].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
textureInfo.uAxis = new Vector3d(float.Parse(split[0], _format), float.Parse(split[1], _format), float.Parse(split[2], _format));
|
|
textureInfo.translation = new Vector2d(float.Parse(split[3], _format), textureInfo.translation.y);
|
|
break;
|
|
}
|
|
case "vaxis": {
|
|
string[] split = tokens[1].SplitUnlessBetweenDelimiters(' ', '[', ']', StringSplitOptions.RemoveEmptyEntries);
|
|
textureInfo.scale = new Vector2d(textureInfo.scale.x, float.Parse(split[1], _format));
|
|
split = split[0].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
textureInfo.vAxis = new Vector3d(float.Parse(split[0], _format), float.Parse(split[1], _format), float.Parse(split[2], _format));
|
|
textureInfo.translation = new Vector2d(textureInfo.translation.x, float.Parse(split[3], _format));
|
|
break;
|
|
}
|
|
case "rotation": {
|
|
textureInfo.rotation = double.Parse(tokens[1], _format);
|
|
break;
|
|
}
|
|
}
|
|
} else if (braceCount > 1) {
|
|
if (inDispInfo) {
|
|
child.Add(line);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|