mirror of
https://github.com/KillzXGaming/Switch-Toolbox
synced 2024-12-21 10:23:07 +00:00
913 lines
38 KiB
C#
913 lines
38 KiB
C#
using Switch_Toolbox.Library.NodeWrappers;
|
|
using Switch_Toolbox.Library;
|
|
using System.Collections.Generic;
|
|
using System.Windows.Forms;
|
|
using System.IO;
|
|
using System;
|
|
using FirstPlugin;
|
|
using ResU = Syroot.NintenTools.Bfres;
|
|
using ResNX = Syroot.NintenTools.NSW.Bfres;
|
|
using Switch_Toolbox.Library.Animations;
|
|
using Switch_Toolbox.Library.Forms;
|
|
|
|
namespace Bfres.Structs
|
|
{
|
|
public enum BRESGroupType
|
|
{
|
|
None,
|
|
Models,
|
|
Textures,
|
|
SkeletalAnim,
|
|
MaterialAnim,
|
|
ShaderParamAnim,
|
|
ColorAnim,
|
|
TexSrtAnim,
|
|
TexPatAnim,
|
|
BoneVisAnim,
|
|
MatVisAnim,
|
|
ShapeAnim,
|
|
SceneAnim,
|
|
Embedded,
|
|
}
|
|
|
|
public class BFRESGroupNode : STGenericWrapper, IContextMenuNode
|
|
{
|
|
public bool ShowNewContextMenu = true;
|
|
|
|
public bool IsWiiU;
|
|
|
|
public override void OnClick(TreeView treeview)
|
|
{
|
|
if (Parent is BFRES)
|
|
((BFRES)Parent).LoadEditors(this);
|
|
else if (Parent.Parent is BFRES) {
|
|
((BFRES)Parent.Parent).LoadEditors(this);
|
|
}else {
|
|
((BFRES)Parent.Parent.Parent).LoadEditors(this);
|
|
}
|
|
}
|
|
|
|
public BFRESGroupNode(bool isWiiU) : base()
|
|
{
|
|
ImageKey = "folder";
|
|
|
|
IsWiiU = isWiiU;
|
|
|
|
CanExport = false;
|
|
CanReplace = false;
|
|
CanRename = false;
|
|
CanDelete = false;
|
|
}
|
|
|
|
public ToolStripItem[] GetContextMenuItems()
|
|
{
|
|
List<ToolStripItem> Items = new List<ToolStripItem>();
|
|
|
|
Items.Add(new STToolStipMenuItem("New", null, NewAction, Keys.Control | Keys.N) { Enabled = ShowNewContextMenu });
|
|
Items.Add(new STToolStipMenuItem("Import", null, ImportAction, Keys.Control | Keys.I));
|
|
Items.Add(new ToolStripMenuItem("Export All", null, ExportAllAction, Keys.Control | Keys.E));
|
|
Items.Add(new ToolStripMenuItem("Replace (From Folder)", null, ReplaceAllAction, Keys.Control | Keys.R));
|
|
Items.Add(new STToolStripSeparator());
|
|
Items.Add(new STToolStipMenuItem("Sort", null, SortAction, Keys.Control | Keys.S));
|
|
Items.Add(new STToolStipMenuItem("Clear", null, ClearAction, Keys.Control | Keys.C));
|
|
|
|
if (Type == BRESGroupType.Textures)
|
|
{
|
|
Items.Add(new STToolStripSeparator());
|
|
Items.Add(new STToolStipMenuItem("Batch Generate Mipmaps", null, BatchGenerateMipmapsAction, Keys.Control | Keys.M));
|
|
}
|
|
if (Type == BRESGroupType.Models)
|
|
{
|
|
Items.Add(new STToolStripSeparator());
|
|
Items.Add(new STToolStipMenuItem("Show All Models", null, ShowAllModelsAction, Keys.Control | Keys.A));
|
|
Items.Add(new STToolStipMenuItem("Hide All Models", null, HideAllModelsAction, Keys.Control | Keys.H));
|
|
}
|
|
if (Type == BRESGroupType.SkeletalAnim)
|
|
{
|
|
Items.Add(new STToolStripSeparator());
|
|
Items.Add(new STToolStipMenuItem("Batch Edit Base Data", null, BatchEditBaseAnimDataAction, Keys.Control | Keys.A));
|
|
}
|
|
|
|
return Items.ToArray();
|
|
}
|
|
|
|
public override string ExportFilter { get { return GetSubfileExtensions(true); } }
|
|
public override string ImportFilter { get { return GetSubfileExtensions(false); } }
|
|
|
|
protected void NewAction(object sender, EventArgs e) { NewSubFile(); }
|
|
protected void BatchGenerateMipmapsAction(object sender, EventArgs e) { BatchGenerateMipmaps(); }
|
|
|
|
protected void HideAllModelsAction(object sender, EventArgs e) { HideAllModels(); }
|
|
protected void ShowAllModelsAction(object sender, EventArgs e) { ShowAllModels(); }
|
|
|
|
protected void BatchEditBaseAnimDataAction(object sender, EventArgs e) { BatchEditBaseAnimData(); }
|
|
|
|
private void BatchEditBaseAnimData()
|
|
{
|
|
if (Nodes.Count <= 0)
|
|
return;
|
|
|
|
BatchEditBaseAnimDataForm form = new BatchEditBaseAnimDataForm();
|
|
form.LoadAnim((Animation)Nodes[0]);
|
|
|
|
if (form.ShowDialog()== DialogResult.OK)
|
|
{
|
|
foreach (FSKA animation in Nodes)
|
|
{
|
|
if (animation.SkeletalAnimU != null)
|
|
{
|
|
foreach (var boneAnim in animation.SkeletalAnimU.BoneAnims)
|
|
{
|
|
if (boneAnim.Name == form.TargetBone)
|
|
{
|
|
var baseData = boneAnim.BaseData;
|
|
if (form.HasCustomScale)
|
|
{
|
|
boneAnim.FlagsBase |= ResU.BoneAnimFlagsBase.Scale;
|
|
boneAnim.ApplyScaleOne = false;
|
|
boneAnim.ApplyScaleUniform = false;
|
|
boneAnim.ApplySegmentScaleCompensate = form.SegmentScaleCompensate;
|
|
baseData.Scale = new Syroot.Maths.Vector3F(form.ScaleX, form.ScaleY, form.ScaleZ);
|
|
}
|
|
|
|
boneAnim.BaseData = baseData;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var boneAnim in animation.SkeletalAnim.BoneAnims)
|
|
{
|
|
if (boneAnim.Name == form.TargetBone)
|
|
{
|
|
var baseData = boneAnim.BaseData;
|
|
if (form.HasCustomScale)
|
|
{
|
|
boneAnim.FlagsBase |= ResNX.BoneAnimFlagsBase.Scale;
|
|
boneAnim.ApplyScaleOne = false;
|
|
boneAnim.ApplyScaleUniform = false;
|
|
boneAnim.ApplySegmentScaleCompensate = form.SegmentScaleCompensate;
|
|
baseData.Scale = new Syroot.Maths.Vector3F(form.ScaleX, form.ScaleY, form.ScaleZ);
|
|
}
|
|
|
|
boneAnim.BaseData = baseData;
|
|
}
|
|
}
|
|
}
|
|
|
|
animation.OpenAnimationData();
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void ReplaceAll()
|
|
{
|
|
FolderSelectDialog sfd = new FolderSelectDialog();
|
|
if (sfd.ShowDialog() == DialogResult.OK)
|
|
{
|
|
if (Type == BRESGroupType.Textures)
|
|
{
|
|
GTXTextureImporter importer = new GTXTextureImporter();
|
|
List<GTXImporterSettings> settings = new List<GTXImporterSettings>();
|
|
|
|
foreach (string file in System.IO.Directory.GetFiles(sfd.SelectedPath))
|
|
{
|
|
string FileName = System.IO.Path.GetFileNameWithoutExtension(file);
|
|
|
|
foreach (FTEX ftex in Nodes)
|
|
{
|
|
if (FileName == ftex.Text)
|
|
{
|
|
string ext = Path.GetExtension(file);
|
|
ext = ext.ToLower();
|
|
|
|
if (ext == ".bftex")
|
|
{
|
|
ftex.texture = new ResU.Texture();
|
|
ftex.texture.Import(file, GetResFileU());
|
|
ftex.IsEdited = true;
|
|
ftex.Read(ftex.texture);
|
|
}
|
|
else if (ext == ".dds" || ext == ".dds2")
|
|
{
|
|
ftex.texture = new ResU.Texture();
|
|
|
|
GTXImporterSettings setting = FTEX.SetImporterSettings(file);
|
|
if (setting.DataBlockOutput != null)
|
|
{
|
|
var surface = GTXSwizzle.CreateGx2Texture(setting.DataBlockOutput[0], setting);
|
|
var tex = FTEX.FromGx2Surface(surface, setting.TexName);
|
|
ftex.UpdateTex(tex);
|
|
|
|
ftex.IsEdited = true;
|
|
ftex.Read(ftex.texture);
|
|
ftex.LoadOpenGLTexture();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
settings.Add(FTEX.SetImporterSettings(file));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (settings.Count == 0)
|
|
{
|
|
importer.Dispose();
|
|
}
|
|
else
|
|
{
|
|
importer.LoadSettings(settings);
|
|
if (importer.ShowDialog() == DialogResult.OK)
|
|
{
|
|
foreach (var setting in settings)
|
|
{
|
|
foreach (FTEX ftex in Nodes)
|
|
{
|
|
if (setting.TexName == ftex.Text)
|
|
{
|
|
if (setting.GenerateMipmaps)
|
|
{
|
|
setting.DataBlockOutput.Clear();
|
|
setting.DataBlockOutput.Add(setting.GenerateMips());
|
|
}
|
|
|
|
if (setting.DataBlockOutput != null)
|
|
{
|
|
ftex.texture = new ResU.Texture();
|
|
var surface = GTXSwizzle.CreateGx2Texture(setting.DataBlockOutput[0], setting);
|
|
var tex = FTEX.FromGx2Surface(surface, setting.TexName);
|
|
ftex.UpdateTex(tex);
|
|
ftex.IsEdited = true;
|
|
|
|
ftex.Read(ftex.texture);
|
|
ftex.LoadOpenGLTexture();
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show("Something went wrong???");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
settings.Clear();
|
|
|
|
GC.Collect();
|
|
Cursor.Current = Cursors.Default;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (string file in System.IO.Directory.GetFiles(sfd.SelectedPath))
|
|
{
|
|
string FileName = System.IO.Path.GetFileNameWithoutExtension(file);
|
|
|
|
foreach (TreeNode node in Nodes)
|
|
{
|
|
if (node is STGenericWrapper)
|
|
{
|
|
if (FileName == node.Text)
|
|
{
|
|
((STGenericWrapper)node).Replace(file);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void BatchGenerateMipmaps()
|
|
{
|
|
foreach (FTEX texture in Nodes)
|
|
{
|
|
texture.SetImageData(texture.GetBitmap(), 0);
|
|
}
|
|
}
|
|
|
|
public void ShowAllModels()
|
|
{
|
|
for (int i = 0; i < Nodes.Count; i++)
|
|
{
|
|
Nodes[i].Checked = true;
|
|
}
|
|
}
|
|
|
|
public void HideAllModels()
|
|
{
|
|
for (int i = 0; i < Nodes.Count; i++)
|
|
{
|
|
Nodes[i].Checked = false;
|
|
}
|
|
}
|
|
|
|
public BFRESGroupNode(string name, bool isWiiU = false) : base() { Text = name; IsWiiU = isWiiU; }
|
|
public BFRESGroupNode(BRESGroupType type, bool isWiiU = false) : base() { Type = type; SetNameByType(); IsWiiU = isWiiU; }
|
|
|
|
public BRESGroupType Type { get; set; }
|
|
|
|
public Dictionary<string, STGenericWrapper> ResourceNodes = new Dictionary<string, STGenericWrapper>(); //To get instance of classes
|
|
|
|
public ResNX.ResFile GetResFile() {
|
|
if (Parent is BFRES)
|
|
return ((BFRES)Parent).resFile;
|
|
else
|
|
return ((BFRES)Parent.Parent).resFile;
|
|
}
|
|
|
|
public ResU.ResFile GetResFileU() {
|
|
if (Parent is BFRES)
|
|
return ((BFRES)Parent).resFileU;
|
|
else
|
|
return ((BFRES)Parent.Parent).resFileU;
|
|
}
|
|
|
|
|
|
public void NewSubFile()
|
|
{
|
|
switch (Type)
|
|
{
|
|
case BRESGroupType.Models: NewModel(); break;
|
|
case BRESGroupType.SkeletalAnim: ((BFRESAnimFolder)Parent).NewSkeletalAnim(); break;
|
|
case BRESGroupType.ShaderParamAnim: ((BFRESAnimFolder)Parent).ImportShaderParamAnim(); break;
|
|
case BRESGroupType.ColorAnim: ((BFRESAnimFolder)Parent).NewColorAnim(); break;
|
|
case BRESGroupType.TexSrtAnim: ((BFRESAnimFolder)Parent).NewTexSrtAnim(); break;
|
|
case BRESGroupType.TexPatAnim: ((BFRESAnimFolder)Parent).NewTexPatAnim(); break;
|
|
case BRESGroupType.BoneVisAnim: ((BFRESAnimFolder)Parent).NewBoneVisAnim(); break;
|
|
case BRESGroupType.MatVisAnim: ((BFRESAnimFolder)Parent).NewMatVisAnim(); break;
|
|
case BRESGroupType.ShapeAnim: ((BFRESAnimFolder)Parent).NewShapeAnim(); break;
|
|
case BRESGroupType.SceneAnim: ((BFRESAnimFolder)Parent).NewSceneAnim(); break;
|
|
case BRESGroupType.Embedded: NewExternalFile(); break;
|
|
}
|
|
}
|
|
|
|
public FMDL NewModel(bool AddTreeNode = true)
|
|
{
|
|
FMDL fmdl = new FMDL();
|
|
|
|
if (IsWiiU)
|
|
{
|
|
fmdl.ModelU = new ResU.Model();
|
|
|
|
//Create skeleton with empty bone
|
|
var skeleton = new ResU.Skeleton();
|
|
|
|
//Create skeleton with empty bone
|
|
skeleton.Bones.Add("Root", new ResU.Bone() { Name = "Root" });
|
|
|
|
fmdl.ModelU.Skeleton = skeleton;
|
|
|
|
var shape = new ResU.Shape() { Name = "NewShape" };
|
|
shape.CreateEmptyMesh();
|
|
|
|
var VertexBuffer = new ResU.VertexBuffer();
|
|
VertexBuffer.CreateEmptyVertexBuffer();
|
|
|
|
fmdl.ModelU.VertexBuffers.Add(VertexBuffer);
|
|
fmdl.ModelU.Shapes.Add("NewShape", shape);
|
|
fmdl.ModelU.Materials.Add("NewMaterial", new ResU.Material() { Name = "NewMaterial", RenderState = new ResU.RenderState(), });
|
|
|
|
BfresWiiU.ReadModel(fmdl, fmdl.ModelU);
|
|
((BFRES)Parent).DrawableContainer.Drawables.Add(fmdl.Skeleton);
|
|
}
|
|
else
|
|
{
|
|
fmdl.Model = new ResNX.Model();
|
|
|
|
//Create skeleton with empty bone
|
|
var skeleton = new ResNX.Skeleton();
|
|
|
|
//Create skeleton with empty bone
|
|
skeleton.Bones.Add(new ResNX.Bone() { Name = "Root" });
|
|
|
|
fmdl.Model.Skeleton = skeleton;
|
|
|
|
var shape = new ResNX.Shape() { Name = "NewShape" };
|
|
shape.CreateEmptyMesh();
|
|
|
|
fmdl.Model.Shapes.Add(shape);
|
|
fmdl.Model.Materials.Add(new ResNX.Material() { Name = "NewMaterial" });
|
|
|
|
var VertexBuffer = new ResNX.VertexBuffer();
|
|
VertexBuffer.CreateEmptyVertexBuffer();
|
|
|
|
fmdl.Model.VertexBuffers.Add(VertexBuffer);
|
|
|
|
BfresSwitch.ReadModel(fmdl, fmdl.Model);
|
|
((BFRES)Parent).DrawableContainer.Drawables.Add(fmdl.Skeleton);
|
|
}
|
|
|
|
if (AddTreeNode)
|
|
AddNode(fmdl, "NewModel");
|
|
|
|
return fmdl;
|
|
}
|
|
|
|
public void NewExternalFile()
|
|
{
|
|
ExternalFileData externalFileData = new ExternalFileData("NewExternalFile", new byte[0]);
|
|
AddNode(externalFileData, "NewExternalFile");
|
|
}
|
|
|
|
|
|
private string GetSubfileExtensions(bool IsExporting)
|
|
{
|
|
switch (Type)
|
|
{
|
|
case BRESGroupType.Models: return FileFilters.GetFilter(typeof(FMDL), null, IsExporting);
|
|
case BRESGroupType.Textures: return FileFilters.GetFilter(typeof(FTEX), null, IsExporting);
|
|
case BRESGroupType.SkeletalAnim: return FileFilters.GetFilter(typeof(FSKA), null, IsExporting);
|
|
case BRESGroupType.MaterialAnim: return FileFilters.GetFilter(typeof(FMAA), null, IsExporting);
|
|
case BRESGroupType.ShaderParamAnim: return FileFilters.GetFilter(typeof(FSHU), null, IsExporting);
|
|
case BRESGroupType.ColorAnim: return FileFilters.GetFilter(typeof(FSHU), MaterialAnimation.AnimationType.Color, IsExporting);
|
|
case BRESGroupType.TexSrtAnim: return FileFilters.GetFilter(typeof(FSHU), MaterialAnimation.AnimationType.TextureSrt, IsExporting);
|
|
case BRESGroupType.TexPatAnim: return FileFilters.GetFilter(typeof(FTXP), MaterialAnimation.AnimationType.ShaderParam, IsExporting);
|
|
case BRESGroupType.BoneVisAnim: return FileFilters.GetFilter(typeof(FVIS), null, IsExporting);
|
|
case BRESGroupType.MatVisAnim: return FileFilters.GetFilter(typeof(FVIS), null, IsExporting);
|
|
case BRESGroupType.ShapeAnim: return FileFilters.GetFilter(typeof(FSHA), null, IsExporting);
|
|
case BRESGroupType.SceneAnim: return FileFilters.GetFilter(typeof(FSCN), null, IsExporting);
|
|
case BRESGroupType.Embedded: return FileFilters.GetFilter(typeof(ExternalFileData), null, IsExporting);
|
|
default: return "All files(*.*)|*.*";
|
|
}
|
|
}
|
|
|
|
public override void Import(string[] FileNames) {
|
|
Import(FileNames, GetResFile(), GetResFileU());
|
|
}
|
|
|
|
public void Import(string[] FileNames, ResNX.ResFile resFileNX, ResU.ResFile resFileU)
|
|
{
|
|
if (Type == BRESGroupType.Textures)
|
|
{
|
|
ImportTexture(FileNames);
|
|
return;
|
|
}
|
|
|
|
foreach (string FileName in FileNames)
|
|
{
|
|
string ResourceName = Path.GetFileNameWithoutExtension(FileName);
|
|
string ResourceNameExt = Path.GetFileName(FileName);
|
|
|
|
string extension = Path.GetExtension(FileName);
|
|
|
|
switch (Type)
|
|
{
|
|
case BRESGroupType.Models:
|
|
FMDL fmdl = NewModel(false);
|
|
fmdl.Text = ResourceName;
|
|
fmdl.Replace(FileName, resFileNX, resFileU);
|
|
fmdl.UpdateVertexData();
|
|
AddNode(fmdl);
|
|
break;
|
|
case BRESGroupType.SkeletalAnim:
|
|
FSKA fska = new FSKA();
|
|
fska.Text = ResourceName;
|
|
if (IsWiiU)
|
|
fska.SkeletalAnimU = new ResU.SkeletalAnim();
|
|
else
|
|
fska.SkeletalAnim = new ResNX.SkeletalAnim();
|
|
|
|
fska.Replace(FileName, resFileNX, resFileU);
|
|
Nodes.Add(fska);
|
|
break;
|
|
case BRESGroupType.ShaderParamAnim:
|
|
if (IsWiiU)
|
|
{
|
|
FSHU fshu = new FSHU(new ResU.ShaderParamAnim(), MaterialAnimation.AnimationType.ShaderParam);
|
|
fshu.Text = ResourceName;
|
|
fshu.Replace(FileName, resFileU);
|
|
Nodes.Add(fshu);
|
|
}
|
|
else
|
|
{
|
|
FMAA fmaaPrm = new FMAA(new ResNX.MaterialAnim(), MaterialAnimation.AnimationType.ShaderParam);
|
|
fmaaPrm.Text = ResourceName;
|
|
fmaaPrm.Replace(FileName);
|
|
Nodes.Add(fmaaPrm);
|
|
}
|
|
break;
|
|
case BRESGroupType.ColorAnim:
|
|
if (IsWiiU)
|
|
{
|
|
FSHU fclh = new FSHU(new ResU.ShaderParamAnim(), MaterialAnimation.AnimationType.Color);
|
|
fclh.Text = ResourceName;
|
|
fclh.Replace(FileName, resFileU);
|
|
Nodes.Add(fclh);
|
|
}
|
|
else
|
|
{
|
|
FMAA fmaaClr = new FMAA(new ResNX.MaterialAnim(), MaterialAnimation.AnimationType.Color);
|
|
fmaaClr.Text = ResourceName;
|
|
fmaaClr.Replace(FileName);
|
|
Nodes.Add(fmaaClr);
|
|
}
|
|
break;
|
|
case BRESGroupType.TexSrtAnim:
|
|
if (IsWiiU)
|
|
{
|
|
FSHU fsth = new FSHU(new ResU.ShaderParamAnim(), MaterialAnimation.AnimationType.TextureSrt);
|
|
fsth.Text = ResourceName;
|
|
fsth.Replace(FileName, resFileU);
|
|
Nodes.Add(fsth);
|
|
}
|
|
else
|
|
{
|
|
FMAA fmaaSrt = new FMAA(new ResNX.MaterialAnim(), MaterialAnimation.AnimationType.TextureSrt);
|
|
fmaaSrt.Text = ResourceName;
|
|
fmaaSrt.Replace(FileName);
|
|
Nodes.Add(fmaaSrt);
|
|
}
|
|
break;
|
|
case BRESGroupType.TexPatAnim:
|
|
FTXP ftxp = new FTXP(new ResU.TexPatternAnim());
|
|
ftxp.Text = ResourceName;
|
|
ftxp.Replace(FileName, resFileU);
|
|
Nodes.Add(ftxp);
|
|
break;
|
|
case BRESGroupType.BoneVisAnim:
|
|
FVIS fbnv = new FVIS();
|
|
fbnv.Text = ResourceName;
|
|
if (IsWiiU)
|
|
fbnv.VisibilityAnimU = new ResU.VisibilityAnim() { Type = ResU.VisibilityAnimType.Bone };
|
|
else
|
|
fbnv.VisibilityAnim = new ResNX.VisibilityAnim();
|
|
|
|
fbnv.Replace(FileName, resFileNX, resFileU);
|
|
Nodes.Add(fbnv);
|
|
break;
|
|
case BRESGroupType.MatVisAnim:
|
|
if (IsWiiU)
|
|
{
|
|
FVIS fmtv = new FVIS(new ResU.VisibilityAnim() { Type = ResU.VisibilityAnimType.Material });
|
|
fmtv.Text = ResourceName;
|
|
fmtv.Replace(FileName, resFileNX, resFileU);
|
|
Nodes.Add(fmtv);
|
|
}
|
|
else
|
|
{
|
|
FMAA fmaaVis = new FMAA(new ResNX.MaterialAnim(), MaterialAnimation.AnimationType.Visibilty);
|
|
fmaaVis.Text = ResourceName;
|
|
fmaaVis.Replace(FileName);
|
|
Nodes.Add(fmaaVis);
|
|
}
|
|
break;
|
|
case BRESGroupType.ShapeAnim:
|
|
FSHA fsha = new FSHA();
|
|
fsha.Text = ResourceName;
|
|
if (IsWiiU)
|
|
fsha.ShapeAnimU = new ResU.ShapeAnim();
|
|
else
|
|
fsha.ShapeAnim = new ResNX.ShapeAnim();
|
|
|
|
fsha.Replace(FileName, resFileNX, resFileU);
|
|
Nodes.Add(fsha);
|
|
break;
|
|
case BRESGroupType.SceneAnim:
|
|
FSCN fscn = new FSCN();
|
|
fscn.Text = ResourceName;
|
|
if (IsWiiU)
|
|
fscn.SceneAnimU = new ResU.SceneAnim();
|
|
else
|
|
fscn.SceneAnim = new ResNX.SceneAnim();
|
|
|
|
fscn.Replace(FileName, resFileNX, resFileU);
|
|
Nodes.Add(fscn);
|
|
break;
|
|
case BRESGroupType.Embedded:
|
|
ExternalFileData ext = new ExternalFileData(ResourceNameExt, File.ReadAllBytes(FileName));
|
|
ext.Replace(FileName);
|
|
Nodes.Add(ext);
|
|
break;
|
|
case BRESGroupType.MaterialAnim:
|
|
FMAA fmaa = new FMAA(new ResNX.MaterialAnim(), MaterialAnimation.AnimationType.ShaderParam);
|
|
fmaa.Replace(FileName);
|
|
Nodes.Add(fmaa);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void AddNode(STGenericWrapper node, string Name)
|
|
{
|
|
node.Text = SearchDuplicateName(Name);
|
|
|
|
AddNode(node);
|
|
}
|
|
|
|
public void AddNode(STGenericWrapper node)
|
|
{
|
|
if (node.Text == string.Empty)
|
|
throw new System.Exception("Text invalid. Must not be empty! ");
|
|
|
|
Nodes.Add(node);
|
|
ResourceNodes.Add(node.Text, node);
|
|
}
|
|
|
|
public void RemoveChild(STGenericWrapper node)
|
|
{
|
|
Nodes.Remove(node);
|
|
ResourceNodes.Remove(node.Text);
|
|
}
|
|
|
|
|
|
public override void Clear()
|
|
{
|
|
var result = MessageBox.Show("Are you sure you want to clear this section? This cannot be undone!",
|
|
"", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
|
|
|
if (result == DialogResult.Yes)
|
|
{
|
|
foreach (TreeNode node in Nodes)
|
|
{
|
|
if (node is STGenericWrapper)
|
|
{
|
|
((STGenericWrapper)node).Unload();
|
|
RemoveChild(((STGenericWrapper)node));
|
|
}
|
|
}
|
|
|
|
ResourceNodes.Clear();
|
|
Nodes.Clear();
|
|
|
|
if (Type == BRESGroupType.Models)
|
|
{
|
|
((BFRES)Parent).BFRESRender.UpdateModelList();
|
|
LibraryGUI.UpdateViewport();
|
|
}
|
|
}
|
|
}
|
|
|
|
public STGenericWrapper GetFirstChild()
|
|
{
|
|
if (Nodes.Count > 0 && Nodes[0] is STGenericWrapper)
|
|
return (STGenericWrapper)Nodes[0];
|
|
else
|
|
return new STGenericWrapper();
|
|
}
|
|
|
|
public void SetNameByType()
|
|
{
|
|
Text = SetName();
|
|
}
|
|
|
|
private string SetName()
|
|
{
|
|
switch (Type)
|
|
{
|
|
case BRESGroupType.Models: return "Models";
|
|
case BRESGroupType.Textures: return "Textures";
|
|
case BRESGroupType.SkeletalAnim: return "Skeletal Animations";
|
|
case BRESGroupType.ShaderParamAnim: return "Shader Param Animations";
|
|
case BRESGroupType.ColorAnim: return "Color Animations";
|
|
case BRESGroupType.TexSrtAnim: return "Texture SRT Animations";
|
|
case BRESGroupType.TexPatAnim: return "Texture Pattern Animations";
|
|
case BRESGroupType.BoneVisAnim: return "Bone Visibilty Animations";
|
|
case BRESGroupType.MatVisAnim: return "Material Visibilty Animations";
|
|
case BRESGroupType.ShapeAnim: return "Shape Animations";
|
|
case BRESGroupType.SceneAnim: return "Scene Animations";
|
|
case BRESGroupType.Embedded: return "Embedded Files";
|
|
case BRESGroupType.MaterialAnim: return "Material Animations";
|
|
default:
|
|
throw new System.Exception("Unknown type? " + Type);
|
|
}
|
|
}
|
|
|
|
public void GetFileType()
|
|
{
|
|
var child = GetFirstChild();
|
|
|
|
if (Text == "Models" || child is FMDL)
|
|
Type = BRESGroupType.Models;
|
|
if (Text == "Textures" || child is FTEX)
|
|
Type = BRESGroupType.Textures;
|
|
if (Text == "Skeleton Animations" || child is FSKA)
|
|
Type = BRESGroupType.SkeletalAnim;
|
|
if (Text == "Material Animations" || child is FMAA)
|
|
Type = BRESGroupType.MaterialAnim;
|
|
if (Text == "Shader Param Animations" || child is FSHU)
|
|
Type = BRESGroupType.ShaderParamAnim;
|
|
if (Text == "Color Animations" || child is FSHU)
|
|
Type = BRESGroupType.ColorAnim;
|
|
if (Text == "Texture Srt Animations" || child is FSHU)
|
|
Type = BRESGroupType.TexSrtAnim;
|
|
if (Text == "Texture Pattern Animations" || child is FTXP)
|
|
Type = BRESGroupType.TexPatAnim;
|
|
if (Text == "Bone Visibilty Animations" || child is FVIS)
|
|
Type = BRESGroupType.BoneVisAnim;
|
|
if (Text == "Material Visibilty Animations" || child is FVIS)
|
|
Type = BRESGroupType.MatVisAnim;
|
|
if (Text == "Embedded Files" || child is ExternalFileData)
|
|
Type = BRESGroupType.Embedded;
|
|
}
|
|
|
|
int IndexStr = 0;
|
|
public string SearchDuplicateName(string Name)
|
|
{
|
|
if (ResourceNodes.ContainsKey(Name))
|
|
return SearchDuplicateName($"{Name}{IndexStr++}");
|
|
else
|
|
return Name;
|
|
}
|
|
|
|
public void ImportTexture(string[] FileNames)
|
|
{
|
|
GTXTextureImporter importer = new GTXTextureImporter();
|
|
List<GTXImporterSettings> settings = new List<GTXImporterSettings>();
|
|
|
|
foreach (string name in FileNames)
|
|
{
|
|
string TextureName = Path.GetFileNameWithoutExtension(name);
|
|
|
|
|
|
string ext = Path.GetExtension(name);
|
|
ext = ext.ToLower();
|
|
|
|
if (ext == ".bftex")
|
|
{
|
|
FTEX ftex = new FTEX();
|
|
ftex.texture = new ResU.Texture();
|
|
ftex.texture.Import(name, GetResFileU());
|
|
ftex.IsEdited = true;
|
|
ftex.Read(ftex.texture);
|
|
AddNode(ftex);
|
|
}
|
|
else if (ext == ".dds" || ext == ".dds2")
|
|
{
|
|
FTEX ftex = new FTEX();
|
|
ftex.texture = new ResU.Texture();
|
|
|
|
GTXImporterSettings setting = FTEX.SetImporterSettings(name);
|
|
|
|
if (setting.DataBlockOutput != null)
|
|
{
|
|
var surface = GTXSwizzle.CreateGx2Texture(setting.DataBlockOutput[0], setting);
|
|
var tex = FTEX.FromGx2Surface(surface, setting.TexName);
|
|
ftex.UpdateTex(tex);
|
|
|
|
ftex.IsEdited = true;
|
|
ftex.Read(ftex.texture);
|
|
ftex.LoadOpenGLTexture();
|
|
AddNode(ftex);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
settings.Add(FTEX.SetImporterSettings(name));
|
|
}
|
|
}
|
|
if (settings.Count == 0)
|
|
{
|
|
importer.Dispose();
|
|
}
|
|
else
|
|
{
|
|
importer.LoadSettings(settings);
|
|
if (importer.ShowDialog() == DialogResult.OK)
|
|
{
|
|
ImportTexture(settings);
|
|
|
|
settings.Clear();
|
|
|
|
GC.Collect();
|
|
Cursor.Current = Cursors.Default;
|
|
}
|
|
}
|
|
}
|
|
|
|
public GTXImporterSettings LoadSettings(System.Drawing.Image image, string Name)
|
|
{
|
|
var importer = new GTXImporterSettings();
|
|
importer.LoadBitMap(image, Name);
|
|
return importer;
|
|
}
|
|
|
|
private void ImportTexture(List<GTXImporterSettings> settings)
|
|
{
|
|
Cursor.Current = Cursors.WaitCursor;
|
|
foreach (var setting in settings)
|
|
{
|
|
if (setting.GenerateMipmaps)
|
|
{
|
|
setting.DataBlockOutput.Clear();
|
|
setting.DataBlockOutput.Add(setting.GenerateMips());
|
|
}
|
|
|
|
if (setting.DataBlockOutput != null)
|
|
{
|
|
FTEX ftex = new FTEX();
|
|
ftex.texture = new ResU.Texture();
|
|
var surface = GTXSwizzle.CreateGx2Texture(setting.DataBlockOutput[0], setting);
|
|
var tex = FTEX.FromGx2Surface(surface, setting.TexName);
|
|
ftex.UpdateTex(tex);
|
|
ftex.IsEdited = true;
|
|
|
|
ftex.Read(ftex.texture);
|
|
ftex.LoadOpenGLTexture();
|
|
AddNode(ftex);
|
|
}
|
|
else
|
|
{
|
|
MessageBox.Show("Something went wrong???");
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ImportTexture(ImageKeyFrame[] Keys, string TextureName)
|
|
{
|
|
if (ResourceNodes.ContainsKey(TextureName) || Type != BRESGroupType.Textures)
|
|
return;
|
|
|
|
GTXTextureImporter importer = new GTXTextureImporter();
|
|
List<GTXImporterSettings> settings = new List<GTXImporterSettings>();
|
|
|
|
foreach (var key in Keys) {
|
|
settings.Add(FTEX.SetImporterSettings(key.Image, $"{TextureName}{key.Frame}"));
|
|
}
|
|
|
|
importer.LoadSettings(settings);
|
|
|
|
if (importer.ShowDialog() == DialogResult.OK) {
|
|
ImportTexture(settings);
|
|
}
|
|
|
|
settings.Clear();
|
|
GC.Collect();
|
|
Cursor.Current = Cursors.Default;
|
|
}
|
|
|
|
public void ImportPlaceholderTexture(string TextureName)
|
|
{
|
|
if (ResourceNodes.ContainsKey(TextureName) || Type != BRESGroupType.Textures)
|
|
return;
|
|
|
|
if (TextureName == "Basic_Alb")
|
|
ImportBasicTextures("Basic_Alb");
|
|
else if (TextureName == "Basic_Nrm")
|
|
ImportBasicTextures("Basic_Nrm");
|
|
else if (TextureName == "Basic_Spm")
|
|
ImportBasicTextures("Basic_Spm");
|
|
else if (TextureName == "Basic_Sphere")
|
|
ImportBasicTextures("Basic_Sphere");
|
|
else if (TextureName == "Basic_Mtl")
|
|
ImportBasicTextures("Basic_Mtl");
|
|
else if (TextureName == "Basic_Rgh")
|
|
ImportBasicTextures("Basic_Rgh");
|
|
else if (TextureName == "Basic_MRA")
|
|
ImportBasicTextures("Basic_MRA");
|
|
else if (TextureName == "Basic_Bake_st0")
|
|
ImportBasicTextures("Basic_Bake_st0");
|
|
else if (TextureName == "Basic_Bake_st1")
|
|
ImportBasicTextures("Basic_Bake_st1");
|
|
else if (TextureName == "Basic_Emm")
|
|
ImportBasicTextures("Basic_Emm");
|
|
else
|
|
{
|
|
ImportPlaceholderTexture(FirstPlugin.Properties.Resources.InjectTexErrored, TextureName);
|
|
}
|
|
}
|
|
private void ImportPlaceholderTexture(byte[] data, string TextureName)
|
|
{
|
|
GTXImporterSettings setting = new GTXImporterSettings();
|
|
setting.LoadDDS(TextureName, data);
|
|
|
|
var surface = GTXSwizzle.CreateGx2Texture(setting.DataBlockOutput[0], setting);
|
|
FTEX ftex = new FTEX();
|
|
ftex.texture = new ResU.Texture();
|
|
ftex.texture = FTEX.FromGx2Surface(surface, setting.TexName);
|
|
ftex.IsEdited = true;
|
|
ftex.Read(ftex.texture);
|
|
|
|
AddNode(ftex);
|
|
ftex.LoadOpenGLTexture();
|
|
}
|
|
public void ImportBasicTextures(string TextureName, bool BC5Nrm = true)
|
|
{
|
|
if (ResourceNodes.ContainsKey(TextureName) || Type != BRESGroupType.Textures)
|
|
return;
|
|
|
|
if (TextureName == "Basic_Alb")
|
|
ImportPlaceholderTexture(FirstPlugin.Properties.Resources.InjectTexErrored, TextureName);
|
|
if (TextureName == "Basic_Nrm" && BC5Nrm)
|
|
ImportPlaceholderTexture(FirstPlugin.Properties.Resources.Basic_NrmBC5, TextureName);
|
|
if (TextureName == "Basic_Nrm" && BC5Nrm == false)
|
|
ImportPlaceholderTexture(FirstPlugin.Properties.Resources.Basic_Nrm, TextureName);
|
|
if (TextureName == "Basic_Spm")
|
|
ImportPlaceholderTexture(FirstPlugin.Properties.Resources.Black, TextureName);
|
|
if (TextureName == "Basic_Sphere")
|
|
ImportPlaceholderTexture(FirstPlugin.Properties.Resources.Black, TextureName);
|
|
if (TextureName == "Basic_Mtl")
|
|
ImportPlaceholderTexture(FirstPlugin.Properties.Resources.Black, TextureName);
|
|
if (TextureName == "Basic_Rgh")
|
|
ImportPlaceholderTexture(FirstPlugin.Properties.Resources.White, TextureName);
|
|
if (TextureName == "Basic_MRA")
|
|
ImportPlaceholderTexture(FirstPlugin.Properties.Resources.Black, TextureName);
|
|
if (TextureName == "Basic_Bake_st0")
|
|
ImportPlaceholderTexture(FirstPlugin.Properties.Resources.Basic_Bake_st0, TextureName);
|
|
if (TextureName == "Basic_Bake_st1")
|
|
ImportPlaceholderTexture(FirstPlugin.Properties.Resources.Basic_Bake_st1, TextureName);
|
|
}
|
|
}
|
|
}
|