private static XElement GetVertexElement(ESOModel model, int index) { var element = new XElement("Vertex"); element.SetAttributeValueWithDefault("Position", model.Vertices[index]); if (model.HasNormals) { element.SetAttributeValueWithDefault("Normal", model.Normals[index]); } if (model.HasColors) { element.SetAttributeValueWithDefault("Color", model.Colors[index].GetString(), "Transparent"); } if (model.HasTexCoords) { element.SetAttributeValueWithDefault("TexCoord", model.TexCoords[index]); } if (model.HasTexCoords2) { element.SetAttributeValueWithDefault("TexCoords2", model.TexCoords2[index]); } return(element); }
public string Generate(string path) { var models = new ESOModel[4]; for (short x = 0; x < level.Size.Width; x++) { for (short y = 0; y < level.Size.Length; y++) { for (short z = 0; z < level.Size.Height; z++) { var info = GetInformation(x, y, z); if (info.Height < 0) { continue; } var theme = themes[info.Theme]; if (models[theme] == null) { models[theme] = new ESOModel(ESOModel.Flags.Normals | ESOModel.Flags.TexCoords) { MaterialAsset = AssetHash.Parse(Materials[theme] + ModelsNamespace) } } ; var model = models[theme]; short x1 = (short)(x + 1), y1 = (short)(y + 1), z1 = (short)(z + 1); float texY1 = 1 - z * 0.25F, texY = texY1 - 0.25F; if (GetInformation(x, y, z1).Height < 1 && (Math.Abs(x - level.ExitPoint.X) > 1 || Math.Abs(y - level.ExitPoint.Y) > 1 || z1 != level.ExitPoint.Z)) { model.Vertices.Add(Transform(new Vec3(x, z1, y))); model.Vertices.Add(Transform(new Vec3(x1, z1, y))); model.Vertices.Add(Transform(new Vec3(x, z1, y1))); model.Vertices.Add(Transform(new Vec3(x, z1, y1))); model.Vertices.Add(Transform(new Vec3(x1, z1, y))); model.Vertices.Add(Transform(new Vec3(x1, z1, y1))); model.Normals.AddRange(YNormals); float texX = ((x + y) & 1) == 0 ? 0.51F : 0.76F, texX1 = texX + 0.23F; model.TexCoords.Add(new Vec2(texX, texY)); model.TexCoords.Add(new Vec2(texX1, texY)); model.TexCoords.Add(new Vec2(texX, texY1)); model.TexCoords.Add(new Vec2(texX, texY1)); model.TexCoords.Add(new Vec2(texX1, texY)); model.TexCoords.Add(new Vec2(texX1, texY1)); } if (info.Height <= 0) { continue; } var zB = z1 - info.Height; texY1 -= 0.25F * (1 - info.Height); if (GetInformation(x1, y, z).Height < info.Height) { model.Vertices.Add(Transform(new Vec3(x1, zB, y))); model.Vertices.Add(Transform(new Vec3(x1, zB, y1))); model.Vertices.Add(Transform(new Vec3(x1, z1, y))); model.Vertices.Add(Transform(new Vec3(x1, zB, y1))); model.Vertices.Add(Transform(new Vec3(x1, z1, y1))); model.Vertices.Add(Transform(new Vec3(x1, z1, y))); model.Normals.AddRange(XNormals); model.TexCoords.Add(new Vec2(0.49F, texY1)); model.TexCoords.Add(new Vec2(0.26F, texY1)); model.TexCoords.Add(new Vec2(0.49F, texY)); model.TexCoords.Add(new Vec2(0.26F, texY1)); model.TexCoords.Add(new Vec2(0.26F, texY)); model.TexCoords.Add(new Vec2(0.49F, texY)); } if (GetInformation(x, y1, z).Height < info.Height) { model.Vertices.Add(Transform(new Vec3(x, zB, y1))); model.Vertices.Add(Transform(new Vec3(x, z1, y1))); model.Vertices.Add(Transform(new Vec3(x1, zB, y1))); model.Vertices.Add(Transform(new Vec3(x, z1, y1))); model.Vertices.Add(Transform(new Vec3(x1, z1, y1))); model.Vertices.Add(Transform(new Vec3(x1, zB, y1))); model.Normals.AddRange(ZNormals); model.TexCoords.Add(new Vec2(0.01F, texY1)); model.TexCoords.Add(new Vec2(0.01F, texY)); model.TexCoords.Add(new Vec2(0.24F, texY1)); model.TexCoords.Add(new Vec2(0.01F, texY)); model.TexCoords.Add(new Vec2(0.24F, texY)); model.TexCoords.Add(new Vec2(0.24F, texY1)); } } } } string fileName = Path.GetFileNameWithoutExtension(path) + ".rmdl", result; models = models.Where(model => model != null).ToArray(); new ESO { AssetHeader = new AssetHeader(AssetUtil.EngineVersion.Version1804Edge, fileName, "models"), Models = models, Header = new ESOHeader { V01 = 1, V02 = 4096, V20 = 1, NumModels = models.Length, ScaleXYZ = 1, Scale = new Vec3(0.1F, 0.1F, 0.1F), Translate = Translates[themes[0]], NodeChild = AssetHash.Parse(ChildModels[themes[0]] + ModelsNamespace), BoundingMin = Transform(new Vec3()), BoundingMax = Transform(new Vec3(level.Size.Width, level.Size.Height, level.Size.Length)) } }.Save(result = Path.Combine(Path.GetDirectoryName(path), AssetUtil.CrcFullName(fileName, "models") + ".eso")); return(result); } }
public static ESO ParseEso(XElement element, string name, string nameSpace = "models") { var scaleXyz = element.GetAttributeValueWithDefault <float>("ScaleXYZ", 1); Vec3 translate = element.GetAttributeValueWithDefault <Vec3>("Translate"), rotate = element.GetAttributeValueWithDefault <Vec3>("Rotate") * ToRadian, scale = element.GetAttributeValueWithDefault("Scale", new Vec3(1, 1, 1)); var mode = element.GetAttributeValueWithDefault <ApplyTransformMode>("ApplyTransform"); var matrix = new Matrix3D(); if (mode.HasFlag(ApplyTransformMode.MultiplicationOnly) || mode.HasFlag(ApplyTransformMode.DivisionOnly)) { matrix.Scale(ConvertVector(scale)); matrix.Scale(new Vector3D(scaleXyz, scaleXyz, scaleXyz)); matrix.Rotate(new Quaternion(new Vector3D(1, 0, 0), rotate.X * ToDegree)); matrix.Rotate(new Quaternion(new Vector3D(0, 1, 0), rotate.Y * ToDegree)); matrix.Rotate(new Quaternion(new Vector3D(0, 0, 1), rotate.Z * ToDegree)); matrix.Translate(ConvertVector(translate)); if (mode.HasFlag(ApplyTransformMode.DivisionOnly)) { matrix.Invert(); } } if (mode.HasFlag(ApplyTransformMode.Remove)) { scaleXyz = 1; rotate = translate = default(Vec3); scale = new Vec3(1, 1, 1); } var modelsAutoNormals = element.GetAttributeValueWithDefault <bool>("AutoNormals"); var models = new List <ESOModel>(); foreach (var e in element.ElementsCaseInsensitive("Model")) { var modelAutoNormals = e.GetAttributeValueWithDefault("AutoNormals", modelsAutoNormals); var triangles = e.ElementsCaseInsensitive("Triangle").ToArray(); var vertexCount = triangles.Length * 3; var model = new ESOModel(numVerts: vertexCount) { MaterialAsset = e.GetAttributeValueWithDefault <AssetHash>("MaterialAsset") }; foreach (var triangle in triangles) { var autoNormals = triangle.GetAttributeValueWithDefault("AutoNormals", modelAutoNormals); var normals = new bool[3]; var i = model.Vertices.Count; var vertices = triangle.ElementsCaseInsensitive("Vertex").ToArray(); if (vertices.Length != 3) { throw new FormatException(Localization.TriangleVertexCountError); } foreach (var vertex in vertices) { model.Vertices.Add(ConvertFromVertex(matrix.Transform (ConvertVertex(vertex.GetAttributeValueWithDefault <Vec3>("Position"))))); if (vertex.AttributeCaseInsensitive("Normal") != null) { if (!model.HasNormals) { model.HasNormals = true; model.Normals.AddRange( from j in Enumerable.Range(0, model.Vertices.Count - 1) select default(Vec3)); } normals[model.Normals.Count - i] = true; } if (model.HasNormals) { model.Normals.Add(ConvertFromVector(matrix.Transform( ConvertVector(vertex.GetAttributeValueWithDefault <Vec3>("Normal"))))); } if (!model.HasColors && vertex.AttributeCaseInsensitive("Color") != null) { model.HasColors = true; model.Colors.AddRange( from j in Enumerable.Range(0, model.Vertices.Count - 1) select Color.Transparent); } if (model.HasColors) { model.Colors.Add(Helper.Parse(vertex.GetAttributeValueWithDefault("Color", "Transparent"))); } if (!model.HasTexCoords && vertex.AttributeCaseInsensitive("TexCoord") != null) { model.HasTexCoords = true; model.TexCoords.AddRange( from j in Enumerable.Range(0, model.Vertices.Count - 1) select default(Vec2)); } if (model.HasTexCoords) { model.TexCoords.Add(vertex.GetAttributeValueWithDefault <Vec2>("TexCoord")); } if (!model.HasTexCoords2 && vertex.AttributeCaseInsensitive("TexCoord2") != null) { model.HasTexCoords2 = true; model.TexCoords2.AddRange( from j in Enumerable.Range(0, model.Vertices.Count - 1) select default(Vec2)); } if (model.HasTexCoords2) { model.TexCoords2.Add(vertex.GetAttributeValueWithDefault <Vec2>("TexCoord2")); } } if (!autoNormals) { continue; } model.HasNormals = true; model.Normals.AddRange(from j in Enumerable.Range(0, i - model.Normals.Count) select default(Vec3)); var p0 = ConvertVertex(model.Vertices[i]); var normal = Vector3D.CrossProduct(ConvertVertex(model.Vertices[i + 2]) - p0, ConvertVertex(model.Vertices[i + 1]) - p0); var vec3 = new Vec3((float)normal.X, (float)normal.Y, (float)normal.Z); for (var j = i; j < model.Vertices.Count; j++) { if (!normals[j - i]) { model.Normals[j] = vec3; } } } models.Add(model); } var result = new ESO { AssetHeader = new AssetHeader(AssetUtil.EngineVersion.Version1804Edge, name, nameSpace), Models = models.ToArray(), Header = new ESOHeader { V01 = element.GetAttributeValueWithDefault <int>("V01"), V02 = element.GetAttributeValueWithDefault <int>("V02"), NodeChild = element.GetAttributeValueWithDefault <AssetHash>("NodeChild"), NodeSibling = element.GetAttributeValueWithDefault <AssetHash>("NodeSibling"), V07 = element.GetAttributeValueWithDefault <int>("V07"), V08 = element.GetAttributeValueWithDefault <int>("V08"), V09 = element.GetAttributeValueWithDefault <int>("V09"), V21 = element.GetAttributeValueWithDefault <int>("V21"), ScaleXYZ = scaleXyz, Scale = scale, Translate = translate, Rotate = rotate, NumModels = models.Count, V20 = element.GetAttributeValueWithDefault <float>("V20") } }; if (models.Count > 0) { result.Header.BoundingMin = ConvertFromVertex(matrix.Transform( ConvertVertex(element.GetAttributeValueWithDefault <Vec3>("BoundingMin")))); result.Header.BoundingMax = ConvertFromVertex(matrix.Transform( ConvertVertex(element.GetAttributeValueWithDefault <Vec3>("BoundingMax")))); result.Footer = new ESOFooter(element.GetAttributeValueWithDefault <float>("FooterV01"), element.GetAttributeValueWithDefault <float>("FooterV02"), element.GetAttributeValueWithDefault <int>("FooterV03"), element.GetAttributeValueWithDefault <int>("FooterV04")); if (Math.Abs(result.Footer.V01) > 1e-4 || Math.Abs(result.Footer.V02) > 1e-4 || result.Footer.V03 != 0 || result.Footer.V04 != 0) { result.HasFooter = true; } } return(result); }