public static Tae ReadTae(string path) { Tae tae = new Tae(); BinaryReader file = new BinaryReader(File.Open(path, FileMode.Open)); tae.header = new Header(); tae.data = new Data(); tae.header.signature = file.ReadBytes(4); if (Encoding.ASCII.GetString(tae.header.signature) == "TAE ") { tae.header.unk1 = file.ReadUInt32(); tae.header.unk2 = file.ReadUInt32(); tae.header.fileSize = file.ReadUInt32(); tae.header.unk3 = file.ReadBytes(64); tae.header.id = file.ReadUInt32(); tae.header.idCount = file.ReadUInt32(); tae.header.idsOffset = file.ReadUInt32(); tae.header.groupsOffset = file.ReadUInt32(); tae.header.unk4 = file.ReadUInt32(); tae.header.dataCount = file.ReadUInt32(); tae.header.dataOffset = file.ReadUInt32(); tae.header.unk5 = file.ReadBytes(40); tae.header.filenamesOffset = file.ReadUInt32(); tae.data.skeletonHkxName = new NameStruct(); tae.data.SibName = new NameStruct(); file.BaseStream.Seek(tae.header.filenamesOffset, SeekOrigin.Begin); tae.data.skeletonHkxName.offset = file.ReadUInt32(); tae.data.SibName.offset = file.ReadUInt32(); tae.data.unk = file.ReadUInt64(); file.BaseStream.Seek(tae.data.skeletonHkxName.offset, SeekOrigin.Begin); tae.data.skeletonHkxName.name = MyReadChars(file); file.BaseStream.Seek(tae.data.SibName.offset, SeekOrigin.Begin); tae.data.SibName.name = MyReadChars(file); file.BaseStream.Seek(tae.header.idsOffset, SeekOrigin.Begin); tae.data.ids = new List <IdStruct> { }; for (int i = 0; i < tae.header.idCount; i++) { IdStruct id = new IdStruct(); id.id = file.ReadUInt32(); id.offset = file.ReadUInt32(); tae.data.ids.Add(id); } file.BaseStream.Seek(tae.header.groupsOffset, SeekOrigin.Begin); tae.data.groupCount = file.ReadUInt32(); tae.data.groupDataOffset = file.ReadUInt32(); file.BaseStream.Seek(tae.data.groupDataOffset, SeekOrigin.Begin); tae.data.groups = new List <GroupStruct> { }; for (int i = 0; i < tae.data.groupCount; i++) { GroupStruct group = new GroupStruct(); group.firstId = file.ReadUInt32(); group.lastId = file.ReadUInt32(); group.firstIdOffset = file.ReadUInt32(); tae.data.groups.Add(group); } file.BaseStream.Seek(tae.header.dataOffset, SeekOrigin.Begin); tae.data.animDatas = new List <AnimDataStruct> { }; long currpos = 0; for (int i = 0; i < tae.header.dataCount; i++) { AnimDataStruct animData = new AnimDataStruct(); animData.eventCount = file.ReadUInt32(); animData.eventHeaderOffset = file.ReadUInt32(); animData.unk = file.ReadUInt64(); animData.timeConstantsCount = file.ReadUInt32(); animData.timeConstantsOffset = file.ReadUInt32(); animData.animFileOffset = file.ReadUInt32(); currpos = file.BaseStream.Position; file.BaseStream.Seek(animData.animFileOffset, SeekOrigin.Begin); animData.animFile = new AnimFileStruct(); animData.animFile.name = new NameStruct(); animData.animFile.type = file.ReadUInt32(); animData.animFile.dataOffset = file.ReadUInt32(); if (animData.animFile.type == 0) { animData.animFile.name.offset = file.ReadUInt32(); } else { animData.animFile.nextFileOffset = file.ReadUInt32(); animData.animFile.linkedAnimId = file.ReadUInt32(); } animData.animFile.unk1 = file.ReadUInt32(); animData.animFile.unk2 = file.ReadUInt32(); animData.animFile.nulla = file.ReadUInt32(); if (animData.animFile.type == 0) { file.BaseStream.Seek(animData.animFile.name.offset, SeekOrigin.Begin); animData.animFile.name.name = MyReadChars(file); } animData.events = new List <EventStruct> { }; for (int j = 0; j < animData.eventCount; j++) { EventStruct Event = new EventStruct(); file.BaseStream.Seek(animData.eventHeaderOffset + j * 12, SeekOrigin.Begin); Event.startTimeOffset = file.ReadUInt32(); Event.endTimeOffset = file.ReadUInt32(); Event.eventbodyOffset = file.ReadUInt32(); file.BaseStream.Seek(Event.startTimeOffset, SeekOrigin.Begin); Event.startTime = file.ReadSingle(); Event.startTimeOffset -= animData.timeConstantsOffset; file.BaseStream.Seek(Event.endTimeOffset, SeekOrigin.Begin); Event.endTime = file.ReadSingle(); Event.endTimeOffset -= animData.timeConstantsOffset; file.BaseStream.Seek(Event.eventbodyOffset, SeekOrigin.Begin); Event.eventType = file.ReadUInt32(); Event.eventParamOffset = file.ReadUInt32(); file.BaseStream.Seek(Event.eventParamOffset, SeekOrigin.Begin); Event.parameters = ReadParams(Event.eventType, file); if (Event.parameters[0] == null) { tae.err = "Unrecognized event type: " + BitConverter.ToInt32(Event.parameters[1], 0) + "\n\nPosition in the file: " + file.BaseStream.Position; file.Close(); return(tae); } animData.events.Add(Event); } file.BaseStream.Seek(animData.timeConstantsOffset, SeekOrigin.Begin); animData.timeConstants = new List <float> { }; for (int j = 0; j < animData.timeConstantsCount; j++) { animData.timeConstants.Add(file.ReadSingle()); } file.BaseStream.Seek((uint)currpos, SeekOrigin.Begin); tae.data.animDatas.Add(animData); } } else { tae.err = "Specified file is not a TAE file."; } file.Close(); return(tae); }
public static void WriteTae(Tae tae, string path) { BinaryWriter file = new BinaryWriter(File.Open(path, FileMode.Create)); int c = 0; while (c < 2) { file.Write(tae.header.signature); file.Write(tae.header.unk1); file.Write(tae.header.unk2); file.Write(tae.header.fileSize); file.Write(tae.header.unk3); file.Write(tae.header.id); file.Write(tae.header.idCount); file.Write(tae.header.idsOffset); file.Write(tae.header.groupsOffset); file.Write(tae.header.unk4); file.Write(tae.header.dataCount); file.Write(tae.header.dataOffset); file.Write(tae.header.unk5); file.Write(tae.header.filenamesOffset); tae.header.filenamesOffset = (uint)file.BaseStream.Position; file.Write(tae.data.skeletonHkxName.offset); file.Write(tae.data.SibName.offset); file.Write(tae.data.unk); tae.data.skeletonHkxName.offset = (uint)file.BaseStream.Position; file.Write(Encoding.UTF8.GetBytes(tae.data.skeletonHkxName.name)); tae.data.SibName.offset = (uint)file.BaseStream.Position; file.Write(Encoding.UTF8.GetBytes(tae.data.SibName.name)); tae.header.idsOffset = (uint)file.BaseStream.Position; foreach (IdStruct id in tae.data.ids) { for (int i = 0; i < tae.data.groupCount; i++) { if (id.id == tae.data.groups[i].firstId) { tae.data.groups[i].firstIdOffset = (uint)file.BaseStream.Position; } } file.Write(id.id); file.Write(id.offset); } tae.header.groupsOffset = (uint)file.BaseStream.Position; file.Write(tae.data.groupCount); file.Write((uint)file.BaseStream.Position + 4); foreach (GroupStruct group in tae.data.groups) { file.Write(group.firstId); file.Write(group.lastId); file.Write(group.firstIdOffset); } tae.header.dataOffset = (uint)file.BaseStream.Position; for (int i = 0; i < tae.data.animDatas.Count; i++) { tae.data.ids[i].offset = (uint)file.BaseStream.Position; file.Write(tae.data.animDatas[i].eventCount); file.Write(tae.data.animDatas[i].eventHeaderOffset); file.Write(tae.data.animDatas[i].unk); file.Write(tae.data.animDatas[i].timeConstantsCount); file.Write(tae.data.animDatas[i].timeConstantsOffset); file.Write(tae.data.animDatas[i].animFileOffset); } for (int i = 0; i < tae.data.animDatas.Count; i++) { tae.data.animDatas[i].animFileOffset = (uint)file.BaseStream.Position; file.Write(tae.data.animDatas[i].animFile.type); file.Write(tae.data.animDatas[i].animFile.dataOffset); tae.data.animDatas[i].animFile.dataOffset = (uint)file.BaseStream.Position; if (tae.data.animDatas[i].animFile.type == 0) { file.Write(tae.data.animDatas[i].animFile.name.offset); } else { file.Write(tae.data.animDatas[i].animFile.nextFileOffset); file.Write(tae.data.animDatas[i].animFile.linkedAnimId); } file.Write(tae.data.animDatas[i].animFile.unk1); file.Write(tae.data.animDatas[i].animFile.unk2); file.Write(tae.data.animDatas[i].animFile.nulla); if (tae.data.animDatas[i].animFile.type == 0) //&& tae.data.animDatas[i].animFile.name.name != Encoding.UTF8.GetString(new byte[2])) { tae.data.animDatas[i].animFile.name.offset = (uint)file.BaseStream.Position; file.Write(Encoding.UTF8.GetBytes(tae.data.animDatas[i].animFile.name.name)); } if (tae.data.animDatas[i].animFile.type == 1) { tae.data.animDatas[i].animFile.nextFileOffset = (uint)file.BaseStream.Position; } tae.data.animDatas[i].timeConstantsOffset = (uint)file.BaseStream.Position; foreach (float timeConstant in tae.data.animDatas[i].timeConstants) { file.Write(timeConstant); } tae.data.animDatas[i].eventHeaderOffset = (uint)file.BaseStream.Position; foreach (EventStruct Event in tae.data.animDatas[i].events) { uint offset = tae.data.animDatas[i].timeConstantsOffset; file.Write(offset + Event.startTimeOffset); file.Write(offset + Event.endTimeOffset); file.Write(Event.eventbodyOffset); } for (int j = 0; j < tae.data.animDatas[i].events.Count; j++) { tae.data.animDatas[i].events[j].eventbodyOffset = (uint)file.BaseStream.Position; file.Write(tae.data.animDatas[i].events[j].eventType); file.Write(tae.data.animDatas[i].events[j].eventParamOffset); tae.data.animDatas[i].events[j].eventParamOffset = (uint)file.BaseStream.Position; file.Write(ConcatParams(tae.data.animDatas[i].events[j].parameters)); } } c++; file.BaseStream.Seek(0, SeekOrigin.End); tae.header.fileSize = (uint)file.BaseStream.Position; file.BaseStream.Seek(0, SeekOrigin.Begin); } file.Close(); }
protected override void BuildContents() { var entityType = Tae.Graph?.ViewportInteractor?.EntityType; if (entityType == TaeViewportInteractor.TaeEntityType.NPC) { ImGui.Button("Load Additional Texture File(s)..."); if (ImGui.IsItemClicked()) { Tae.BrowseForMoreTextures(); } var mdl = Tae.Graph?.ViewportInteractor?.CurrentModel; if (mdl != null) { if (ImGui.TreeNode("NPC Param Selection")) { lock (mdl._lock_NpcParams) { foreach (var npc in mdl.PossibleNpcParams) { bool oldSelected = npc == mdl.NpcParam; var selected = MenuBar.CheckboxBig(npc.GetDisplayName(), oldSelected); ImGui.Indent(); ImGui.PushStyleColor(ImGuiCol.Text, new System.Numerics.Vector4(0, 1, 1, 1)); { ImGui.Text($"BehaviorVariationID: {npc.BehaviorVariationID}"); if (mdl.NpcMaterialNamesPerMask.Any(kvp => kvp.Key >= 0)) { ImGui.Text($"Meshes Visible:"); ImGui.Indent(); { foreach (var kvp in mdl.NpcMaterialNamesPerMask) { if (kvp.Key < 0) { continue; } if (mdl.NpcMasksEnabledOnAllNpcParams.Contains(kvp.Key)) { continue; } if (npc.DrawMask[kvp.Key]) { foreach (var v in kvp.Value) { ImGui.BulletText(v); } } } } ImGui.Unindent(); } } ImGui.PopStyleColor(); ImGui.Unindent(); if (selected != oldSelected) { mdl.NpcParam = npc; npc.ApplyToNpcModel(mdl); } } } ImGui.TreePop(); } } ImGui.Separator(); ImGui.Button("Open NPC Model Importer"); if (ImGui.IsItemClicked()) { Tae.BringUpImporter_FLVER2(); } } else if (entityType == TaeViewportInteractor.TaeEntityType.OBJ) { ImGui.Button("Load Additional Texture File(s)..."); if (ImGui.IsItemClicked()) { Tae.BrowseForMoreTextures(); } } else if (entityType == TaeViewportInteractor.TaeEntityType.PC) { OSD.WindowEditPlayerEquip.IsOpen = MenuBar.CheckboxBig("Show Player Equipment Editor Window", OSD.WindowEditPlayerEquip.IsOpen); if (Tae.Graph?.ViewportInteractor?.EventSim != null) { var currentHitViewSource = Tae.Config.HitViewDummyPolySource; int currentHitViewSourceIndex = BehaviorHitboxSrcEnum_Values.IndexOf(currentHitViewSource); ImGui.ListBox("Behavior / Hitbox Source", ref currentHitViewSourceIndex, BehaviorHitboxSrcEnum_Names, BehaviorHitboxSrcEnum_Names.Length); var newHitViewSource = currentHitViewSourceIndex >= 0 ? BehaviorHitboxSrcEnum_Values[currentHitViewSourceIndex] : ParamData.AtkParam.DummyPolySource.Body; if (currentHitViewSource != newHitViewSource) { lock (Tae.Graph._lock_EventBoxManagement) { Tae.Graph.ViewportInteractor.EventSim.OnNewAnimSelected(Tae.Graph.EventBoxes); Tae.Config.HitViewDummyPolySource = newHitViewSource; Tae.Graph.ViewportInteractor.EventSim.OnNewAnimSelected(Tae.Graph.EventBoxes); Tae.Graph.ViewportInteractor.OnScrubFrameChange(); } } } } else if (entityType == TaeViewportInteractor.TaeEntityType.REMO) { RemoManager.EnableRemoCameraInViewport = MenuBar.CheckboxBig("Show Cutscene Camera View", RemoManager.EnableRemoCameraInViewport); RemoManager.EnableDummyPrims = MenuBar.CheckboxBig("Enable Dummy Node Helpers", RemoManager.EnableDummyPrims); Main.Config.LockAspectRatioDuringRemo = MenuBar.CheckboxBig("Lock Aspect Ratio to 16:9", Main.Config.LockAspectRatioDuringRemo); ImGui.Button("Preview Full Cutscene With Streamed Audio"); if (ImGui.IsItemClicked()) { RemoManager.StartFullPreview(); } } else { ImGui.Text("No entity loaded."); } }