1
0
mirror of synced 2024-11-12 02:00:50 +01:00

Add option to remove unused textures on save.

This commit is contained in:
KillzXGaming 2019-06-01 12:30:17 -04:00
parent 7845840209
commit 4d7171605b
17 changed files with 203 additions and 135 deletions

Binary file not shown.

View File

@ -57,7 +57,7 @@ namespace FirstPlugin
else if (f.Matches(0x00000004)) return ".gfbanm";
else if (f.Matches(0x00000014)) return ".gfbanm";
else if (f.Matches(0x00000018)) return ".gfbanmcfg";
else if (f.Matches(0x00000002)) return ".gfbmdl";
else if (f.Matches(0x00000020)) return ".gfbmdl";
else if (f.Matches(0x00000044)) return ".gfbpokecfg";
else return "";
}

View File

@ -1338,6 +1338,9 @@ namespace FirstPlugin
}
if (node is BNTX)
{
if (SettingRemoveUnusedTextures)
RemoveUnusedTextures((BNTX)node);
if (((BNTX)node).Textures.Count > 0)
{
resFile.ExternalFiles.Add(new ExternalFile() { Data = ((BNTX)node).Save() });
@ -1351,6 +1354,86 @@ namespace FirstPlugin
resFile.Save(mem);
}
private void RemoveUnusedTextures(BFRESGroupNode ftexGroup)
{
var models = GetModels();
if (models == null)
return;
List<string> Keys = ftexGroup.ResourceNodes.Select(x => x.Key).ToList();
var AllTextures = GetAllTextures();
for (int i = 0; i < Keys.Count; i++)
{
//If nowhere in the bfres contains the key, we can remove it
if (!AllTextures.Contains(Keys[i]))
{
ftexGroup.RemoveChild(ftexGroup.ResourceNodes[Keys[i]]);
}
}
}
private void RemoveUnusedTextures(BNTX bntx)
{
var models = GetModels();
if (models == null)
return;
List<string> Keys = bntx.Textures.Select(x => x.Key).ToList();
var AllTextures = GetAllTextures();
for (int i = 0; i < Keys.Count; i++)
{
//If nowhere in the bfres contains the key, we can remove it
if (!AllTextures.Contains(Keys[i]))
{
bntx.RemoveTexture(bntx.Textures[Keys[i]]);
}
}
}
private List<string> GetAllTextures()
{
List<string> AllTextures = new List<string>();
foreach (TreeNode group in Nodes)
{
if (group is BFRESGroupNode && ((BFRESGroupNode)group).Type == BRESGroupType.Models)
{
for (int i = 0; i < group.Nodes.Count; i++)
{
foreach (var material in ((FMDL)group.Nodes[i]).materials.Values)
{
foreach (var tex in material.TextureMaps)
{
if (!AllTextures.Contains(tex.Name))
AllTextures.Add(tex.Name);
}
}
}
}
if (group is BFRESAnimFolder)
{
foreach (BFRESGroupNode animGroup in group.Nodes)
{
if (animGroup.Type == BRESGroupType.TexPatAnim)
{
for (int i = 0; i < group.Nodes.Count; i++)
{
foreach (var tex in ((MaterialAnimation)group.Nodes[i]).Textures)
{
if (!AllTextures.Contains(tex))
AllTextures.Add(tex);
}
}
}
}
}
}
return AllTextures;
}
private static void SaveBfresSwitchGroup(BFRESGroupNode group, ResFile resFile)
{
switch (group.Type)
@ -1453,12 +1536,12 @@ namespace FirstPlugin
foreach (TreeNode node in Nodes)
{
if (node is BFRESGroupNode)
SaveBfresWiiUGroup((BFRESGroupNode)node, resFileU);
SaveBfresWiiUGroup(this, (BFRESGroupNode)node, resFileU);
if (node is BFRESAnimFolder)
{
foreach (var animGroup in node.Nodes)
SaveBfresWiiUGroup((BFRESGroupNode)animGroup, resFileU);
SaveBfresWiiUGroup(this, (BFRESGroupNode)animGroup, resFileU);
}
}
@ -1466,7 +1549,7 @@ namespace FirstPlugin
resFileU.Save(mem);
}
private static void SaveBfresWiiUGroup(BFRESGroupNode group, ResU.ResFile resFileU)
private static void SaveBfresWiiUGroup(BFRES bfres, BFRESGroupNode group, ResU.ResFile resFileU)
{
switch (group.Type)
{
@ -1478,6 +1561,9 @@ namespace FirstPlugin
}
break;
case BRESGroupType.Textures:
if (bfres.SettingRemoveUnusedTextures)
bfres.RemoveUnusedTextures(group);
for (int i = 0; i < group.Nodes.Count; i++)
{
((FTEX)group.Nodes[i]).texture.Name = group.Nodes[i].Text;

View File

@ -189,7 +189,7 @@ namespace Bfres.Structs
fmdl.ModelU.VertexBuffers.Add(VertexBuffer);
fmdl.ModelU.Shapes.Add("NewShape", shape);
fmdl.ModelU.Materials.Add("NewMaterial", new ResU.Material() { Name = "NewMaterial" });
fmdl.ModelU.Materials.Add("NewMaterial", new ResU.Material() { Name = "NewMaterial", RenderState = new ResU.RenderState(), });
BfresWiiU.ReadModel(fmdl, fmdl.ModelU);
((BFRES)Parent).AddSkeletonDrawable(fmdl.Skeleton);

View File

@ -154,14 +154,14 @@ namespace Bfres.Structs
foreach (var sampler in mat.Samplers)
{
//If constant, create a constant instance with the first value set
if (sampler.group.Constant)
if (sampler.Constant)
{
AnimConstant animConstant = new AnimConstant();
animConstant.AnimDataOffset = 0;
animConstant.Value = sampler.group.GetValue(0);
animConstant.Value = sampler.GetValue(0);
data.Constants.Add(animConstant);
}
else if (sampler.group.Keys.Count > 0)
else if (sampler.Keys.Count > 0)
{
//If a sampler is not constant and uses curve data, then we need to set our begin curve index
if (!SetBeginCurve)
@ -183,13 +183,13 @@ namespace Bfres.Structs
curve.CurveType = AnimCurveType.StepBool;
else
{
if (sampler.group.InterpolationType == InterpolationType.HERMITE)
if (sampler.InterpolationType == InterpolationType.HERMITE)
curve.CurveType = AnimCurveType.Cubic;
if (sampler.group.InterpolationType == InterpolationType.LINEAR)
if (sampler.InterpolationType == InterpolationType.LINEAR)
curve.CurveType = AnimCurveType.Linear;
if (sampler.group.InterpolationType == InterpolationType.STEP)
if (sampler.InterpolationType == InterpolationType.STEP)
curve.CurveType = AnimCurveType.StepInt;
if (sampler.group.InterpolationType == InterpolationType.STEPBOOL)
if (sampler.InterpolationType == InterpolationType.STEPBOOL)
curve.CurveType = AnimCurveType.StepBool;
}
@ -203,12 +203,12 @@ namespace Bfres.Structs
List<float> Frames = new List<float>();
List<float> Keys = new List<float>();
for (int frame = 0; frame < sampler.group.Keys.Count; frame++)
for (int frame = 0; frame < sampler.Keys.Count; frame++)
{
float currentIndex = sampler.group.GetValue(frame);
float currentIndex = sampler.GetValue(frame);
if (frame > 0)
{
float previousIndex = sampler.group.GetValue(frame - 1);
float previousIndex = sampler.GetValue(frame - 1);
if (currentIndex != previousIndex)
{
//Add key frame if texture not loaded previously
@ -431,43 +431,35 @@ namespace Bfres.Structs
int textureIndex = 0;
uint animOffset = 0;
if (SamplerInfo.BeginConstant != 65535)
{
animOffset = matanim.Constants[SamplerInfo.BeginConstant].AnimDataOffset;
textureIndex = matanim.Constants[SamplerInfo.BeginConstant].Value;
var group = new Animation.KeyGroup();
group.AnimDataOffset = animOffset;
group.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = textureIndex });
group.Constant = true;
sampler.group = group;
sampler.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = textureIndex });
sampler.Constant = true;
sampler.AnimDataOffset = matanim.Constants[SamplerInfo.BeginConstant].AnimDataOffset;
}
if (SamplerInfo.CurveIndex != 65535)
{
int index = (int)SamplerInfo.CurveIndex;
Animation.KeyGroup keyGroup = CurveHelper.CreateTrack(matanim.Curves[index]);
keyGroup.AnimDataOffset = matanim.Curves[index].AnimDataOffset;
sampler.group = new KeyGroup()
{
AnimDataOffset = keyGroup.AnimDataOffset,
Keys = keyGroup.Keys,
};
sampler.AnimDataOffset = matanim.Curves[index].AnimDataOffset;
sampler.Keys = keyGroup.Keys;
}
}
}
}
public class BfresSamplerAnim : Material.Sampler
public class BfresSamplerAnim : SamplerKeyGroup
{
FMAA MatAnimWrapper;
MaterialAnimEntry MatWrapper;
public BfresSamplerAnim(string Name, FMAA materialAnimation, MaterialAnimEntry material)
public BfresSamplerAnim(string Name, FMAA materialAnimation, MaterialAnimEntry material) : base(materialAnimation)
{
MatWrapper = material;
MatAnimWrapper = materialAnimation;
@ -476,13 +468,13 @@ namespace Bfres.Structs
public override string GetActiveTextureName(int frame)
{
uint val = (uint)group.GetValue(frame);
uint val = (uint)GetValue(frame);
return MatAnimWrapper.Textures[(int)val];
}
public void AddKeyFrame(string TextureName, float Frame = -1, bool IsConstant = false)
{
group.Constant = IsConstant;
Constant = IsConstant;
var MatAnim = MatAnimWrapper.MaterialAnim;
@ -497,11 +489,11 @@ namespace Bfres.Structs
if (Frame == -1)
{
Frame = group.EndFrame + 1; //Add to the end of the list by default
Frame = EndFrame + 1; //Add to the end of the list by default
}
//For non constants we load a curve
if (!group.Constant)
if (!Constant)
{
}
}
@ -528,7 +520,7 @@ namespace Bfres.Structs
public override STGenericTexture GetActiveTexture(int frame)
{
uint val = (uint)group.GetValue(frame);
uint val = (uint)GetValue(frame);
foreach (var bntx in PluginRuntime.bntxContainers)
{
@ -692,7 +684,7 @@ namespace Bfres.Structs
//Loop through sampler list for texture anims
//These store a list of indices (step curve) to grab a texture name list
//Then we'll update the active texture
foreach (Material.Sampler samplerAnim in matAnim.Samplers)
foreach (SamplerKeyGroup samplerAnim in matAnim.Samplers)
{
foreach (MatTexture texture in material.TextureMaps)
{
@ -700,7 +692,7 @@ namespace Bfres.Structs
{
texture.textureState = STGenericMatTexture.TextureState.Animated;
uint index = (uint)samplerAnim.group.GetValue(Frame);
uint index = (uint)samplerAnim.GetValue(Frame);
texture.animatedTexName = Textures[(int)index];
}
}

View File

@ -76,23 +76,16 @@ namespace Bfres.Structs
{
textureIndex = SamplerInfo.SubBindIndex;
var group = new Animation.KeyGroup();
group.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = textureIndex });
group.Constant = true;
sampler.group = group;
sampler.Keys.Add(new Animation.KeyFrame() { Frame = 0, Value = textureIndex });
sampler.Constant = true;
}
if (SamplerInfo.CurveIndex != -1)
{
int index = (int)SamplerInfo.CurveIndex;
Animation.KeyGroup keyGroup = CurveHelper.CreateTrackWiiU(matanim.Curves[index]);
keyGroup.AnimDataOffset = matanim.Curves[index].AnimDataOffset;
sampler.group = new KeyGroup()
{
AnimDataOffset = keyGroup.AnimDataOffset,
Keys = keyGroup.Keys,
};
sampler.AnimDataOffset = matanim.Curves[index].AnimDataOffset;
sampler.Keys = keyGroup.Keys;
foreach (var ind in keyGroup.Keys)
{
@ -140,11 +133,11 @@ namespace Bfres.Structs
}
}
public class BfresSamplerAnim : Material.Sampler
public class BfresSamplerAnim : SamplerKeyGroup
{
FTXP AnimWrapper;
public BfresSamplerAnim(string Name, FTXP ftxp)
public BfresSamplerAnim(string Name, FTXP ftxp) : base(ftxp)
{
Text = Name;
ImageKey = "texture";
@ -155,13 +148,13 @@ namespace Bfres.Structs
public override string GetActiveTextureName(int frame)
{
uint val = (uint)group.GetValue(frame);
uint val = (uint)GetValue(frame);
return AnimWrapper.Textures[(int)val];
}
public override STGenericTexture GetActiveTexture(int frame)
{
uint val = (uint)group.GetValue(frame);
uint val = (uint)GetValue(frame);
foreach (var ftexFolder in PluginRuntime.ftexContainers)
{
@ -211,7 +204,7 @@ namespace Bfres.Structs
//Loop through sampler list for texture anims
//These store a list of indices (step curve) to grab a texture name list
//Then we'll update the active texture
foreach (Material.Sampler samplerAnim in matAnim.Samplers)
foreach (SamplerKeyGroup samplerAnim in matAnim.Samplers)
{
foreach (MatTexture texture in material.TextureMaps)
{
@ -219,7 +212,7 @@ namespace Bfres.Structs
{
texture.textureState = STGenericMatTexture.TextureState.Animated;
uint index = (uint)samplerAnim.group.GetValue(Frame);
uint index = (uint)samplerAnim.GetValue(Frame);
texture.animatedTexName = Textures[(int)index];
}
}

View File

@ -21,11 +21,11 @@ namespace FirstPlugin.Forms
CanResize = false;
}
public MaterialAnimation.Material.Sampler GetSamplerData()
public MaterialAnimation.SamplerKeyGroup GetSamplerData(MaterialAnimation materialAnimation)
{
MaterialAnimation.Material.Sampler sampler = new MaterialAnimation.Material.Sampler();
MaterialAnimation.SamplerKeyGroup sampler = new MaterialAnimation.SamplerKeyGroup(materialAnimation);
sampler.Text = samplerNameTB.Text;
sampler.group.Constant = constantChkBox.Checked;
sampler.Constant = constantChkBox.Checked;
return sampler;
}

View File

@ -178,7 +178,7 @@ namespace FirstPlugin.Forms
public List<int> KeyFrames = new List<int>(); //Used for getting the frame of the list item
public bool IsLoading = false;
private void LoadAniamtion(MaterialAnimation anim, MaterialAnimation.Material.Sampler activeSampler)
private void LoadAniamtion(MaterialAnimation anim, MaterialAnimation.SamplerKeyGroup activeSampler)
{
if (activeSampler == null || IsLoading)
return;
@ -200,12 +200,12 @@ namespace FirstPlugin.Forms
for (int Frame = 0; Frame <= anim.FrameCount; Frame++)
{
//Constants always show so break after first frame
if (activeSampler.group.Constant && Frame != 0)
if (activeSampler.Constant && Frame != 0)
break;
var keyFrame = activeSampler.group.GetKeyFrame(Frame);
var keyFrame = activeSampler.GetKeyFrame(Frame);
if (keyFrame.IsKeyed || activeSampler.group.Constant)
if (keyFrame.IsKeyed || activeSampler.Constant)
{
var tex = activeSampler.GetActiveTexture(Frame);
@ -500,9 +500,9 @@ namespace FirstPlugin.Forms
int index = ActiveMaterialAnim.Textures.IndexOf(NewTex);
if (activeSampleU != null)
activeSampleU.group.SetValue(SelectedFrame, index);
activeSampleU.SetValue(SelectedFrame, index);
else
activeSampler.group.SetValue(SelectedFrame, index);
activeSampler.SetValue(SelectedFrame, index);
ActiveMaterialAnim.UpdateAnimationData();
}
@ -515,7 +515,7 @@ namespace FirstPlugin.Forms
return;
TexPatternInfoEditor editor = new TexPatternInfoEditor();
editor.LoadAnim(ActiveMaterialAnim.Materials[materialCB.SelectedIndex]);
editor.LoadAnim(ActiveMaterialAnim, ActiveMaterialAnim.Materials[materialCB.SelectedIndex]);
if (editor.ShowDialog() == DialogResult.OK)
{

View File

@ -24,10 +24,12 @@ namespace FirstPlugin.Forms
}
MaterialAnimation.Material activeMat;
MaterialAnimation ActiveMaterialAnim;
public void LoadAnim(MaterialAnimation.Material mat)
public void LoadAnim(MaterialAnimation materialAnimation, MaterialAnimation.Material mat)
{
activeMat = mat;
ActiveMaterialAnim = materialAnimation;
foreach (var sampler in mat.Samplers)
{
@ -72,7 +74,7 @@ namespace FirstPlugin.Forms
private void btnAdd_Click(object sender, EventArgs e)
{
activeMat.Samplers.Add(new MaterialAnimation.Material.Sampler());
activeMat.Samplers.Add(new MaterialAnimation.SamplerKeyGroup(ActiveMaterialAnim));
listViewCustom1.Items.Add("");
}
@ -92,7 +94,7 @@ namespace FirstPlugin.Forms
{
int index = listViewCustom1.SelectedIndices[0];
activeMat.Samplers[index].group.Constant = stCheckBox1.Checked;
activeMat.Samplers[index].Constant = stCheckBox1.Checked;
}
}
}

View File

@ -92,7 +92,7 @@ namespace FirstPlugin.Forms
int index = listViewCustom1.SelectedIndices[0];
TexPatternInfoEditor editor = new TexPatternInfoEditor();
editor.LoadAnim(activeAnim.Materials[index]);
editor.LoadAnim(activeAnim, activeAnim.Materials[index]);
if (editor.ShowDialog() == DialogResult.OK)
{

View File

@ -62,7 +62,7 @@ namespace FirstPlugin.Forms
int KeyPosY = KeyHeight;
foreach (FMAA.BfresSamplerAnim sampler in material.Nodes)
{
var keyFrame = sampler.group.GetKeyFrame(Frame);
var keyFrame = sampler.GetKeyFrame(Frame);
if (keyFrame.IsKeyed)
{

View File

@ -21,9 +21,24 @@ namespace FirstPlugin.NodeWrappers
public bool IsWiiU { get; set; }
public bool SettingRemoveUnusedTextures
{
get
{
return ((ToolStripMenuItem)SettingsToolStrip.DropDownItems[0]).Checked;
}
}
private ToolStripMenuItem SettingsToolStrip;
public void LoadMenus(bool isWiiUBfres) {
IsWiiU = isWiiUBfres;
LoadFileMenus(true);
SettingsToolStrip = new ToolStripMenuItem("Settings", null);
SettingsToolStrip.DropDownItems.Add(new ToolStripMenuItem("Remove Unused Textures on Save", null, SettingBooleanAction));
ContextMenuStrip.Items.Add(SettingsToolStrip);
}
public override void Delete()
@ -36,54 +51,16 @@ namespace FirstPlugin.NodeWrappers
}
}
protected void ImportModelAction(object sender, EventArgs e) { ImportModel(); }
protected void ImportEmbeddedFileAction(object sender, EventArgs e) { ImportEmbeddedFile(); }
public void ImportModel()
protected void SettingBooleanAction(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() != DialogResult.OK)
return;
BFRESGroupNode group = new BFRESGroupNode(IsWiiU);
group.Import(ofd.FileNames);
}
public void ImportEmbeddedFile()
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() != DialogResult.OK)
return;
BFRESGroupNode group = new BFRESGroupNode(IsWiiU);
group.Import(ofd.FileNames);
}
public void NewModel()
{
BFRESGroupNode group = new BFRESGroupNode(IsWiiU);
FMDL anim = new FMDL();
if (IsWiiU)
BfresWiiU.ReadModel(anim, new ResU.Model());
else
BfresSwitch.ReadModel(anim, new ResNX.Model());
group.AddNode(anim, "NewModel");
}
private void SetupAddedNode(BFRESGroupNode group, STGenericWrapper node)
{
Nodes.Add(group);
TreeView.SelectedNode = node;
}
public void NewEmbeddedFile()
{
BFRESGroupNode group = new BFRESGroupNode(IsWiiU);
ExternalFileData fshu = new ExternalFileData("NewFile", new byte[0]);
group.AddNode(fshu, "NewFile");
SetupAddedNode(group, fshu);
if (sender is ToolStripMenuItem)
{
if (((ToolStripMenuItem)sender).Checked)
((ToolStripMenuItem)sender).Checked = false;
else
((ToolStripMenuItem)sender).Checked = true;
}
}
}
}

View File

@ -31,7 +31,7 @@ namespace Switch_Toolbox.Library.Animations
public class Material : STGenericWrapper
{
public List<ParamKeyGroup> Params = new List<ParamKeyGroup>();
public List<Sampler> Samplers = new List<Sampler>();
public List<SamplerKeyGroup> Samplers = new List<SamplerKeyGroup>();
public Material()
{
@ -44,23 +44,8 @@ namespace Switch_Toolbox.Library.Animations
ImageKey = "material";
SelectedImageKey = "material";
}
public class Sampler : TreeNodeCustom
{
public Sampler()
{
ImageKey = "sampler";
SelectedImageKey = "sampler";
}
public virtual string GetActiveTextureName(int frame) { return ""; }
public virtual STGenericTexture GetActiveTexture(int Frame) { return null; }
//Stores texture indices
public KeyGroup group = new KeyGroup();
}
}
public class ParamKeyGroup : TreeNodeCustom
{
public AnimationType Type;
@ -68,7 +53,40 @@ namespace Switch_Toolbox.Library.Animations
public string UniformName;
//Params will have multiple curves for values
public List<Animation.KeyGroup> Values = new List<Animation.KeyGroup>();
public List<KeyGroup> Values = new List<KeyGroup>();
}
public class SamplerKeyGroup : KeyGroup
{
MaterialAnimation MaterialAnimation;
public SamplerKeyGroup(MaterialAnimation materialAnimation)
{
ImageKey = "sampler";
SelectedImageKey = "sampler";
MaterialAnimation = materialAnimation;
}
public virtual string GetActiveTextureName(int frame)
{
float index = GetValue(frame);
return MaterialAnimation.Textures[(int)index];
}
public virtual void SetActiveTextureName(int Frame, string TextureName)
{
if (!MaterialAnimation.Textures.Contains(TextureName))
MaterialAnimation.Textures.Add(TextureName);
int index = MaterialAnimation.Textures.IndexOf(TextureName);
SetValue(index, Frame);
}
public virtual STGenericTexture GetActiveTexture(int Frame) { return null; }
}
}
}