public UnknownWorldMapBone(BoneIter boneIter, Matrix4 parentMatrix) : base(Vector4.Transform(new Vector4(boneIter.Current.Position.ToVec3(), 1), parentMatrix).Xyz.ToSceneScale()) { BoneName = boneIter.Current.Name; bone = boneIter.Current; Dictionary <short, (Matrix4 matrix, UnknownWorldMapBone bone)> loadedWorldmapBones = new Dictionary <short, (Matrix4 matrix, UnknownWorldMapBone bone)> { { (short)boneIter.CurrentBoneIndex, (boneIter.Current.CalculateRelativeMatrix() * parentMatrix, this) } }; while (loadedWorldmapBones.TryGetValue(boneIter.PeekNext()?.ParentIndex ?? -1, out (Matrix4 matrix, UnknownWorldMapBone bone)parent)) //is part of the child tree { boneIter.MoveNext(); var bone = new UnknownWorldMapBone(boneIter, parent.matrix); parent.bone.Children.Add(bone); loadedWorldmapBones.Add( (short)boneIter.CurrentBoneIndex, (boneIter.Current.CalculateRelativeMatrix() * parent.matrix, bone) ); } }
//public List<(string, WorldMapPoint)> Connections { get; private set; } = new List<(string, WorldMapPoint)>(); public WorldMapPoint(BoneIter boneIter, Matrix4 parentMatrix, string[] attributes, WorldMapRoute route = null) : base(Vector4.Transform(new Vector4(boneIter.Current.Position.ToVec3(), 1), parentMatrix).Xyz.ToSceneScale()) { BoneName = boneIter.Current.Name; this.attributes = attributes; Route = route; if (boneIter.PeekNext()?.ParentIndex == boneIter.CurrentBoneIndex && (boneIter.PeekNext()?.Name.StartsWith("cob") ?? false)) { Matrix4 boneMatrix = boneIter.Current.CalculateRelativeMatrix() * parentMatrix; boneIter.MoveNext(); Cob = new WorldMapCob(boneIter, boneMatrix); } }
public WorldMapRoute(BoneIter boneIter, Matrix4 parentMatrix, Dictionary <string, string[]> pointCsv) { Name = boneIter.Current.Name; Dictionary <short, Matrix4> loadedBoneMatrices = new Dictionary <short, Matrix4> { { (short)boneIter.CurrentBoneIndex, boneIter.Current.CalculateRelativeMatrix() * parentMatrix } }; while (loadedBoneMatrices.TryGetValue(boneIter.PeekNext()?.ParentIndex ?? -1, out Matrix4 _parentMatrix)) //is part of the child tree { boneIter.MoveNext(); pointCsv.TryGetValue(boneIter.Current.Name, out string[] attributes); RoutePoints.Add(new WorldMapPoint(boneIter, _parentMatrix, attributes, this)); loadedBoneMatrices.Add((short)boneIter.CurrentBoneIndex, boneIter.Current.CalculateRelativeMatrix() * _parentMatrix); } }
public WorldMapCob(BoneIter boneIter, Matrix4 parentMatrix) : base(Vector4.Transform(new Vector4(boneIter.Current.Position.ToVec3(), 1), parentMatrix).Xyz.ToSceneScale()) { ModelName = boneIter.Current.Name.TrimEnd(new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }); }
public WorldMapScene(SarcData sarc, string sarcName) { multiSelect = true; #region read files this.sarc = sarc; this.sarcName = sarcName; bfresEntry = sarc.Files.First(x => x.Key.EndsWith(".bfres")); pointEntry = sarc.Files.First(x => x.Key.StartsWith("pointW")); routeEntry = sarc.Files.First(x => x.Key.StartsWith("routeW")); bfres = new ResFile(new MemoryStream(bfresEntry.Value)); bones = bfres.Models[0].Skeleton.Bones; pointCsv = Encoding.GetEncoding("shift-jis").GetString(sarc.Files.First(file => file.Key.StartsWith("pointW")).Value). Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None).Reverse().Skip(1).Select(row => { int pos = 0; List <string> fields = new List <string>(); while (pos < row.Length) { string value; // Special handling for quoted field if (row[pos] == '"') { // Skip initial quote pos++; // Parse quoted value int start = pos; while (pos < row.Length) { // Test for quote character if (row[pos] == '"') { // Found one pos++; // If two quotes together, keep one // Otherwise, indicates end of value if (pos >= row.Length || row[pos] != '"') { pos--; break; } } pos++; } value = row.Substring(start, pos - start); value = value.Replace("\"\"", "\""); } else { // Parse unquoted value int start = pos; while (pos < row.Length && row[pos] != ',') { pos++; } value = row.Substring(start, pos - start); } // Add field to list fields.Add(value); // Eat up to and including next comma while (pos < row.Length && row[pos] != ',') { pos++; } if (pos < row.Length) { pos++; } } return(fields.ToArray()); }).Reverse().ToArray().ToDictionary(x => x[1]); routeCsv = Encoding.GetEncoding("shift-jis").GetString(sarc.Files.First(file => file.Key.StartsWith("routeW")).Value). Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None).Reverse().Skip(1).Select(row => { int pos = 0; List <string> fields = new List <string>(); while (pos < row.Length) { string value; // Special handling for quoted field if (row[pos] == '"') { // Skip initial quote pos++; // Parse quoted value int start = pos; while (pos < row.Length) { // Test for quote character if (row[pos] == '"') { // Found one pos++; // If two quotes together, keep one // Otherwise, indicates end of value if (pos >= row.Length || row[pos] != '"') { pos--; break; } } pos++; } value = row.Substring(start, pos - start); value = value.Replace("\"\"", "\""); } else { // Parse unquoted value int start = pos; while (pos < row.Length && row[pos] != ',') { pos++; } value = row.Substring(start, pos - start); } // Add field to list fields.Add(value); // Eat up to and including next comma while (pos < row.Length && row[pos] != ',') { pos++; } if (pos < row.Length) { pos++; } } return(fields.ToArray()); }).Reverse().ToArray().ToDictionary(x => x[0]); //SaveFileDialog sfd = new SaveFileDialog() //{ // FileName = sarcName //}; //if (sfd.ShowDialog() == DialogResult.OK) //{ // var stream = new MemoryStream(); // bfres.Save(stream, true); // sarc.Files[bfresEntry.Key] = stream.ToArray(); // Yaz0.Compress(new FileStream(sfd.FileName, FileMode.OpenOrCreate), SARC.PackN(sarc)); //} #endregion #region read map from bones Matrix4 rootMatrix = bones[0].CalculateRelativeMatrix(); var boneIter = new BoneIter(bones); boneIter.MoveNext(); //first bone is the root, we don't need to read it while (boneIter.MoveNext()) { var bone = boneIter.Current; if (bone.ParentIndex == -1) //there is more than one root (should never happen) { break; } if (bone.Name.StartsWith("R")) //indicates a Route { Routes.Add(new WorldMapRoute(boneIter, rootMatrix, pointCsv)); continue; } if (bone.ParentIndex != 0) { throw new Exception(bone.Name + " is in an unexpected Layer, proceeding might currupt the file"); } Vector4 pos = new Vector4( bone.Position.X / 100, bone.Position.Y / 100, bone.Position.Z / 100, 1 ); if (bone.Name == "course") { Matrix4 courseBoneMatrix = boneIter.Current.CalculateRelativeMatrix() * rootMatrix; short courseBoneIndex = (short)boneIter.CurrentBoneIndex; while (boneIter.PeekNext()?.ParentIndex == courseBoneIndex) { boneIter.MoveNext(); if (pointCsv.ContainsKey(boneIter.Current.Name)) { WorldMapObjects.Add(new WorldMapPoint(boneIter, courseBoneMatrix, pointCsv[boneIter.Current.Name])); } else { WorldMapObjects.Add(new UnknownWorldMapBone(boneIter, rootMatrix)); } } } else if (pointCsv.ContainsKey(bone.Name)) { WorldMapObjects.Add(new WorldMapPoint(boneIter, rootMatrix, pointCsv[bone.Name])); } else if (bone.Name.StartsWith("cob")) { WorldMapObjects.Add(new WorldMapCob(boneIter, rootMatrix)); } else { WorldMapObjects.Add(new UnknownWorldMapBone(boneIter, rootMatrix)); } } #endregion foreach (var route in Routes) { TryGetPoint(route.Name.Substring(1, 4), out WorldMapPoint start); TryGetPoint(route.Name.Substring(5, 4), out WorldMapPoint end); route.Start = start; route.End = end; } //ModelObjectReplace(); StaticObjects.Add(new StaticModel(bfresEntry.Key, bfres)); StaticObjects.Add(new ConnectionDrawer(this)); SelectionChanged += WorldMapScene_SelectionChanged; }