1
0
mirror of synced 2025-02-25 22:38:07 +01:00

Some fixes.

Check for all meshes to apply default bfres settings.
Expand/collapse only if tree nodes have children.
This commit is contained in:
KillzXGaming 2019-11-18 19:01:40 -05:00
parent 1f37e182b5
commit 2a62ad98ab
6 changed files with 155 additions and 48 deletions

View File

@ -211,7 +211,7 @@ namespace Bfres.Structs
{
foreach (var shape in shapes)
{
if (!shape.HasUV0())
if (!shape.HasAttributeUV0())
{
MessageBox.Show($"Error! {Text} does not have UVs!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
@ -227,7 +227,7 @@ namespace Bfres.Structs
{
foreach (var shape in shapes)
{
if (!shape.HasUV0())
if (!shape.HasAttributeUV0())
{
MessageBox.Show($"Error! {Text} does not have UVs!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
@ -344,7 +344,7 @@ namespace Bfres.Structs
bool HasTans = shp.vertexAttributes.Any(x => x.Name == "_t0");
bool HasBiTans = shp.vertexAttributes.Any(x => x.Name == "_b0");
if (!shp.HasUV0())
if (!shp.HasAttributeUV0())
{
MessageBox.Show($"Error! {Text} does not have UVs!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
@ -683,7 +683,7 @@ namespace Bfres.Structs
}
BfresModelImportSettings csvsettings = new BfresModelImportSettings();
csvsettings.DisableMaterialEdits();
csvsettings.SetModelAttributes(csvModel.objects[0]);
csvsettings.SetModelAttributes(csvModel.objects);
if (csvsettings.ShowDialog() == DialogResult.OK)
{
if (csvsettings.LimitSkinCount ||
@ -861,7 +861,7 @@ namespace Bfres.Structs
settings.UpdateTexturePlaceholderSetting(HasTextures);
}
settings.SetModelAttributes(ImportedObjects[0]);
settings.SetModelAttributes(ImportedObjects);
if (settings.ShowDialog() == DialogResult.OK)
{
STProgressBar progressBar = new STProgressBar();

View File

@ -685,7 +685,7 @@ namespace Bfres.Structs
bool HasTans = vertexAttributes.Any(x => x.Name == "_t0");
bool HasBiTans = vertexAttributes.Any(x => x.Name == "_b0");
if (!HasUV0())
if (!HasAttributeUV0())
{
MessageBox.Show($"Error! {Text} does not have UVs!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
@ -738,21 +738,21 @@ namespace Bfres.Structs
UpdateVertexData();
Cursor.Current = Cursors.Default;
}
public bool HasUV0()
public bool HasAttributeUV0()
{
return vertexAttributes.Any(x => x.Name == "_u0");
}
public bool HasUV1()
public bool HasAttributeUV1()
{
return vertexAttributes.Any(x => x.Name == "_u1");
}
public bool HasUV2()
public bool HasAttributeUV2()
{
return vertexAttributes.Any(x => x.Name == "_u2");
}
public void FlipUvsVertical(object sender, EventArgs args)
{
if (!HasUV0())
if (!HasAttributeUV0())
{
MessageBox.Show($"Error! {Text} does not have UVs!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
@ -764,7 +764,7 @@ namespace Bfres.Structs
}
public void FlipUvsHorizontal(object sender, EventArgs args)
{
if (!HasUV0())
if (!HasAttributeUV0())
{
MessageBox.Show($"Error! {Text} does not have UVs!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
@ -888,7 +888,7 @@ namespace Bfres.Structs
var originalAttributes = vertexAttributes;
BfresModelImportSettings settings = new BfresModelImportSettings();
settings.SetModelAttributes(assimp.objects[0]);
settings.SetModelAttributes(assimp.objects);
if (settings.ShowDialog() == DialogResult.OK)
{
STGenericObject obj = selector.GetSelectedMesh();

View File

@ -2254,15 +2254,15 @@ namespace Bfres.Structs
BFRESRender.UpdateVertexData();
Cursor.Current = Cursors.Default;
}
public bool HasUV0()
public bool HasAttributeUV0()
{
return vertexAttributes.Any(x => x.Name == "_u0");
}
public bool HasUV1()
public bool HasAttributeUV1()
{
return vertexAttributes.Any(x => x.Name == "_u1");
}
public bool HasUV2()
public bool HasAttributeUV2()
{
return vertexAttributes.Any(x => x.Name == "_u2");
}

View File

@ -8,6 +8,7 @@ using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using OpenTK;
using System.Reflection;
namespace FirstPlugin
{
@ -16,8 +17,8 @@ namespace FirstPlugin
public FileType FileType { get; set; } = FileType.Model;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "MDL" };
public string[] Extension { get; set; } = new string[] { "*.mdl" };
public string[] Description { get; set; } = new string[] { "GFBANM" };
public string[] Extension { get; set; } = new string[] { "*.gfbanm" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
@ -36,11 +37,12 @@ namespace FirstPlugin
}
}
Header header;
public void Load(System.IO.Stream stream)
{
using (var reader = new FileReader(stream))
{
header = new Header(reader);
}
}
@ -56,30 +58,46 @@ namespace FirstPlugin
public class Header
{
public Config config;
public BoneList boneList;
public void Read(FileReader reader)
public Header(FileReader reader)
{
reader.ReadUInt32();
config = ParseSection<Config>(reader, this);
boneList = ParseSection<BoneList>(reader, this);
Console.WriteLine($"config NumKeyFrames {config.NumKeyFrames}");
Console.WriteLine($"config FramesPerSecond {config.FramesPerSecond}");
}
}
private static T ParseSection<T>(FileReader reader, Header header)
where T : GFSection, new()
{
var layoutOffset = reader.ReadOffset(true, typeof(uint));
var offset = reader.ReadOffset(true, typeof(uint));
reader.SeekBegin(offset);
long origin = reader.Position;
int layoutOffset = reader.ReadInt32();
var dataOffset = reader.ReadOffset(true, typeof(uint));
T section = new T();
using (reader.TemporarySeek(layoutOffset, System.IO.SeekOrigin.Begin))
using (reader.TemporarySeek(origin - layoutOffset, System.IO.SeekOrigin.Begin))
{
ushort layoutSize = reader.ReadUInt16();
ushort layoutStride = reader.ReadUInt16();
section.LayoutPointers = reader.ReadUInt16s((int)(layoutSize / 2));
List<ushort> pointers = new List<ushort>();
uint looper = 4;
while (looper < layoutSize) {
pointers.Add(reader.ReadUInt16());
looper += 2;
}
section.LayoutPointers = reader.ReadUInt16s((int)(layoutSize / 4));
}
using (reader.TemporarySeek(dataOffset, System.IO.SeekOrigin.Begin))
{
using (reader.TemporarySeek(dataOffset, System.IO.SeekOrigin.Begin)) {
section.Read(reader, header);
}
@ -88,30 +106,117 @@ namespace FirstPlugin
public class GFSection
{
public ushort LayoutSize { get; set; }
public ushort LayoutStride { get; set; }
public ushort[] LayoutPointers { get; set; }
public virtual void Read(FileReader reader, Header header)
public void Read(FileReader reader, Header header)
{
long origin = reader.Position;
PropertyInfo[] types = new PropertyInfo[(int)LayoutPointers?.Length];
var sectionType = this.GetType();
int index = 0;
foreach (var prop in sectionType.GetProperties()) {
if (!Attribute.IsDefined(prop, typeof(FlatTableParse)))
continue;
types[index++] = prop;
}
for (int i = 0; i < LayoutPointers?.Length; i++)
{
reader.SeekBegin(origin + LayoutPointers[i]);
if (types[i] != null)
{
var prop = types[i];
var propertyType = prop.PropertyType;
if (propertyType == typeof(uint))
prop.SetValue(this, reader.ReadUInt32());
else if (propertyType == typeof(int))
prop.SetValue(this, reader.ReadInt32());
else if(propertyType == typeof(byte))
prop.SetValue(this, reader.ReadByte());
else if(propertyType == typeof(sbyte))
prop.SetValue(this, reader.ReadSByte());
else if (propertyType == typeof(ushort))
prop.SetValue(this, reader.ReadUInt16());
else if (propertyType == typeof(short))
prop.SetValue(this, reader.ReadInt16());
else if (propertyType == typeof(Vector2))
prop.SetValue(this, new Vector2(
reader.ReadSingle(),
reader.ReadSingle())
);
else if (propertyType == typeof(Vector3))
prop.SetValue(this, new Vector3(
reader.ReadSingle(),
reader.ReadSingle(),
reader.ReadSingle())
);
else if (propertyType == typeof(Vector4))
prop.SetValue(this, new Vector4(
reader.ReadSingle(),
reader.ReadSingle(),
reader.ReadSingle(),
reader.ReadSingle())
);
else if (propertyType == typeof(GFSection))
{
var offset = reader.ReadOffset(true, typeof(uint));
reader.SeekBegin(offset);
}
else if (propertyType is IEnumerable<GFSection>) {
}
}
}
}
}
public class FlatTableParse : Attribute { }
public class OffsetProperty : Attribute { }
[OffsetProperty]
public class Config : GFSection
{
[FlatTableParse]
public int Unknown { get; set; }
[FlatTableParse]
public uint NumKeyFrames { get; set; }
[FlatTableParse]
public uint FramesPerSecond { get; set; }
}
[OffsetProperty]
public class BoneList : GFSection
{
[FlatTableParse]
public List<Bone> Bones = new List<Bone>();
[FlatTableParse]
public List<BoneDefaults> BoneDefaults = new List<BoneDefaults>();
}
public class Bone
{
[FlatTableParse, OffsetProperty]
public string Name { get; set; }
[FlatTableParse]
public byte ScaleType { get; set; }
}
public class NammeOffset
{
[FlatTableParse, OffsetProperty]
public string Name { get; set; }
[FlatTableParse]
public byte ScaleType { get; set; }
}

View File

@ -6,6 +6,7 @@ using Toolbox.Library;
using Toolbox.Library.Forms;
using Toolbox.Library.Rendering;
using Bfres.Structs;
using System.Linq;
namespace FirstPlugin
{
@ -98,40 +99,40 @@ namespace FirstPlugin
originalMeshListView.EndUpdate();
}
public void SetModelAttributes(STGenericObject obj)
public void SetModelAttributes(List<STGenericObject> objects)
{
chkBoxEnablePositions.Enabled = true;
chkBoxEnablePositions.Checked = obj.HasPos;
chkBoxEnableNormals.Checked = obj.HasNrm;
chkBoxEnableUVs.Checked = obj.HasUv0;
chkBoxEnableTans.Checked = obj.HasUv0;
chkBoxEnableBitans.Checked = obj.HasUv0;
chkBoxEnableWeightIndices.Checked = obj.HasWeights;
chkBoxEnableVertColors.Checked = obj.HasVertColors;
chkBoxEnablePositions.Checked = objects.Any(o => o.HasPos);
chkBoxEnableNormals.Checked = objects.Any(o => o.HasNrm);
chkBoxEnableUVs.Checked = objects.Any(o => o.HasUv0);
chkBoxEnableTans.Checked = objects.Any(o => o.HasUv0);
chkBoxEnableBitans.Checked = objects.Any(o => o.HasUv0);
chkBoxEnableWeightIndices.Checked = objects.Any(o => o.HasWeights);
chkBoxEnableVertColors.Checked = objects.Any(o => o.HasVertColors);
chkResetUVParams.Checked = true;
chkBoxTransformMatrix.Checked = true;
if (!obj.HasPos)
if (!objects.Any(o => o.HasPos))
DisableAttribute(chkBoxEnablePositions, comboBoxFormatPositions);
if (!obj.HasNrm)
if (!objects.Any(o => o.HasNrm))
DisableAttribute(chkBoxEnableNormals, comboBoxFormatPositions);
if (!obj.HasUv0)
if (!objects.Any(o => o.HasUv0))
DisableAttribute(chkBoxEnableUVs, comboBoxFormatUvs);
//Note. Bitans/tans uses uvs to generate
if (!obj.HasUv0)
if (!objects.Any(o => o.HasUv0))
DisableAttribute(chkBoxEnableTans, comboBoxFormatTangents);
if (!obj.HasUv0)
if (!objects.Any(o => o.HasUv0))
DisableAttribute(chkBoxEnableBitans, comboBoxFormatBitans);
if (!obj.HasWeights && !obj.HasIndices)
if (!objects.Any(o => o.HasWeights) && !objects.Any(o => o.HasIndices))
{
DisableAttribute(chkBoxEnableWeightIndices, comboBoxFormatWeights);
DisableAttribute(chkBoxEnableWeightIndices, comboBoxFormatIndices);
}
if (!obj.HasVertColors)
if (!objects.Any(o => o.HasVertColors))
DisableAttribute(chkBoxEnableVertColors, comboBoxFormatVertexColors);
EnableUV1 = obj.HasUv1;
EnableUV2 = obj.HasUv2;
EnableUV1 = objects.Any(o => o.HasUv1);
EnableUV2 = objects.Any(o => o.HasUv2);
}
public List<FSHP.VertexAttribute> CreateNewAttributes(List<FSHP.VertexAttribute> Attributes)

View File

@ -320,6 +320,7 @@ namespace Toolbox.Library.Forms
if (e.Node is IContextMenuNode)
{
bool IsRoot = e.Node.Parent == null;
bool HasChildren = e.Node.Nodes.Count > 0;
treeNodeContextMenu.Items.Clear();
if (e.Node.Tag != null && e.Node.Tag is ArchiveFileInfo)
@ -354,10 +355,10 @@ namespace Toolbox.Library.Forms
HasExpand = true;
}
if (!HasCollpase)
if (!HasCollpase && HasChildren)
treeNodeContextMenu.Items.Add(new ToolStripMenuItem("Collapse All", null, CollapseAllAction, Keys.Control | Keys.Q));
if (!HasExpand)
if (!HasExpand && HasChildren)
treeNodeContextMenu.Items.Add(new ToolStripMenuItem("Expand All", null, ExpandAllAction, Keys.Control | Keys.P));
treeNodeContextMenu.Show(Cursor.Position);
@ -405,7 +406,9 @@ namespace Toolbox.Library.Forms
}
treeViewCustom1.Nodes.Remove(node);
ResetEditor();
if (treeViewCustom1.Nodes.Count == 0)
ResetEditor();
//Force garbage collection.
GC.Collect();
@ -424,8 +427,6 @@ namespace Toolbox.Library.Forms
{
if (control is STUserControl)
((STUserControl)control).OnControlClosing();
control.Dispose();
}
stPanel2.Controls.Clear();