Some fixes.
Check for all meshes to apply default bfres settings. Expand/collapse only if tree nodes have children.
This commit is contained in:
parent
1f37e182b5
commit
2a62ad98ab
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user