Alot of Pokemon additions.

Redid gfmdl parser completely. This allows the file to be rebuilt for custom models which will be coming soon.
Textures now load in the gfmdl section to easily edit without touching bntx.
Added a basic material editor (more like a viewer atm) for gfbmdl.
Added a Pokemon viewer (requires game path to be set). This shows icons of all the pokemon and opens the archive they are located in.
Start to parse GFBANIM. Not previewable yet because of rotations breaking. If anyone wants to help though be my guest :)
Basic GFBANIMCFG support. It can be used to view animation file names.
This commit is contained in:
KillzXGaming 2019-11-26 19:54:59 -05:00
parent b9d5eb03da
commit 61550ac786
35 changed files with 5986 additions and 1499 deletions

File diff suppressed because it is too large Load diff

View file

@ -9,11 +9,16 @@ using Toolbox.Library;
using Toolbox.Library.IO;
using OpenTK;
using System.Reflection;
using Toolbox.Library.IO.FlatBuffer;
using Toolbox.Library.Animations;
using FirstPlugin.Forms;
namespace FirstPlugin
{
public class GFBANM : IFileFormat
public class GFBANM : TreeNodeFile, IFileFormat, IAnimationContainer
{
public STAnimation AnimationController => AnimationData;
public FileType FileType { get; set; } = FileType.Model;
public bool CanSave { get; set; }
@ -28,6 +33,17 @@ namespace FirstPlugin
return Utils.GetExtension(FileName) == ".gfbanm";
}
public override void OnClick(TreeView treeView)
{
ViewportEditor editor = (ViewportEditor)LibraryGUI.GetActiveContent(typeof(ViewportEditor));
if (editor == null)
{
editor = new ViewportEditor(true);
editor.Dock = DockStyle.Fill;
LibraryGUI.LoadEditor(editor);
}
}
public Type[] Types
{
get
@ -37,12 +53,31 @@ namespace FirstPlugin
}
}
Header header;
Animation AnimationData;
public void Load(System.IO.Stream stream)
{
using (var reader = new FileReader(stream))
{
header = new Header(reader);
Text = FileName;
Gfbanim.Animation anim = Gfbanim.Animation.GetRootAsAnimation(
new FlatBuffers.ByteBuffer(stream.ToBytes()));
AnimationData = new Animation();
AnimationData.FrameCount = anim.AnimConfig.Value.KeyFrames;
if (anim.Bones.HasValue) {
for (int i = 0; i < anim.Bones.Value.BonesLength; i++)
AnimationData.LoadBoneGroup(anim.Bones.Value.Bones(i).Value);
}
if (anim.Materials.HasValue) {
for (int i = 0; i < anim.Materials.Value.MaterialsLength; i++)
AnimationData.LoadMaterialGroup(anim.Materials.Value.Materials(i).Value);
}
if (anim.Groups.HasValue) {
for (int i = 0; i < anim.Groups.Value.GroupsLength; i++)
AnimationData.LoadVisibilyGroup(anim.Groups.Value.Groups(i).Value);
}
if (anim.Triggers.HasValue) {
for (int i = 0; i < anim.Triggers.Value.TriggersLength; i++)
AnimationData.LoadTriggerGroup(anim.Triggers.Value.Triggers(i).Value);
}
}
@ -55,199 +90,426 @@ namespace FirstPlugin
{
}
public class Header
public class Animation : STSkeletonAnimation
{
public Config config;
public BoneList boneList;
public Header(FileReader reader)
public override void NextFrame()
{
config = ParseSection<Config>(reader, this);
boneList = ParseSection<BoneList>(reader, this);
if (Frame > FrameCount) return;
Console.WriteLine($"config NumKeyFrames {config.NumKeyFrames}");
Console.WriteLine($"config FramesPerSecond {config.FramesPerSecond}");
}
}
var skeleton = GetActiveSkeleton();
if (skeleton == null) return;
private static T ParseSection<T>(FileReader reader, Header header)
where T : GFSection, new()
if (Frame == 0)
skeleton.reset();
bool Updated = false; // no need to update skeleton of animations that didn't change
foreach (var animGroup in AnimGroups)
{
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(origin - layoutOffset, System.IO.SeekOrigin.Begin))
if (animGroup is BoneGroup)
{
ushort layoutSize = reader.ReadUInt16();
ushort layoutStride = reader.ReadUInt16();
var node = animGroup as BoneGroup;
List<ushort> pointers = new List<ushort>();
uint looper = 4;
while (looper < layoutSize) {
pointers.Add(reader.ReadUInt16());
looper += 2;
}
STBone b = null;
b = skeleton.GetBone(node.Name);
if (b == null) continue;
section.LayoutPointers = reader.ReadUInt16s((int)(layoutSize / 4));
}
Updated = true;
using (reader.TemporarySeek(dataOffset, System.IO.SeekOrigin.Begin)) {
section.Read(reader, header);
}
if (node.TranslateX.HasKeys)
b.pos.X = node.TranslateX.GetFrameValue(Frame);
if (node.TranslateY.HasKeys)
b.pos.Y = node.TranslateY.GetFrameValue(Frame);
if (node.TranslateZ.HasKeys)
b.pos.Z = node.TranslateZ.GetFrameValue(Frame);
return section;
}
if (node.ScaleX.HasKeys)
b.sca.X = node.ScaleX.GetFrameValue(Frame);
else b.sca.X = 1;
if (node.ScaleY.HasKeys)
b.sca.Y = node.ScaleY.GetFrameValue(Frame);
else b.sca.Y = 1;
if (node.ScaleZ.HasKeys)
b.sca.Z = node.ScaleZ.GetFrameValue(Frame);
else b.sca.Z = 1;
public class GFSection
if (node.RotationX.HasKeys || node.RotationY.HasKeys || node.RotationZ.HasKeys)
{
public ushort LayoutSize { get; set; }
public ushort LayoutStride { get; set; }
float x = node.RotationX.HasKeys ? node.RotationX.GetFrameValue(Frame) : b.rotation[0];
float y = node.RotationY.HasKeys ? node.RotationY.GetFrameValue(Frame) : b.rotation[1];
float z = node.RotationZ.HasKeys ? node.RotationZ.GetFrameValue(Frame) : b.rotation[2];
public ushort[] LayoutPointers { get; set; }
var Rotation = new Vector3(x / 0xffff, y/ 0xffff, z / 0xffff).Normalized();
b.rot = EulerToQuat(Rotation.Z, Rotation.Y, Rotation.X);
public void Read(FileReader reader, Header header)
// b.rot = EulerToQuat(Rotation.Z, Rotation.Y, Rotation.X);
float Angle = Rotation.Length;
Console.WriteLine($"{node.Name} Angle {Angle}");
// b.rot = Angle > 0
// ? Quaternion.FromAxisAngle(Vector3.Normalize(Rotation), Angle)
// : Quaternion.Identity;
}
else
{
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;
b.rot = EulerToQuat(b.rotation[2], b.rotation[1], b.rotation[0]);
}
}
}
for (int i = 0; i < LayoutPointers?.Length; i++)
if (Updated)
{
reader.SeekBegin(origin + LayoutPointers[i]);
if (types[i] != null)
skeleton.update();
}
}
public static Quaternion EulerToQuat(float z, float y, float x)
{
var prop = types[i];
var propertyType = prop.PropertyType;
Quaternion xRotation = Quaternion.FromAxisAngle(Vector3.UnitX, x);
Quaternion yRotation = Quaternion.FromAxisAngle(Vector3.UnitY, y);
Quaternion zRotation = Quaternion.FromAxisAngle(Vector3.UnitZ, z);
return (zRotation * yRotation * xRotation);
}
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))
public void LoadBoneGroup(Gfbanim.Bone boneAnim)
{
var offset = reader.ReadOffset(true, typeof(uint));
reader.SeekBegin(offset);
}
else if (propertyType is IEnumerable<GFSection>) {
BoneGroup groupAnim = new BoneGroup();
groupAnim.Name = boneAnim.Name;
AnimGroups.Add(groupAnim);
}
}
}
}
}
//Tracks use 3 types
// Fixed/constant
// Dynamic (baked and multiple keys, no frames)
// Framed (multiple keys and frames)
public class FlatTableParse : Attribute { }
public class OffsetProperty : Attribute { }
List<float> Frames = new List<float>();
[OffsetProperty]
public class Config : GFSection
Console.WriteLine($"BoneGroup {groupAnim.Name }");
switch (boneAnim.RotateType)
{
[FlatTableParse]
public int Unknown { get; set; }
[FlatTableParse]
public uint NumKeyFrames { get; set; }
[FlatTableParse]
public uint FramesPerSecond { get; set; }
}
[OffsetProperty]
public class BoneList : GFSection
case Gfbanim.QuatTrack.DynamicQuatTrack:
{
[FlatTableParse]
public List<Bone> Bones = new List<Bone>();
[FlatTableParse]
public List<BoneDefaults> BoneDefaults = new List<BoneDefaults>();
}
public class Bone
var rotate = boneAnim.Rotate<Gfbanim.DynamicQuatTrack>();
if (rotate.HasValue)
{
[FlatTableParse, OffsetProperty]
public string Name { get; set; }
[FlatTableParse]
public byte ScaleType { get; set; }
var values = LoadRotationTrack(rotate.Value);
groupAnim.RotationX = values[0];
groupAnim.RotationY = values[1];
groupAnim.RotationZ = values[2];
}
public class NammeOffset
}
break;
case Gfbanim.QuatTrack.FixedQuatTrack:
{
[FlatTableParse, OffsetProperty]
public string Name { get; set; }
[FlatTableParse]
public byte ScaleType { get; set; }
}
public class BoneDefaults
var rotate = boneAnim.Rotate<Gfbanim.FixedQuatTrack>();
if (rotate.HasValue)
{
public int Unknown { get; set; }
public Vector3 Scale { get; set; }
public Vector4 Rotation { get; set; }
public Vector3 Translation { get; set; }
var vec = rotate.Value.Value.Value;
groupAnim.RotationX.KeyFrames.Add(new STKeyFrame(0, ConvertRotation(vec.X)));
groupAnim.RotationY.KeyFrames.Add(new STKeyFrame(0, ConvertRotation(vec.Y)));
groupAnim.RotationZ.KeyFrames.Add(new STKeyFrame(0, ConvertRotation(vec.Z)));
}
public class TriggerList
}
break;
case Gfbanim.QuatTrack.FramedQuatTrack:
{
public List<Trigger> Triggers = new List<Trigger>();
}
public class Trigger
var rotate = boneAnim.Rotate<Gfbanim.FramedQuatTrack>();
if (rotate.HasValue)
{
public string Name { get; set; }
public int StartFrame { get; set; }
public int EndFrame { get; set; }
var values = LoadRotationTrack(rotate.Value);
groupAnim.RotationX = values[0];
groupAnim.RotationY = values[1];
groupAnim.RotationZ = values[2];
}
public class TriggerParameter
}
break;
}
switch (boneAnim.ScaleType)
{
case Gfbanim.VectorTrack.FixedVectorTrack:
{
var scale = boneAnim.Scale<Gfbanim.FixedVectorTrack>();
if (scale.HasValue)
{
var vec = scale.Value.Value.Value;
groupAnim.ScaleX.KeyFrames.Add(new STKeyFrame(0, vec.X));
groupAnim.ScaleY.KeyFrames.Add(new STKeyFrame(0, vec.Y));
groupAnim.ScaleZ.KeyFrames.Add(new STKeyFrame(0, vec.Z));
}
}
break;
}
switch (boneAnim.ScaleType)
{
case Gfbanim.VectorTrack.DynamicVectorTrack:
{
var scale = boneAnim.Scale<Gfbanim.DynamicVectorTrack>();
if (scale.HasValue)
{
var values = LoadVectorTrack(scale.Value);
groupAnim.ScaleX = values[0];
groupAnim.ScaleY = values[1];
groupAnim.ScaleZ = values[2];
}
}
break;
case Gfbanim.VectorTrack.FramedVectorTrack:
{
var scale = boneAnim.Scale<Gfbanim.FramedVectorTrack>();
if (scale.HasValue)
{
var values = LoadVectorTrack(scale.Value);
groupAnim.ScaleX = values[0];
groupAnim.ScaleY = values[1];
groupAnim.ScaleZ = values[2];
}
}
break;
case Gfbanim.VectorTrack.FixedVectorTrack:
{
var scale = boneAnim.Scale<Gfbanim.FixedVectorTrack>();
if (scale.HasValue)
{
var vec = scale.Value.Value.Value;
groupAnim.ScaleX.KeyFrames.Add(new STKeyFrame(0, vec.X));
groupAnim.ScaleY.KeyFrames.Add(new STKeyFrame(0, vec.Y));
groupAnim.ScaleZ.KeyFrames.Add(new STKeyFrame(0, vec.Z));
}
}
break;
}
switch (boneAnim.TranslateType)
{
case Gfbanim.VectorTrack.DynamicVectorTrack:
{
var trans = boneAnim.Translate<Gfbanim.DynamicVectorTrack>();
if (trans.HasValue)
{
var values = LoadVectorTrack(trans.Value);
groupAnim.TranslateX = values[0];
groupAnim.TranslateY = values[1];
groupAnim.TranslateZ = values[2];
}
}
break;
case Gfbanim.VectorTrack.FramedVectorTrack:
{
var trans = boneAnim.Translate<Gfbanim.FramedVectorTrack>();
if (trans.HasValue)
{
var values = LoadVectorTrack(trans.Value);
groupAnim.TranslateX = values[0];
groupAnim.TranslateY = values[1];
groupAnim.TranslateZ = values[2];
}
}
break;
case Gfbanim.VectorTrack.FixedVectorTrack:
{
var trans = boneAnim.Translate<Gfbanim.FixedVectorTrack>();
if (trans.HasValue)
{
var vec = trans.Value.Value.Value;
groupAnim.TranslateX.KeyFrames.Add(new STKeyFrame(0, vec.X));
groupAnim.TranslateY.KeyFrames.Add(new STKeyFrame(0, vec.Y));
groupAnim.TranslateZ.KeyFrames.Add(new STKeyFrame(0, vec.Z));
}
}
break;
}
}
public float ConvertRotation(ushort val)
{
return val;
}
public STAnimationTrack[] LoadRotationTrack(Gfbanim.DynamicQuatTrack dynamicTrack)
{
STAnimationTrack[] tracks = new STAnimationTrack[3];
tracks[0] = new STAnimationTrack(STInterpoaltionType.Linear);
tracks[1] = new STAnimationTrack(STInterpoaltionType.Linear);
tracks[2] = new STAnimationTrack(STInterpoaltionType.Linear);
for (int i = 0; i < dynamicTrack.ValuesLength; i++)
{
var quat = dynamicTrack.Values(i).Value;
tracks[0].KeyFrames.Add(new STKeyFrame(i, ConvertRotation(quat.X)));
tracks[1].KeyFrames.Add(new STKeyFrame(i, ConvertRotation(quat.Y)));
tracks[2].KeyFrames.Add(new STKeyFrame(i, ConvertRotation(quat.Z)));
Console.WriteLine($"{i} { ConvertRotation(quat.X)} { ConvertRotation(quat.Y)} {ConvertRotation(quat.Z)}");
}
return tracks;
}
public STAnimationTrack[] LoadVectorTrack(Gfbanim.DynamicVectorTrack dynamicTrack)
{
STAnimationTrack[] tracks = new STAnimationTrack[3];
tracks[0] = new STAnimationTrack(STInterpoaltionType.Linear);
tracks[1] = new STAnimationTrack(STInterpoaltionType.Linear);
tracks[2] = new STAnimationTrack(STInterpoaltionType.Linear);
for (int i = 0; i < dynamicTrack.ValuesLength; i++)
{
var vec = dynamicTrack.Values(i).Value;
tracks[0].KeyFrames.Add(new STKeyFrame(i, vec.X));
tracks[1].KeyFrames.Add(new STKeyFrame(i, vec.Y));
tracks[2].KeyFrames.Add(new STKeyFrame(i, vec.Z));
}
return tracks;
}
public STAnimationTrack[] LoadVectorTrack(Gfbanim.FramedVectorTrack framedTrack)
{
ushort[] frames = framedTrack.GetFramesArray();
STAnimationTrack[] tracks = new STAnimationTrack[3];
tracks[0] = new STAnimationTrack(STInterpoaltionType.Linear);
tracks[1] = new STAnimationTrack(STInterpoaltionType.Linear);
tracks[2] = new STAnimationTrack(STInterpoaltionType.Linear);
for (int i = 0; i < framedTrack.ValuesLength; i++)
{
var vec = framedTrack.Values(i).Value;
int frame = i;
if (i < frames?.Length) frame = frames[i];
tracks[0].KeyFrames.Add(new STKeyFrame(frame, vec.X));
tracks[1].KeyFrames.Add(new STKeyFrame(frame, vec.Y));
tracks[2].KeyFrames.Add(new STKeyFrame(frame, vec.Z));
}
return tracks;
}
public STAnimationTrack[] LoadRotationTrack(Gfbanim.FramedQuatTrack framedTrack)
{
ushort[] frames = framedTrack.GetFramesArray();
STAnimationTrack[] tracks = new STAnimationTrack[3];
tracks[0] = new STAnimationTrack(STInterpoaltionType.Linear);
tracks[1] = new STAnimationTrack(STInterpoaltionType.Linear);
tracks[2] = new STAnimationTrack(STInterpoaltionType.Linear);
for (int i = 0; i < framedTrack.ValuesLength; i++)
{
var quat = framedTrack.Values(i).Value;
int frame = i;
if (i < frames?.Length) frame = frames[i];
tracks[0].KeyFrames.Add(new STKeyFrame(frame, ConvertRotation(quat.X)));
tracks[1].KeyFrames.Add(new STKeyFrame(frame, ConvertRotation(quat.Y)));
tracks[2].KeyFrames.Add(new STKeyFrame(frame, ConvertRotation(quat.Z)));
}
return tracks;
}
public void LoadMaterialGroup(Gfbanim.Material matAnim)
{
}
public void LoadVisibilyGroup(Gfbanim.Group visAnim)
{
}
public void LoadTriggerGroup(Gfbanim.Trigger triggerAnim)
{
}
private STAnimationTrack LoadTrack(float[] Frames, float[] Values)
{
STAnimationTrack track = new STAnimationTrack();
track.InterpolationType = STInterpoaltionType.Linear;
for (int i = 0; i < Values?.Length; i++)
{
STKeyFrame keyFrame = new STKeyFrame();
keyFrame.Value = Values[i];
keyFrame.Value = Frames[i];
track.KeyFrames.Add(keyFrame);
}
return track;
}
}
public class BoneGroup : STAnimGroup
{
public STAnimationTrack TranslateX = new STAnimationTrack();
public STAnimationTrack TranslateY = new STAnimationTrack();
public STAnimationTrack TranslateZ = new STAnimationTrack();
public STAnimationTrack RotationX = new STAnimationTrack();
public STAnimationTrack RotationY = new STAnimationTrack();
public STAnimationTrack RotationZ = new STAnimationTrack();
public STAnimationTrack RotationW = new STAnimationTrack();
public STAnimationTrack ScaleX = new STAnimationTrack();
public STAnimationTrack ScaleY = new STAnimationTrack();
public STAnimationTrack ScaleZ = new STAnimationTrack();
public override List<STAnimationTrack> GetTracks()
{
List<STAnimationTrack> anims = new List<STAnimationTrack>();
anims.Add(TranslateX); anims.Add(TranslateY); anims.Add(TranslateZ);
anims.Add(RotationX); anims.Add(RotationY); anims.Add(RotationZ);
anims.Add(ScaleX); anims.Add(ScaleY); anims.Add(ScaleZ);
return anims;
}
}
public class MaterialGroup : STAnimGroup
{
}
public class MaterialSwitchGroup : STAnimGroup
{
public STAnimationTrack SwitchTrack = new STAnimationTrack();
public override List<STAnimationTrack> GetTracks() {
return new List<STAnimationTrack>() { SwitchTrack };
}
}
public class MaterialValueGroup : STAnimGroup
{
public STAnimationTrack ValueTrack = new STAnimationTrack();
public override List<STAnimationTrack> GetTracks() {
return new List<STAnimationTrack>() { ValueTrack };
}
}
public class MaterialVectorGroup : STAnimGroup
{
public STAnimationTrack VectorX = new STAnimationTrack();
public STAnimationTrack VectorY = new STAnimationTrack();
public STAnimationTrack VectorZ = new STAnimationTrack();
public override List<STAnimationTrack> GetTracks()
{
return new List<STAnimationTrack>()
{ VectorX, VectorY, VectorZ };
}
}
public class VisibiltyGroup : STAnimGroup
{
public STAnimationTrack BooleanTrack = new STAnimationTrack();
public override List<STAnimationTrack> GetTracks() {
return new List<STAnimationTrack>() { BooleanTrack };
}
}
public class TriggerGroup : STAnimGroup
{
public string Name { get; set; }
public byte Type { get; set; }
//float, byte, int, string
public object Value { get; set; }
}
}
}

View file

@ -0,0 +1,448 @@
// <auto-generated>
// automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>
namespace FlatBuffers.Gfbanmcfg
{
using global::System;
using global::FlatBuffers;
public struct AnimationConfig : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static AnimationConfig GetRootAsAnimationConfig(ByteBuffer _bb) { return GetRootAsAnimationConfig(_bb, new AnimationConfig()); }
public static AnimationConfig GetRootAsAnimationConfig(ByteBuffer _bb, AnimationConfig obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public AnimationConfig __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public PartList? Parts { get { int o = __p.__offset(4); return o != 0 ? (PartList?)(new PartList()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public FloatingList? FloatList { get { int o = __p.__offset(6); return o != 0 ? (FloatingList?)(new FloatingList()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public int Unkown { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
public int Unkown2 { get { int o = __p.__offset(10); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
public StateList? States { get { int o = __p.__offset(12); return o != 0 ? (StateList?)(new StateList()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public Initial? Initial { get { int o = __p.__offset(14); return o != 0 ? (Initial?)(new Initial()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public AnimationList? Animations { get { int o = __p.__offset(16); return o != 0 ? (AnimationList?)(new AnimationList()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public static Offset<AnimationConfig> CreateAnimationConfig(FlatBufferBuilder builder,
Offset<PartList> PartsOffset = default(Offset<PartList>),
Offset<FloatingList> FloatListOffset = default(Offset<FloatingList>),
int Unkown = 0,
int Unkown2 = 0,
Offset<StateList> StatesOffset = default(Offset<StateList>),
Offset<Initial> InitialOffset = default(Offset<Initial>),
Offset<AnimationList> AnimationsOffset = default(Offset<AnimationList>))
{
builder.StartObject(7);
AnimationConfig.AddAnimations(builder, AnimationsOffset);
AnimationConfig.AddInitial(builder, InitialOffset);
AnimationConfig.AddStates(builder, StatesOffset);
AnimationConfig.AddUnkown2(builder, Unkown2);
AnimationConfig.AddUnkown(builder, Unkown);
AnimationConfig.AddFloatList(builder, FloatListOffset);
AnimationConfig.AddParts(builder, PartsOffset);
return AnimationConfig.EndAnimationConfig(builder);
}
public static void StartAnimationConfig(FlatBufferBuilder builder) { builder.StartObject(7); }
public static void AddParts(FlatBufferBuilder builder, Offset<PartList> PartsOffset) { builder.AddOffset(0, PartsOffset.Value, 0); }
public static void AddFloatList(FlatBufferBuilder builder, Offset<FloatingList> FloatListOffset) { builder.AddOffset(1, FloatListOffset.Value, 0); }
public static void AddUnkown(FlatBufferBuilder builder, int Unkown) { builder.AddInt(2, Unkown, 0); }
public static void AddUnkown2(FlatBufferBuilder builder, int Unkown2) { builder.AddInt(3, Unkown2, 0); }
public static void AddStates(FlatBufferBuilder builder, Offset<StateList> StatesOffset) { builder.AddOffset(4, StatesOffset.Value, 0); }
public static void AddInitial(FlatBufferBuilder builder, Offset<Initial> InitialOffset) { builder.AddOffset(5, InitialOffset.Value, 0); }
public static void AddAnimations(FlatBufferBuilder builder, Offset<AnimationList> AnimationsOffset) { builder.AddOffset(6, AnimationsOffset.Value, 0); }
public static Offset<AnimationConfig> EndAnimationConfig(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<AnimationConfig>(o);
}
public static void FinishAnimationConfigBuffer(FlatBufferBuilder builder, Offset<AnimationConfig> offset) { builder.Finish(offset.Value); }
public static void FinishSizePrefixedAnimationConfigBuffer(FlatBufferBuilder builder, Offset<AnimationConfig> offset) { builder.FinishSizePrefixed(offset.Value); }
};
public struct StateList : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static StateList GetRootAsStateList(ByteBuffer _bb) { return GetRootAsStateList(_bb, new StateList()); }
public static StateList GetRootAsStateList(ByteBuffer _bb, StateList obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public StateList __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public static void StartStateList(FlatBufferBuilder builder) { builder.StartObject(0); }
public static Offset<StateList> EndStateList(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<StateList>(o);
}
};
public struct Initial : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static Initial GetRootAsInitial(ByteBuffer _bb) { return GetRootAsInitial(_bb, new Initial()); }
public static Initial GetRootAsInitial(ByteBuffer _bb, Initial obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public Initial __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public static void StartInitial(FlatBufferBuilder builder) { builder.StartObject(0); }
public static Offset<Initial> EndInitial(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<Initial>(o);
}
};
public struct FloatingList : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static FloatingList GetRootAsFloatingList(ByteBuffer _bb) { return GetRootAsFloatingList(_bb, new FloatingList()); }
public static FloatingList GetRootAsFloatingList(ByteBuffer _bb, FloatingList obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public FloatingList __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public static void StartFloatingList(FlatBufferBuilder builder) { builder.StartObject(0); }
public static Offset<FloatingList> EndFloatingList(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<FloatingList>(o);
}
};
public struct AnimationList : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static AnimationList GetRootAsAnimationList(ByteBuffer _bb) { return GetRootAsAnimationList(_bb, new AnimationList()); }
public static AnimationList GetRootAsAnimationList(ByteBuffer _bb, AnimationList obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public AnimationList __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public AnimationRef? Animations(int j) { int o = __p.__offset(4); return o != 0 ? (AnimationRef?)(new AnimationRef()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
public int AnimationsLength { get { int o = __p.__offset(4); return o != 0 ? __p.__vector_len(o) : 0; } }
public static Offset<AnimationList> CreateAnimationList(FlatBufferBuilder builder,
VectorOffset AnimationsOffset = default(VectorOffset))
{
builder.StartObject(1);
AnimationList.AddAnimations(builder, AnimationsOffset);
return AnimationList.EndAnimationList(builder);
}
public static void StartAnimationList(FlatBufferBuilder builder) { builder.StartObject(1); }
public static void AddAnimations(FlatBufferBuilder builder, VectorOffset AnimationsOffset) { builder.AddOffset(0, AnimationsOffset.Value, 0); }
public static VectorOffset CreateAnimationsVector(FlatBufferBuilder builder, Offset<AnimationRef>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
public static VectorOffset CreateAnimationsVectorBlock(FlatBufferBuilder builder, Offset<AnimationRef>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
public static void StartAnimationsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
public static Offset<AnimationList> EndAnimationList(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<AnimationList>(o);
}
};
public struct AnimationRef : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static AnimationRef GetRootAsAnimationRef(ByteBuffer _bb) { return GetRootAsAnimationRef(_bb, new AnimationRef()); }
public static AnimationRef GetRootAsAnimationRef(ByteBuffer _bb, AnimationRef obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public AnimationRef __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public string Name { get { int o = __p.__offset(4); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
#if ENABLE_SPAN_T
public Span<byte> GetNameBytes() { return __p.__vector_as_span(4); }
#else
public ArraySegment<byte>? GetNameBytes() { return __p.__vector_as_arraysegment(4); }
#endif
public byte[] GetNameArray() { return __p.__vector_as_array<byte>(4); }
public string File { get { int o = __p.__offset(6); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
#if ENABLE_SPAN_T
public Span<byte> GetFileBytes() { return __p.__vector_as_span(6); }
#else
public ArraySegment<byte>? GetFileBytes() { return __p.__vector_as_arraysegment(6); }
#endif
public byte[] GetFileArray() { return __p.__vector_as_array<byte>(6); }
public static Offset<AnimationRef> CreateAnimationRef(FlatBufferBuilder builder,
StringOffset NameOffset = default(StringOffset),
StringOffset FileOffset = default(StringOffset))
{
builder.StartObject(2);
AnimationRef.AddFile(builder, FileOffset);
AnimationRef.AddName(builder, NameOffset);
return AnimationRef.EndAnimationRef(builder);
}
public static void StartAnimationRef(FlatBufferBuilder builder) { builder.StartObject(2); }
public static void AddName(FlatBufferBuilder builder, StringOffset NameOffset) { builder.AddOffset(0, NameOffset.Value, 0); }
public static void AddFile(FlatBufferBuilder builder, StringOffset FileOffset) { builder.AddOffset(1, FileOffset.Value, 0); }
public static Offset<AnimationRef> EndAnimationRef(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<AnimationRef>(o);
}
};
public struct PartList : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static PartList GetRootAsPartList(ByteBuffer _bb) { return GetRootAsPartList(_bb, new PartList()); }
public static PartList GetRootAsPartList(ByteBuffer _bb, PartList obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public PartList __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public static void StartPartList(FlatBufferBuilder builder) { builder.StartObject(0); }
public static Offset<PartList> EndPartList(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<PartList>(o);
}
};
public struct Part : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static Part GetRootAsPart(ByteBuffer _bb) { return GetRootAsPart(_bb, new Part()); }
public static Part GetRootAsPart(ByteBuffer _bb, Part obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public Part __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public int ID { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
public string Name { get { int o = __p.__offset(6); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
#if ENABLE_SPAN_T
public Span<byte> GetNameBytes() { return __p.__vector_as_span(6); }
#else
public ArraySegment<byte>? GetNameBytes() { return __p.__vector_as_arraysegment(6); }
#endif
public byte[] GetNameArray() { return __p.__vector_as_array<byte>(6); }
public ModelRef? Objects { get { int o = __p.__offset(8); return o != 0 ? (ModelRef?)(new ModelRef()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public static Offset<Part> CreatePart(FlatBufferBuilder builder,
int ID = 0,
StringOffset NameOffset = default(StringOffset),
Offset<ModelRef> ObjectsOffset = default(Offset<ModelRef>))
{
builder.StartObject(3);
Part.AddObjects(builder, ObjectsOffset);
Part.AddName(builder, NameOffset);
Part.AddID(builder, ID);
return Part.EndPart(builder);
}
public static void StartPart(FlatBufferBuilder builder) { builder.StartObject(3); }
public static void AddID(FlatBufferBuilder builder, int ID) { builder.AddInt(0, ID, 0); }
public static void AddName(FlatBufferBuilder builder, StringOffset NameOffset) { builder.AddOffset(1, NameOffset.Value, 0); }
public static void AddObjects(FlatBufferBuilder builder, Offset<ModelRef> ObjectsOffset) { builder.AddOffset(2, ObjectsOffset.Value, 0); }
public static Offset<Part> EndPart(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<Part>(o);
}
};
public struct PartEffect : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static PartEffect GetRootAsPartEffect(ByteBuffer _bb) { return GetRootAsPartEffect(_bb, new PartEffect()); }
public static PartEffect GetRootAsPartEffect(ByteBuffer _bb, PartEffect obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public PartEffect __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public int Empty { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
public static Offset<PartEffect> CreatePartEffect(FlatBufferBuilder builder,
int empty = 0)
{
builder.StartObject(1);
PartEffect.AddEmpty(builder, empty);
return PartEffect.EndPartEffect(builder);
}
public static void StartPartEffect(FlatBufferBuilder builder) { builder.StartObject(1); }
public static void AddEmpty(FlatBufferBuilder builder, int empty) { builder.AddInt(0, empty, 0); }
public static Offset<PartEffect> EndPartEffect(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<PartEffect>(o);
}
};
public struct ModelRef : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static ModelRef GetRootAsModelRef(ByteBuffer _bb) { return GetRootAsModelRef(_bb, new ModelRef()); }
public static ModelRef GetRootAsModelRef(ByteBuffer _bb, ModelRef obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public ModelRef __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public StringList? Bones { get { int o = __p.__offset(4); return o != 0 ? (StringList?)(new StringList()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public static Offset<ModelRef> CreateModelRef(FlatBufferBuilder builder,
Offset<StringList> BonesOffset = default(Offset<StringList>))
{
builder.StartObject(1);
ModelRef.AddBones(builder, BonesOffset);
return ModelRef.EndModelRef(builder);
}
public static void StartModelRef(FlatBufferBuilder builder) { builder.StartObject(1); }
public static void AddBones(FlatBufferBuilder builder, Offset<StringList> BonesOffset) { builder.AddOffset(0, BonesOffset.Value, 0); }
public static Offset<ModelRef> EndModelRef(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<ModelRef>(o);
}
};
public struct StringList : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static StringList GetRootAsStringList(ByteBuffer _bb) { return GetRootAsStringList(_bb, new StringList()); }
public static StringList GetRootAsStringList(ByteBuffer _bb, StringList obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public StringList __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public sbyte Unknown { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetSbyte(o + __p.bb_pos) : (sbyte)0; } }
public string List(int j) { int o = __p.__offset(6); return o != 0 ? __p.__string(__p.__vector(o) + j * 4) : null; }
public int ListLength { get { int o = __p.__offset(6); return o != 0 ? __p.__vector_len(o) : 0; } }
public static Offset<StringList> CreateStringList(FlatBufferBuilder builder,
sbyte Unknown = 0,
VectorOffset ListOffset = default(VectorOffset))
{
builder.StartObject(2);
StringList.AddList(builder, ListOffset);
StringList.AddUnknown(builder, Unknown);
return StringList.EndStringList(builder);
}
public static void StartStringList(FlatBufferBuilder builder) { builder.StartObject(2); }
public static void AddUnknown(FlatBufferBuilder builder, sbyte Unknown) { builder.AddSbyte(0, Unknown, 0); }
public static void AddList(FlatBufferBuilder builder, VectorOffset ListOffset) { builder.AddOffset(1, ListOffset.Value, 0); }
public static VectorOffset CreateListVector(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
public static VectorOffset CreateListVectorBlock(FlatBufferBuilder builder, StringOffset[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
public static void StartListVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
public static Offset<StringList> EndStringList(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<StringList>(o);
}
};
public struct Vector3 : IFlatbufferObject
{
private Struct __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public Vector3 __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public float X { get { return __p.bb.GetFloat(__p.bb_pos + 0); } }
public float Y { get { return __p.bb.GetFloat(__p.bb_pos + 4); } }
public float Z { get { return __p.bb.GetFloat(__p.bb_pos + 8); } }
public static Offset<Vector3> CreateVector3(FlatBufferBuilder builder, float X, float Y, float Z)
{
builder.Prep(4, 12);
builder.PutFloat(Z);
builder.PutFloat(Y);
builder.PutFloat(X);
return new Offset<Vector3>(builder.Offset);
}
};
public struct Vector4 : IFlatbufferObject
{
private Struct __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public Vector4 __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public float X { get { return __p.bb.GetFloat(__p.bb_pos + 0); } }
public float Y { get { return __p.bb.GetFloat(__p.bb_pos + 4); } }
public float Z { get { return __p.bb.GetFloat(__p.bb_pos + 8); } }
public float W { get { return __p.bb.GetFloat(__p.bb_pos + 12); } }
public static Offset<Vector4> CreateVector4(FlatBufferBuilder builder, float X, float Y, float Z, float W)
{
builder.Prep(4, 16);
builder.PutFloat(W);
builder.PutFloat(Z);
builder.PutFloat(Y);
builder.PutFloat(X);
return new Offset<Vector4>(builder.Offset);
}
};
public struct Quaternion : IFlatbufferObject
{
private Struct __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public Quaternion __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public ushort X { get { return __p.bb.GetUshort(__p.bb_pos + 0); } }
public ushort Y { get { return __p.bb.GetUshort(__p.bb_pos + 2); } }
public ushort Z { get { return __p.bb.GetUshort(__p.bb_pos + 4); } }
public static Offset<Quaternion> CreateQuaternion(FlatBufferBuilder builder, ushort X, ushort Y, ushort Z)
{
builder.Prep(2, 6);
builder.PutUshort(Z);
builder.PutUshort(Y);
builder.PutUshort(X);
return new Offset<Quaternion>(builder.Offset);
}
};
public struct SRT : IFlatbufferObject
{
private Struct __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public SRT __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public float ScaleX { get { return __p.bb.GetFloat(__p.bb_pos + 0); } }
public float ScaleY { get { return __p.bb.GetFloat(__p.bb_pos + 4); } }
public float ScaleZ { get { return __p.bb.GetFloat(__p.bb_pos + 8); } }
public float RotateX { get { return __p.bb.GetFloat(__p.bb_pos + 12); } }
public float RotateY { get { return __p.bb.GetFloat(__p.bb_pos + 16); } }
public float RotateZ { get { return __p.bb.GetFloat(__p.bb_pos + 20); } }
public float RotateW { get { return __p.bb.GetFloat(__p.bb_pos + 24); } }
public float TranslateX { get { return __p.bb.GetFloat(__p.bb_pos + 28); } }
public float TranslateY { get { return __p.bb.GetFloat(__p.bb_pos + 32); } }
public float TranslateZ { get { return __p.bb.GetFloat(__p.bb_pos + 36); } }
public static Offset<SRT> CreateSRT(FlatBufferBuilder builder, float ScaleX, float ScaleY, float ScaleZ, float RotateX, float RotateY, float RotateZ, float RotateW, float TranslateX, float TranslateY, float TranslateZ)
{
builder.Prep(4, 40);
builder.PutFloat(TranslateZ);
builder.PutFloat(TranslateY);
builder.PutFloat(TranslateX);
builder.PutFloat(RotateW);
builder.PutFloat(RotateZ);
builder.PutFloat(RotateY);
builder.PutFloat(RotateX);
builder.PutFloat(ScaleZ);
builder.PutFloat(ScaleY);
builder.PutFloat(ScaleX);
return new Offset<SRT>(builder.Offset);
}
};
}

View file

@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Toolbox;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using OpenTK;
using System.Reflection;
using Toolbox.Library.Forms;
using Newtonsoft.Json;
namespace FirstPlugin
{
public class GFBANMCFG : IEditor<TextEditor>, IFileFormat, IConvertableTextFormat
{
public FileType FileType { get; set; } = FileType.Model;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "GFBANMCFG" };
public string[] Extension { get; set; } = new string[] { "*.gfbanmcfg" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool Identify(System.IO.Stream stream)
{
return Utils.GetExtension(FileName) == ".gfbanmcfg";
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
public AnimConfig Config;
public void Load(System.IO.Stream stream)
{
Config = new AnimConfig();
var flatBuffer = FlatBuffers.Gfbanmcfg.AnimationConfig.GetRootAsAnimationConfig(
new FlatBuffers.ByteBuffer(stream.ToBytes()));
if (flatBuffer.Animations != null) {
for (int i = 0; i < flatBuffer.Animations.Value.AnimationsLength; i++)
{
var anim = flatBuffer.Animations.Value.Animations(i).Value;
Console.WriteLine(anim.Name);
Config.Animations.Add(new Animation()
{
Name = anim.Name,
FileName = anim.File,
});
}
}
}
public class AnimConfig
{
public List<Animation> Animations = new List<Animation>();
}
public class Animation
{
public string Name { get; set; }
public string FileName { get; set; }
}
public TextEditor OpenForm()
{
return new TextEditor();
}
public void FillEditor(UserControl control)
{
((TextEditor)control).FileFormat = this;
((TextEditor)control).FillEditor(ConvertToString());
}
#region Text Converter Interface
public TextFileType TextFileType => TextFileType.Json;
public bool CanConvertBack => false;
public string ConvertToString() {
return JsonConvert.SerializeObject(Config, Formatting.Indented, new JsonSerializerSettings());
}
public void ConvertFromString(string text)
{
}
#endregion
public void Unload()
{
}
public void Save(System.IO.Stream stream)
{
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -6,31 +6,49 @@ using System.Threading.Tasks;
using Toolbox.Library;
using Toolbox.Library.Rendering;
using OpenTK;
using Toolbox.Library.Forms;
using System.Windows.Forms;
namespace FirstPlugin
{
public class GFBMaterial : STGenericMaterial
{
public GFBMDL.MaterialShaderData MaterialData { get; set; }
public GFBMDL ParentModel { get; set; }
public GFBMaterial(GFBMDL model, GFBMDL.MaterialShaderData data) {
ParentModel = model;
MaterialData = data;
}
}
public class GFBMesh : STGenericObject
public class GFLXMesh : STGenericObject, IContextMenuNode
{
public int[] display;
public int DisplayId;
public GFBMDL ParentModel { get; set; }
public GFLXModel ParentModel { get; set; }
public GFBMaterial GetMaterial(STGenericPolygonGroup polygroup)
public FlatBuffers.Gfbmdl.Mesh MeshData { get; set; }
public FlatBuffers.Gfbmdl.Group GroupData { get; set; }
public GFLXMaterialData GetMaterial(STGenericPolygonGroup polygroup)
{
return ParentModel.header.GenericMaterials[polygroup.MaterialIndex];
return ParentModel.GenericMaterials[polygroup.MaterialIndex];
}
public ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
var uvMenu = new ToolStripMenuItem("UVs");
Items.Add(uvMenu);
uvMenu.DropDownItems.Add(new ToolStripMenuItem("Flip Vertical", null, FlipVerticalAction, Keys.Control | Keys.V));
uvMenu.DropDownItems.Add(new ToolStripMenuItem("Flip Horizontal", null, FlipHorizontalAction, Keys.Control | Keys.H));
return Items.ToArray();
}
private void FlipVerticalAction(object sender, EventArgs args) {
this.FlipUvsVertical();
UpdateMesh();
}
private void FlipHorizontalAction(object sender, EventArgs args) {
this.FlipUvsHorizontal();
UpdateMesh();
}
private void UpdateMesh() {
ParentModel.UpdateVertexData(true);
GFLXMeshBufferHelper.ReloadVertexData(this);
}
public struct DisplayVertex
@ -50,10 +68,17 @@ namespace FirstPlugin
public static int Size = 4 * (3 + 3 + 3 + 2 + 4 + 4 + 4 + 2 + 2 + 3);
}
public GFBMesh(GFBMDL model) {
public GFLXMesh(GFLXModel model,
FlatBuffers.Gfbmdl.Group group,
FlatBuffers.Gfbmdl.Mesh mesh)
{
ParentModel = model;
GroupData = group;
MeshData = mesh;
}
public int MeshIndex { get; set; }
public List<DisplayVertex> CreateDisplayVertices()
{
List<int> Faces = new List<int>();

View file

@ -0,0 +1,303 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Toolbox.Library.IO;
using OpenTK;
using FlatBuffers.Gfbmdl;
using Toolbox.Library.Rendering;
using Toolbox.Library;
namespace FirstPlugin
{
public class GFLXMeshBufferHelper
{
public static void ReloadVertexData(GFLXMesh mesh)
{
var flatMesh = mesh.MeshData;
var buf = flatMesh.ByteBuffer;
for (int v = 0; v < mesh.vertices.Count; v++)
{
// flatMesh.ByteBuffer.PutByte();
// flatMesh.Data(v);
}
}
public static uint GetTotalBufferStride(Mesh mesh)
{
uint VertBufferStride = 0;
for (int i = 0; i < mesh.AlignmentsLength; i++)
{
var attribute = mesh.Alignments(i).Value;
switch (attribute.TypeID)
{
case VertexType.Position:
if (attribute.FormatID == BufferFormat.HalfFloat)
VertBufferStride += 0x08;
else if (attribute.FormatID == BufferFormat.Float)
VertBufferStride += 0x0C;
else
throw new Exception($"Unknown Combination! {attribute.TypeID} {attribute.FormatID}");
break;
case VertexType.Normal:
if (attribute.FormatID == BufferFormat.HalfFloat)
VertBufferStride += 0x08;
else if (attribute.FormatID == BufferFormat.Float)
VertBufferStride += 0x0C;
else
throw new Exception($"Unknown Combination! {attribute.TypeID} {attribute.FormatID}");
break;
case VertexType.Binormal:
if (attribute.FormatID == BufferFormat.HalfFloat)
VertBufferStride += 0x08;
else if (attribute.FormatID == BufferFormat.Float)
VertBufferStride += 0x0C;
else
throw new Exception($"Unknown Combination! {attribute.TypeID} {attribute.FormatID}");
break;
case VertexType.UV1:
case VertexType.UV2:
case VertexType.UV3:
case VertexType.UV4:
if (attribute.FormatID == BufferFormat.HalfFloat)
VertBufferStride += 0x04;
else if (attribute.FormatID == BufferFormat.Float)
VertBufferStride += 0x08;
else
throw new Exception($"Unknown Combination! {attribute.TypeID} {attribute.FormatID}");
break;
case VertexType.Color1:
case VertexType.Color2:
if (attribute.FormatID == BufferFormat.Byte)
VertBufferStride += 0x04;
else
throw new Exception($"Unknown Combination! {attribute.TypeID} {attribute.FormatID}");
break;
case VertexType.BoneID:
if (attribute.FormatID == BufferFormat.Short)
VertBufferStride += 0x08;
else if (attribute.FormatID == BufferFormat.Byte)
VertBufferStride += 0x04;
else
throw new Exception($"Unknown Combination! {attribute.TypeID} {attribute.FormatID}");
break;
case VertexType.BoneWeight:
if (attribute.FormatID == BufferFormat.BytesAsFloat)
VertBufferStride += 0x04;
else
throw new Exception($"Unknown Combination! {attribute.TypeID} {attribute.FormatID}");
break;
default:
Console.WriteLine($"attribute.FormatID {attribute.FormatID}");
if (attribute.FormatID == BufferFormat.HalfFloat)
VertBufferStride += 0x08;
else if (attribute.FormatID == BufferFormat.Float)
VertBufferStride += 0x0C;
else
throw new Exception($"Unknown Combination! {attribute.TypeID} {attribute.FormatID}");
break;
}
}
return VertBufferStride;
}
public static List<Vertex> LoadVertexData(Mesh mesh, OpenTK.Matrix4 transform, List<int> boneSkinningIds)
{
List<Vertex> Vertices = new List<Vertex>();
uint VertBufferStride = GetTotalBufferStride(mesh);
using (var reader = new FileReader(mesh.GetDataArray()))
{
uint numVertex = (uint)reader.BaseStream.Length / VertBufferStride;
for (int v = 0; v < numVertex; v++)
{
Vertex vertex = new Vertex();
Vertices.Add(vertex);
for (int att = 0; att < mesh.AlignmentsLength; att++)
{
var attribute = mesh.Alignments(att).Value;
switch (attribute.TypeID)
{
case VertexType.Position:
var pos = ParseBuffer(reader, attribute.FormatID, attribute.TypeID);
vertex.pos = new OpenTK.Vector3(pos.X, pos.Y, pos.Z);
vertex.pos = OpenTK.Vector3.TransformPosition(vertex.pos, transform);
break;
case VertexType.Normal:
var normal = ParseBuffer(reader, attribute.FormatID, attribute.TypeID);
vertex.nrm = new OpenTK.Vector3(normal.X, normal.Y, normal.Z);
vertex.nrm = OpenTK.Vector3.TransformNormal(vertex.nrm, transform);
break;
case VertexType.UV1:
var texcoord1 = ParseBuffer(reader, attribute.FormatID, attribute.TypeID);
vertex.uv0 = new OpenTK.Vector2(texcoord1.X, texcoord1.Y);
break;
case VertexType.UV2:
var texcoord2 = ParseBuffer(reader, attribute.FormatID, attribute.TypeID);
vertex.uv1 = new OpenTK.Vector2(texcoord2.X, texcoord2.Y);
break;
case VertexType.UV3:
var texcoord3 = ParseBuffer(reader, attribute.FormatID, attribute.TypeID);
vertex.uv2 = new OpenTK.Vector2(texcoord3.X, texcoord3.Y);
break;
case VertexType.UV4:
var texcoord4 = ParseBuffer(reader, attribute.FormatID, attribute.TypeID);
break;
case VertexType.BoneWeight:
var weights = ParseBuffer(reader, attribute.FormatID, attribute.TypeID);
vertex.boneWeights.AddRange(new float[]
{
weights.X,
weights.Y,
weights.Z,
weights.W
});
break;
case VertexType.BoneID:
var boneIndices = ParseBuffer(reader, attribute.FormatID, attribute.TypeID);
vertex.boneIds.AddRange(new int[]
{
boneSkinningIds[(int)boneIndices.X],
boneSkinningIds[(int)boneIndices.Y],
boneSkinningIds[(int)boneIndices.Z],
boneSkinningIds[(int)boneIndices.W],
});
break;
case VertexType.Color1:
OpenTK.Vector4 colors1 = new OpenTK.Vector4(1, 1, 1, 1);
if (attribute.FormatID == BufferFormat.Byte)
colors1 = ParseBuffer(reader, attribute.FormatID, attribute.TypeID);
vertex.col = new OpenTK.Vector4(colors1.X, colors1.Y, colors1.Z, colors1.W);
break;
case VertexType.Color2:
OpenTK.Vector4 colors2 = new OpenTK.Vector4(1, 1, 1, 1);
if (attribute.FormatID == BufferFormat.Byte)
colors2 = ParseBuffer(reader, attribute.FormatID, attribute.TypeID);
break;
case VertexType.Binormal:
var binormals = ParseBuffer(reader, attribute.FormatID, attribute.TypeID);
vertex.bitan = new OpenTK.Vector4(binormals.X, binormals.Y, binormals.Z, binormals.W);
break;
default:
ParseBuffer(reader, attribute.FormatID, attribute.TypeID);
break;
}
}
}
}
return Vertices;
}
private static OpenTK.Vector4 ParseBuffer(FileReader reader, BufferFormat Format, VertexType AttributeType)
{
if (AttributeType == VertexType.Position)
{
switch (Format)
{
case BufferFormat.Float:
return new OpenTK.Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), 0);
case BufferFormat.HalfFloat:
return new OpenTK.Vector4(reader.ReadHalfSingle(), reader.ReadHalfSingle(),
reader.ReadHalfSingle(), reader.ReadHalfSingle());
default:
throw new Exception($"Unknown Combination! {AttributeType} {Format}");
}
}
else if (AttributeType == VertexType.Normal)
{
switch (Format)
{
case BufferFormat.Float:
return new OpenTK.Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), 0);
case BufferFormat.HalfFloat:
return new OpenTK.Vector4(reader.ReadHalfSingle(), reader.ReadHalfSingle(),
reader.ReadHalfSingle(), reader.ReadHalfSingle());
default:
throw new Exception($"Unknown Combination! {AttributeType} {Format}");
}
}
else if (AttributeType == VertexType.Binormal)
{
switch (Format)
{
case BufferFormat.Float:
return new OpenTK.Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), 0);
case BufferFormat.HalfFloat:
return new OpenTK.Vector4(reader.ReadHalfSingle(), reader.ReadHalfSingle(),
reader.ReadHalfSingle(), reader.ReadHalfSingle());
default:
throw new Exception($"Unknown Combination! {AttributeType} {Format}");
}
}
else if (AttributeType == VertexType.UV1 ||
AttributeType == VertexType.UV2 ||
AttributeType == VertexType.UV3 ||
AttributeType == VertexType.UV4)
{
switch (Format)
{
case BufferFormat.Float:
return new OpenTK.Vector4(reader.ReadSingle(), reader.ReadSingle(), 0, 0);
case BufferFormat.HalfFloat:
return new OpenTK.Vector4(reader.ReadHalfSingle(), reader.ReadHalfSingle(), 0, 0);
default:
throw new Exception($"Unknown Combination! {AttributeType} {Format}");
}
}
else if (AttributeType == VertexType.Color1 ||
AttributeType == VertexType.Color2)
{
switch (Format)
{
case BufferFormat.Byte:
return new OpenTK.Vector4(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
default:
throw new Exception($"Unknown Combination! {AttributeType} {Format}");
}
}
else if (AttributeType == VertexType.BoneID)
{
switch (Format)
{
case BufferFormat.Short:
return new OpenTK.Vector4(reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16());
case BufferFormat.Byte:
return new OpenTK.Vector4(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
default:
throw new Exception($"Unknown Combination! {AttributeType} {Format}");
}
}
else if (AttributeType == VertexType.BoneWeight)
{
switch (Format)
{
case BufferFormat.BytesAsFloat:
return new OpenTK.Vector4(reader.ReadByteAsFloat(), reader.ReadByteAsFloat(),
reader.ReadByteAsFloat(), reader.ReadByteAsFloat());
default:
throw new Exception($"Unknown Combination! {AttributeType} {Format}");
}
}
else
{
switch (Format)
{
case BufferFormat.HalfFloat:
return new OpenTK.Vector4(reader.ReadHalfSingle(), reader.ReadHalfSingle(),
reader.ReadHalfSingle(), reader.ReadHalfSingle());
default:
throw new Exception($"Unknown Combination! {AttributeType} {Format}");
}
}
}
}
}

View file

@ -0,0 +1,329 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using FlatBuffers.Gfbmdl;
using Toolbox.Library;
using Toolbox.Library.IO;
using Toolbox.Library.Rendering;
using FirstPlugin.Forms;
namespace FirstPlugin
{
public class GFLXModel
{
public GFBMDL ParentFile;
public List<GFLXMaterialData> GenericMaterials = new List<GFLXMaterialData>();
public List<GFLXMesh> GenericMeshes = new List<GFLXMesh>();
public STSkeleton Skeleton = new STSkeleton();
public Model Model;
public List<string> Textures = new List<string>();
public List<string> Shaders = new List<string>();
public T LoadEditor<T>() where T :
System.Windows.Forms.UserControl, new()
{
return ParentFile.LoadEditor<T>();
}
public void UpdateVertexData(bool updateViewport) {
ParentFile.Renderer.UpdateVertexData();
if (updateViewport)
LibraryGUI.UpdateViewport();
}
public void LoadFile(Model model, GFBMDL file, GFBMDL_Render Renderer) {
Model = model;
ParentFile = file;
for (int t = 0; t < Model.TextureNamesLength; t++)
Textures.Add(Model.TextureNames(t));
for (int s = 0; s < Model.ShaderNamesLength; s++)
Shaders.Add(Model.ShaderNames(s));
for (int m = 0; m < Model.MaterialsLength; m++) {
var mat = Model.Materials(m).Value;
GenericMaterials.Add(new GFLXMaterialData(this, mat));
}
List<int> SkinningIndices = new List<int>();
for (int b = 0; b < Model.BonesLength; b++) {
var bone = Model.Bones(b).Value;
Skeleton.bones.Add(new GFLXBone(this, bone));
if (bone.Type == BoneType.HasSkinning && bone.SkinCheck == null)
SkinningIndices.Add(b);
}
Skeleton.reset();
Skeleton.update();
for (int g = 0; g < Model.GroupsLength; g++) {
var group = Model.Groups(g).Value;
var mesh = Model.Meshes(g).Value;
OpenTK.Matrix4 transform = OpenTK.Matrix4.Identity;
GFLXMesh genericMesh = new GFLXMesh(this, group, mesh);
genericMesh.Checked = true;
genericMesh.ImageKey = "model";
genericMesh.SelectedImageKey = "model";
int boneIndex = (int)group.BoneID;
if (boneIndex < Skeleton.bones.Count && boneIndex > 0)
{
genericMesh.BoneIndex = boneIndex;
transform = Skeleton.bones[boneIndex].Transform;
}
genericMesh.Text = Skeleton.bones[(int)group.MeshID].Text;
Renderer.Meshes.Add(genericMesh);
GenericMeshes.Add(genericMesh);
//Load the vertex data
genericMesh.vertices = GFLXMeshBufferHelper.LoadVertexData(mesh, transform, SkinningIndices);
genericMesh.FlipUvsVertical();
//Load faces
for (int p = 0; p < mesh.PolygonsLength; p++)
{
var poly = mesh.Polygons(p).Value;
var polygonGroup = new STGenericPolygonGroup();
polygonGroup.MaterialIndex = (int)poly.MaterialID;
genericMesh.PolygonGroups.Add(polygonGroup);
for (int f = 0; f < poly.DataLength; f++)
polygonGroup.faces.Add((int)poly.Data(f));
}
}
}
public void SaveFile(System.IO.Stream stream)
{
using (var writer = new FileWriter(stream)) {
writer.Write(Model.ByteBuffer.ToFullArray());
}
}
}
public class GFLXMaterialData : STGenericMaterial
{
private Material Material;
private GFLXModel ParentModel;
public Dictionary<string, GFLXSwitchParam> SwitchParams = new Dictionary<string, GFLXSwitchParam>();
public Dictionary<string, GFLXValueParam> ValueParams = new Dictionary<string, GFLXValueParam>();
public Dictionary<string, GFLXColorParam> ColorParams = new Dictionary<string, GFLXColorParam>();
public override void OnClick(TreeView treeView) {
var editor = ParentModel.LoadEditor<GFLXMaterialEditor>();
editor.LoadMaterial(this);
}
public GFLXMaterialData(GFLXModel parent, Material mat)
{
ParentModel = parent;
Material = mat;
Text = mat.Name;
for (int i = 0; i < Material.SwitchesLength; i++) {
var val = Material.Switches(i).Value;
SwitchParams.Add(val.Name, new GFLXSwitchParam(val));
}
for (int i = 0; i < Material.ValuesLength; i++) {
var val = Material.Values(i).Value;
ValueParams.Add(val.Name, new GFLXValueParam(val));
}
for (int i = 0; i < Material.ColorsLength; i++) {
var val = Material.Colors(i).Value;
ColorParams.Add(val.Name, new GFLXColorParam(val));
}
int textureUnit = 1;
for (int t = 0; t < Material.TexturesLength; t++)
{
var tex = Material.Textures(t).Value;
string name = ParentModel.Textures[tex.Index];
STGenericMatTexture matTexture = new STGenericMatTexture();
matTexture.Name = name;
matTexture.SamplerName = tex.Name;
matTexture.textureUnit = textureUnit++;
matTexture.WrapModeS = STTextureWrapMode.Mirror;
matTexture.WrapModeT = STTextureWrapMode.Repeat;
TextureMaps.Add(matTexture);
switch (tex.Name)
{
case "Col0Tex":
matTexture.Type = STGenericMatTexture.TextureType.Diffuse;
break;
case "EmissionMaskTex":
// matTexture.Type = STGenericMatTexture.TextureType.Emission;
break;
case "LyCol0Tex":
break;
case "NormalMapTex":
matTexture.WrapModeT = STTextureWrapMode.Repeat;
matTexture.WrapModeT = STTextureWrapMode.Repeat;
matTexture.Type = STGenericMatTexture.TextureType.Normal;
break;
case "AmbientTex":
break;
case "LightTblTex":
break;
case "SphereMapTex":
break;
case "EffectTex":
break;
}
}
}
}
public class GFLXBone : STBone
{
private Bone Bone;
private GFLXModel ParentModel;
public GFLXBone(GFLXModel parent, Bone bone) : base(parent.Skeleton)
{
ParentModel = parent;
Bone = bone;
Text = bone.Name;
parentIndex = bone.Parent;
if (bone.Translation != null)
{
position = new float[3]
{ bone.Translation.Value.X,
bone.Translation.Value.Y,
bone.Translation.Value.Z
};
}
if (bone.Rotation != null)
{
rotation = new float[4]
{ bone.Rotation.Value.X,
bone.Rotation.Value.Y,
bone.Rotation.Value.Z,
1.0f,
};
}
if (bone.Scale != null)
{
scale = new float[3]
{ bone.Scale.Value.X,
bone.Scale.Value.Y,
bone.Scale.Value.Z
};
}
}
}
public class GFLXColorParam
{
private MatColor Param;
public GFLXColorParam(MatColor param)
{
Param = param;
}
public string Name
{
get { return Param.Name; }
set
{
Param.ByteBuffer.PutStringUTF8(0, value);
}
}
public OpenTK.Vector3 Value
{
get { return new OpenTK.Vector3(
Param.Color.Value.R,
Param.Color.Value.G,
Param.Color.Value.B);
}
set
{
var vec3 = value;
Param.Color.Value.ByteBuffer.PutFloat(0, vec3.X);
Param.Color.Value.ByteBuffer.PutFloat(1, vec3.Y);
Param.Color.Value.ByteBuffer.PutFloat(2, vec3.Z);
}
}
}
public class GFLXValueParam
{
private MatFloat Param;
public GFLXValueParam(MatFloat param) {
Param = param;
}
public string Name
{
get { return Param.Name; }
set {
Param.ByteBuffer.PutStringUTF8(0, value);
}
}
public float Value
{
get { return Param.Value; }
set {
Param.ByteBuffer.PutFloat(1, value);
}
}
}
public class GFLXSwitchParam
{
private MatSwitch Param;
public GFLXSwitchParam(MatSwitch param)
{
Param = param;
}
public string Name
{
get { return Param.Name; }
set
{
Param.ByteBuffer.PutStringUTF8(0, value);
}
}
public bool Value
{
get { return Param.Value; }
set
{
Param.ByteBuffer.PutByte(1, value ? (byte)1 : (byte)0);
}
}
}
}

View file

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FirstPlugin
{
public class PokemonTable
{
public Dictionary<ushort, string> Gen8 = new Dictionary<ushort, string>()
{
{ 891,"Meltan" },
{ 892,"Melmetal" },
};
}
}

View file

@ -13,9 +13,9 @@ using OpenTK.Graphics.OpenGL;
namespace FirstPlugin
{
public class GFBMDL_Render : AbstractGlDrawable
public class GFBMDL_Render : AbstractGlDrawable, IMeshContainer
{
public List<GFBMesh> Meshes = new List<GFBMesh>();
public List<STGenericObject> Meshes { get; set; } = new List<STGenericObject>();
public Matrix4 ModelTransform = Matrix4.Identity;
@ -43,17 +43,17 @@ namespace FirstPlugin
if (!Runtime.OpenTKInitialized)
return;
GFBMesh.DisplayVertex[] Vertices;
GFLXMesh.DisplayVertex[] Vertices;
int[] Faces;
int poffset = 0;
int voffset = 0;
List<GFBMesh.DisplayVertex> Vs = new List<GFBMesh.DisplayVertex>();
List<GFLXMesh.DisplayVertex> Vs = new List<GFLXMesh.DisplayVertex>();
List<int> Ds = new List<int>();
foreach (GFBMesh shape in Meshes)
foreach (GFLXMesh shape in Meshes)
{
List<GFBMesh.DisplayVertex> pv = shape.CreateDisplayVertices();
List<GFLXMesh.DisplayVertex> pv = shape.CreateDisplayVertices();
Vs.AddRange(pv);
int GroupOffset = 0;
@ -82,7 +82,7 @@ namespace FirstPlugin
// Bind only once!
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_position);
GL.BufferData<GFBMesh.DisplayVertex>(BufferTarget.ArrayBuffer, (IntPtr)(Vertices.Length * GFBMesh.DisplayVertex.Size), Vertices, BufferUsageHint.StaticDraw);
GL.BufferData<GFLXMesh.DisplayVertex>(BufferTarget.ArrayBuffer, (IntPtr)(Vertices.Length * GFLXMesh.DisplayVertex.Size), Vertices, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements);
GL.BufferData<int>(BufferTarget.ElementArrayBuffer, (IntPtr)(Faces.Length * sizeof(int)), Faces, BufferUsageHint.StaticDraw);
@ -165,10 +165,10 @@ namespace FirstPlugin
GL.Enable(EnableCap.CullFace);
}
private static void SetBoneUniforms(GLControl control, ShaderProgram shader, GFBMesh mesh)
private static void SetBoneUniforms(GLControl control, ShaderProgram shader, GFLXMesh mesh)
{
int i = 0;
foreach (var bone in mesh.ParentModel.header.Skeleton.bones)
foreach (var bone in mesh.ParentModel.Skeleton.bones)
{
Matrix4 transform = bone.invert * bone.Transform;
@ -190,7 +190,7 @@ namespace FirstPlugin
}*/
}
private void SetUniformBlocks(GFBMaterial mat, ShaderProgram shader, GFBMesh m, int id)
private void SetUniformBlocks(GFLXMaterialData mat, ShaderProgram shader, GFLXMesh m, int id)
{
/* shader.UniformBlockBinding("TexCoord1", 3);
GL.GetActiveUniformBlock(shader.program,
@ -209,7 +209,7 @@ namespace FirstPlugin
GL.BINDBUFFER*/
}
private static void SetUniforms(GFBMaterial mat, ShaderProgram shader, GFBMesh m, int id)
private static void SetUniforms(GFLXMaterialData mat, ShaderProgram shader, GFLXMesh m, int id)
{
// Texture Maps
/* shader.SetBoolToInt("useColorTex", false);
@ -242,31 +242,26 @@ namespace FirstPlugin
SetUniformData(mat, shader, "ColorUVTranslateV");
}
private static void SetUniformData(GFBMaterial mat, ShaderProgram shader, string propertyName)
private static void SetUniformData(GFLXMaterialData mat, ShaderProgram shader, string propertyName)
{
if (mat.MaterialData.SwitchParams.ContainsKey(propertyName))
if (mat.SwitchParams.ContainsKey(propertyName))
{
bool Value = (bool)mat.MaterialData.SwitchParams[propertyName].Value;
bool Value = (bool)mat.SwitchParams[propertyName].Value;
shader.SetBoolToInt(propertyName, Value);
}
if (mat.MaterialData.ValueParams.ContainsKey(propertyName))
if (mat.ValueParams.ContainsKey(propertyName))
{
var Value = mat.MaterialData.ValueParams[propertyName].Value;
if (Value is float)
var Value = mat.ValueParams[propertyName].Value;
shader.SetFloat(propertyName, (float)Value);
if (Value is uint)
shader.SetFloat(propertyName, (uint)Value);
if (Value is int)
shader.SetFloat(propertyName, (int)Value);
}
if (mat.MaterialData.ColorParams.ContainsKey(propertyName))
if (mat.ColorParams.ContainsKey(propertyName))
{
Vector3 Value = (Vector3)mat.MaterialData.ColorParams[propertyName].Value;
Vector3 Value = (Vector3)mat.ColorParams[propertyName].Value;
shader.SetVector3(propertyName, Value);
}
}
private static void SetTextureUniforms(GFBMaterial mat, GFBMesh m, ShaderProgram shader)
private static void SetTextureUniforms(GFLXMaterialData mat, GFLXMesh m, ShaderProgram shader)
{
SetDefaultTextureAttributes(mat, shader);
@ -302,6 +297,11 @@ namespace FirstPlugin
shader.SetBoolToInt("HasDiffuse", true);
TextureUniform(shader, mat, true, "DiffuseMap", matex);
}
if (matex.Type == STGenericMatTexture.TextureType.Normal)
{
shader.SetBoolToInt("HasNormalMap", true);
TextureUniform(shader, mat, true, "NormalMap", matex);
}
}
}
@ -322,7 +322,7 @@ namespace FirstPlugin
shader.SetInt("brdfLUT", 27);
}
private static void TextureUniform(ShaderProgram shader, GFBMaterial mat, bool hasTex, string name, STGenericMatTexture mattex)
private static void TextureUniform(ShaderProgram shader, GFLXMaterialData mat, bool hasTex, string name, STGenericMatTexture mattex)
{
if (mattex.textureState == STGenericMatTexture.TextureState.Binded)
return;
@ -383,7 +383,7 @@ namespace FirstPlugin
GL.TexParameter(TextureTarget.Texture2D, (TextureParameterName)ExtTextureFilterAnisotropic.TextureMaxAnisotropyExt, 0.0f);
}
private static void SetDefaultTextureAttributes(GFBMaterial mat, ShaderProgram shader)
private static void SetDefaultTextureAttributes(GFLXMaterialData mat, ShaderProgram shader)
{
}
@ -397,7 +397,7 @@ namespace FirstPlugin
private void DrawModels(ShaderProgram shader, GL_ControlModern control)
{
shader.EnableVertexAttributes();
foreach (GFBMesh shp in Meshes)
foreach (GFLXMesh shp in Meshes)
{
if (shp.Checked)
DrawModel(control, shp, shader);
@ -405,30 +405,30 @@ namespace FirstPlugin
shader.DisableVertexAttributes();
}
private void SetVertexAttributes(GFBMesh m, ShaderProgram shader)
private void SetVertexAttributes(GFLXMesh m, ShaderProgram shader)
{
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_position);
GL.VertexAttribPointer(shader.GetAttribute("vPosition"), 3, VertexAttribPointerType.Float, false, GFBMesh.DisplayVertex.Size, 0); //+12
GL.VertexAttribPointer(shader.GetAttribute("vNormal"), 3, VertexAttribPointerType.Float, false, GFBMesh.DisplayVertex.Size, 12); //+12
GL.VertexAttribPointer(shader.GetAttribute("vTangent"), 3, VertexAttribPointerType.Float, false, GFBMesh.DisplayVertex.Size, 24); //+12
GL.VertexAttribPointer(shader.GetAttribute("vUV0"), 2, VertexAttribPointerType.Float, false, GFBMesh.DisplayVertex.Size, 36); //+8
GL.VertexAttribPointer(shader.GetAttribute("vColor"), 4, VertexAttribPointerType.Float, false, GFBMesh.DisplayVertex.Size, 44); //+16
GL.VertexAttribIPointer(shader.GetAttribute("vBone"), 4, VertexAttribIntegerType.Int, GFBMesh.DisplayVertex.Size, new IntPtr(60)); //+16
GL.VertexAttribPointer(shader.GetAttribute("vWeight"), 4, VertexAttribPointerType.Float, false, GFBMesh.DisplayVertex.Size, 76);//+16
GL.VertexAttribPointer(shader.GetAttribute("vUV1"), 2, VertexAttribPointerType.Float, false, GFBMesh.DisplayVertex.Size, 92);//+8
GL.VertexAttribPointer(shader.GetAttribute("vUV2"), 2, VertexAttribPointerType.Float, false, GFBMesh.DisplayVertex.Size, 100);//+8
GL.VertexAttribPointer(shader.GetAttribute("vBinormal"), 3, VertexAttribPointerType.Float, false, GFBMesh.DisplayVertex.Size, 108); //+12
GL.VertexAttribPointer(shader.GetAttribute("vPosition"), 3, VertexAttribPointerType.Float, false, GFLXMesh.DisplayVertex.Size, 0); //+12
GL.VertexAttribPointer(shader.GetAttribute("vNormal"), 3, VertexAttribPointerType.Float, false, GFLXMesh.DisplayVertex.Size, 12); //+12
GL.VertexAttribPointer(shader.GetAttribute("vTangent"), 3, VertexAttribPointerType.Float, false, GFLXMesh.DisplayVertex.Size, 24); //+12
GL.VertexAttribPointer(shader.GetAttribute("vUV0"), 2, VertexAttribPointerType.Float, false, GFLXMesh.DisplayVertex.Size, 36); //+8
GL.VertexAttribPointer(shader.GetAttribute("vColor"), 4, VertexAttribPointerType.Float, false, GFLXMesh.DisplayVertex.Size, 44); //+16
GL.VertexAttribIPointer(shader.GetAttribute("vBone"), 4, VertexAttribIntegerType.Int, GFLXMesh.DisplayVertex.Size, new IntPtr(60)); //+16
GL.VertexAttribPointer(shader.GetAttribute("vWeight"), 4, VertexAttribPointerType.Float, false, GFLXMesh.DisplayVertex.Size, 76);//+16
GL.VertexAttribPointer(shader.GetAttribute("vUV1"), 2, VertexAttribPointerType.Float, false, GFLXMesh.DisplayVertex.Size, 92);//+8
GL.VertexAttribPointer(shader.GetAttribute("vUV2"), 2, VertexAttribPointerType.Float, false, GFLXMesh.DisplayVertex.Size, 100);//+8
GL.VertexAttribPointer(shader.GetAttribute("vBinormal"), 3, VertexAttribPointerType.Float, false, GFLXMesh.DisplayVertex.Size, 108); //+12
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements);
}
private void DrawModel(GLControl control, GFBMesh m, ShaderProgram shader)
private void DrawModel(GLControl control, GFLXMesh m, ShaderProgram shader)
{
foreach (var group in m.PolygonGroups)
{
if (group.faces.Count <= 3)
return;
var Material = m.ParentModel.header.Materials[group.MaterialIndex];
var Material = m.ParentModel.GenericMaterials[group.MaterialIndex];
SetUniforms(m.GetMaterial(group), shader, m, m.DisplayId);
SetUniformBlocks(m.GetMaterial(group), shader, m, m.DisplayId);

View file

@ -0,0 +1,503 @@
namespace FirstPlugin.Forms
{
partial class GFLXMaterialEditor
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GFLXMaterialEditor));
this.stTabControl1 = new Toolbox.Library.Forms.STTabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.stPanel1 = new Toolbox.Library.Forms.STPanel();
this.stFlowLayoutPanel1 = new Toolbox.Library.Forms.STFlowLayoutPanel();
this.stDropDownPanel1 = new Toolbox.Library.Forms.STDropDownPanel();
this.listViewCustom1 = new Toolbox.Library.Forms.ListViewCustom();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.stDropDownPanel2 = new Toolbox.Library.Forms.STDropDownPanel();
this.stLabel2 = new Toolbox.Library.Forms.STLabel();
this.stTextBox2 = new Toolbox.Library.Forms.STTextBox();
this.stLabel1 = new Toolbox.Library.Forms.STLabel();
this.stTextBox1 = new Toolbox.Library.Forms.STTextBox();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.pictureBoxCustom1 = new Toolbox.Library.Forms.PictureBoxCustom();
this.stLabel3 = new Toolbox.Library.Forms.STLabel();
this.stLabel4 = new Toolbox.Library.Forms.STLabel();
this.stComboBox1 = new Toolbox.Library.Forms.STComboBox();
this.stComboBox2 = new Toolbox.Library.Forms.STComboBox();
this.barSlider1 = new BarSlider.BarSlider();
this.barSlider2 = new BarSlider.BarSlider();
this.barSlider3 = new BarSlider.BarSlider();
this.barSlider4 = new BarSlider.BarSlider();
this.stPanel2 = new Toolbox.Library.Forms.STPanel();
this.stTabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.stPanel1.SuspendLayout();
this.stFlowLayoutPanel1.SuspendLayout();
this.stDropDownPanel1.SuspendLayout();
this.stDropDownPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom1)).BeginInit();
this.stPanel2.SuspendLayout();
this.SuspendLayout();
//
// stTabControl1
//
this.stTabControl1.Controls.Add(this.tabPage1);
this.stTabControl1.Controls.Add(this.tabPage2);
this.stTabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.stTabControl1.Location = new System.Drawing.Point(0, 0);
this.stTabControl1.myBackColor = System.Drawing.Color.Empty;
this.stTabControl1.Name = "stTabControl1";
this.stTabControl1.SelectedIndex = 0;
this.stTabControl1.Size = new System.Drawing.Size(575, 769);
this.stTabControl1.TabIndex = 0;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.stPanel1);
this.tabPage1.Location = new System.Drawing.Point(4, 25);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(567, 740);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Texture Maps";
this.tabPage1.UseVisualStyleBackColor = true;
//
// stPanel1
//
this.stPanel1.Controls.Add(this.stFlowLayoutPanel1);
this.stPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.stPanel1.Location = new System.Drawing.Point(3, 3);
this.stPanel1.Name = "stPanel1";
this.stPanel1.Size = new System.Drawing.Size(561, 734);
this.stPanel1.TabIndex = 0;
//
// stFlowLayoutPanel1
//
this.stFlowLayoutPanel1.Controls.Add(this.stDropDownPanel1);
this.stFlowLayoutPanel1.Controls.Add(this.stDropDownPanel2);
this.stFlowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.stFlowLayoutPanel1.FixedHeight = false;
this.stFlowLayoutPanel1.FixedWidth = true;
this.stFlowLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.stFlowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.stFlowLayoutPanel1.Name = "stFlowLayoutPanel1";
this.stFlowLayoutPanel1.Size = new System.Drawing.Size(561, 734);
this.stFlowLayoutPanel1.TabIndex = 0;
//
// stDropDownPanel1
//
this.stDropDownPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.stDropDownPanel1.Controls.Add(this.listViewCustom1);
this.stDropDownPanel1.ExpandedHeight = 0;
this.stDropDownPanel1.IsExpanded = true;
this.stDropDownPanel1.Location = new System.Drawing.Point(0, 0);
this.stDropDownPanel1.Margin = new System.Windows.Forms.Padding(0);
this.stDropDownPanel1.Name = "stDropDownPanel1";
this.stDropDownPanel1.PanelName = "Textures";
this.stDropDownPanel1.PanelValueName = "";
this.stDropDownPanel1.SetIcon = null;
this.stDropDownPanel1.SetIconAlphaColor = System.Drawing.Color.Transparent;
this.stDropDownPanel1.SetIconColor = System.Drawing.Color.Transparent;
this.stDropDownPanel1.Size = new System.Drawing.Size(561, 207);
this.stDropDownPanel1.TabIndex = 0;
//
// listViewCustom1
//
this.listViewCustom1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.listViewCustom1.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.listViewCustom1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1});
this.listViewCustom1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
this.listViewCustom1.HideSelection = false;
this.listViewCustom1.Location = new System.Drawing.Point(3, 22);
this.listViewCustom1.Name = "listViewCustom1";
this.listViewCustom1.OwnerDraw = true;
this.listViewCustom1.Size = new System.Drawing.Size(570, 185);
this.listViewCustom1.TabIndex = 1;
this.listViewCustom1.UseCompatibleStateImageBehavior = false;
this.listViewCustom1.View = System.Windows.Forms.View.Details;
this.listViewCustom1.SelectedIndexChanged += new System.EventHandler(this.listViewCustom1_SelectedIndexChanged);
//
// columnHeader1
//
this.columnHeader1.Text = "Name";
this.columnHeader1.Width = 384;
//
// stDropDownPanel2
//
this.stDropDownPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.stDropDownPanel2.Controls.Add(this.stPanel2);
this.stDropDownPanel2.Controls.Add(this.stComboBox2);
this.stDropDownPanel2.Controls.Add(this.stComboBox1);
this.stDropDownPanel2.Controls.Add(this.stLabel4);
this.stDropDownPanel2.Controls.Add(this.stLabel3);
this.stDropDownPanel2.Controls.Add(this.pictureBoxCustom1);
this.stDropDownPanel2.Controls.Add(this.stLabel2);
this.stDropDownPanel2.Controls.Add(this.stTextBox2);
this.stDropDownPanel2.Controls.Add(this.stLabel1);
this.stDropDownPanel2.Controls.Add(this.stTextBox1);
this.stDropDownPanel2.ExpandedHeight = 0;
this.stDropDownPanel2.IsExpanded = true;
this.stDropDownPanel2.Location = new System.Drawing.Point(0, 207);
this.stDropDownPanel2.Margin = new System.Windows.Forms.Padding(0);
this.stDropDownPanel2.Name = "stDropDownPanel2";
this.stDropDownPanel2.PanelName = "Texture Params";
this.stDropDownPanel2.PanelValueName = "";
this.stDropDownPanel2.SetIcon = null;
this.stDropDownPanel2.SetIconAlphaColor = System.Drawing.Color.Transparent;
this.stDropDownPanel2.SetIconColor = System.Drawing.Color.Transparent;
this.stDropDownPanel2.Size = new System.Drawing.Size(561, 495);
this.stDropDownPanel2.TabIndex = 1;
//
// stLabel2
//
this.stLabel2.AutoSize = true;
this.stLabel2.Location = new System.Drawing.Point(14, 62);
this.stLabel2.Name = "stLabel2";
this.stLabel2.Size = new System.Drawing.Size(38, 13);
this.stLabel2.TabIndex = 4;
this.stLabel2.Text = "Effect:";
//
// stTextBox2
//
this.stTextBox2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.stTextBox2.Location = new System.Drawing.Point(67, 60);
this.stTextBox2.Name = "stTextBox2";
this.stTextBox2.Size = new System.Drawing.Size(208, 20);
this.stTextBox2.TabIndex = 3;
//
// stLabel1
//
this.stLabel1.AutoSize = true;
this.stLabel1.Location = new System.Drawing.Point(14, 36);
this.stLabel1.Name = "stLabel1";
this.stLabel1.Size = new System.Drawing.Size(38, 13);
this.stLabel1.TabIndex = 2;
this.stLabel1.Text = "Name:";
//
// stTextBox1
//
this.stTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.stTextBox1.Location = new System.Drawing.Point(67, 34);
this.stTextBox1.Name = "stTextBox1";
this.stTextBox1.Size = new System.Drawing.Size(208, 20);
this.stTextBox1.TabIndex = 1;
//
// tabPage2
//
this.tabPage2.Location = new System.Drawing.Point(4, 25);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(529, 525);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Params";
this.tabPage2.UseVisualStyleBackColor = true;
//
// pictureBoxCustom1
//
this.pictureBoxCustom1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.pictureBoxCustom1.BackColor = System.Drawing.Color.Transparent;
this.pictureBoxCustom1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBoxCustom1.BackgroundImage")));
this.pictureBoxCustom1.Location = new System.Drawing.Point(17, 133);
this.pictureBoxCustom1.Name = "pictureBoxCustom1";
this.pictureBoxCustom1.Size = new System.Drawing.Size(508, 378);
this.pictureBoxCustom1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBoxCustom1.TabIndex = 5;
this.pictureBoxCustom1.TabStop = false;
//
// stLabel3
//
this.stLabel3.AutoSize = true;
this.stLabel3.Location = new System.Drawing.Point(292, 36);
this.stLabel3.Name = "stLabel3";
this.stLabel3.Size = new System.Drawing.Size(74, 13);
this.stLabel3.TabIndex = 6;
this.stLabel3.Text = "Wrap Mode U";
//
// stLabel4
//
this.stLabel4.AutoSize = true;
this.stLabel4.Location = new System.Drawing.Point(292, 62);
this.stLabel4.Name = "stLabel4";
this.stLabel4.Size = new System.Drawing.Size(73, 13);
this.stLabel4.TabIndex = 7;
this.stLabel4.Text = "Wrap Mode V";
//
// stComboBox1
//
this.stComboBox1.BorderColor = System.Drawing.Color.Empty;
this.stComboBox1.BorderStyle = System.Windows.Forms.ButtonBorderStyle.Solid;
this.stComboBox1.ButtonColor = System.Drawing.Color.Empty;
this.stComboBox1.FormattingEnabled = true;
this.stComboBox1.IsReadOnly = false;
this.stComboBox1.Location = new System.Drawing.Point(372, 33);
this.stComboBox1.Name = "stComboBox1";
this.stComboBox1.Size = new System.Drawing.Size(153, 21);
this.stComboBox1.TabIndex = 8;
//
// stComboBox2
//
this.stComboBox2.BorderColor = System.Drawing.Color.Empty;
this.stComboBox2.BorderStyle = System.Windows.Forms.ButtonBorderStyle.Solid;
this.stComboBox2.ButtonColor = System.Drawing.Color.Empty;
this.stComboBox2.FormattingEnabled = true;
this.stComboBox2.IsReadOnly = false;
this.stComboBox2.Location = new System.Drawing.Point(371, 60);
this.stComboBox2.Name = "stComboBox2";
this.stComboBox2.Size = new System.Drawing.Size(154, 21);
this.stComboBox2.TabIndex = 9;
//
// barSlider1
//
this.barSlider1.ActiveEditColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
this.barSlider1.BarInnerColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(80)))), ((int)(((byte)(80)))));
this.barSlider1.BarPenColorBottom = System.Drawing.Color.Empty;
this.barSlider1.BarPenColorMiddle = System.Drawing.Color.Empty;
this.barSlider1.BarPenColorTop = System.Drawing.Color.Empty;
this.barSlider1.BorderRoundRectSize = new System.Drawing.Size(32, 32);
this.barSlider1.DataType = null;
this.barSlider1.DrawSemitransparentThumb = false;
this.barSlider1.ElapsedInnerColor = System.Drawing.Color.FromArgb(((int)(((byte)(83)))), ((int)(((byte)(121)))), ((int)(((byte)(180)))));
this.barSlider1.ElapsedPenColorBottom = System.Drawing.Color.Empty;
this.barSlider1.ElapsedPenColorMiddle = System.Drawing.Color.Empty;
this.barSlider1.ElapsedPenColorTop = System.Drawing.Color.Empty;
this.barSlider1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F);
this.barSlider1.IncrementAmount = 0.01F;
this.barSlider1.InputName = "Param1";
this.barSlider1.LargeChange = 5F;
this.barSlider1.Location = new System.Drawing.Point(6, 4);
this.barSlider1.Maximum = 100F;
this.barSlider1.Minimum = 0F;
this.barSlider1.Name = "barSlider1";
this.barSlider1.Precision = 0.01F;
this.barSlider1.ScaleDivisions = 1;
this.barSlider1.ScaleSubDivisions = 2;
this.barSlider1.ShowDivisionsText = false;
this.barSlider1.ShowSmallScale = false;
this.barSlider1.Size = new System.Drawing.Size(122, 25);
this.barSlider1.SmallChange = 1F;
this.barSlider1.TabIndex = 1;
this.barSlider1.Text = "barSlider1";
this.barSlider1.ThumbInnerColor = System.Drawing.Color.Empty;
this.barSlider1.ThumbPenColor = System.Drawing.Color.Empty;
this.barSlider1.ThumbRoundRectSize = new System.Drawing.Size(1, 1);
this.barSlider1.ThumbSize = new System.Drawing.Size(1, 1);
this.barSlider1.TickAdd = 0F;
this.barSlider1.TickColor = System.Drawing.Color.White;
this.barSlider1.TickDivide = 0F;
this.barSlider1.TickStyle = System.Windows.Forms.TickStyle.None;
this.barSlider1.UseInterlapsedBar = true;
this.barSlider1.Value = 30F;
//
// barSlider2
//
this.barSlider2.ActiveEditColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
this.barSlider2.BarInnerColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(80)))), ((int)(((byte)(80)))));
this.barSlider2.BarPenColorBottom = System.Drawing.Color.Empty;
this.barSlider2.BarPenColorMiddle = System.Drawing.Color.Empty;
this.barSlider2.BarPenColorTop = System.Drawing.Color.Empty;
this.barSlider2.BorderRoundRectSize = new System.Drawing.Size(32, 32);
this.barSlider2.DataType = null;
this.barSlider2.DrawSemitransparentThumb = false;
this.barSlider2.ElapsedInnerColor = System.Drawing.Color.FromArgb(((int)(((byte)(83)))), ((int)(((byte)(121)))), ((int)(((byte)(180)))));
this.barSlider2.ElapsedPenColorBottom = System.Drawing.Color.Empty;
this.barSlider2.ElapsedPenColorMiddle = System.Drawing.Color.Empty;
this.barSlider2.ElapsedPenColorTop = System.Drawing.Color.Empty;
this.barSlider2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F);
this.barSlider2.IncrementAmount = 0.01F;
this.barSlider2.InputName = "Param2";
this.barSlider2.LargeChange = 5F;
this.barSlider2.Location = new System.Drawing.Point(134, 4);
this.barSlider2.Maximum = 100F;
this.barSlider2.Minimum = 0F;
this.barSlider2.Name = "barSlider2";
this.barSlider2.Precision = 0.01F;
this.barSlider2.ScaleDivisions = 1;
this.barSlider2.ScaleSubDivisions = 2;
this.barSlider2.ShowDivisionsText = false;
this.barSlider2.ShowSmallScale = false;
this.barSlider2.Size = new System.Drawing.Size(122, 25);
this.barSlider2.SmallChange = 1F;
this.barSlider2.TabIndex = 10;
this.barSlider2.Text = "barSlider2";
this.barSlider2.ThumbInnerColor = System.Drawing.Color.Empty;
this.barSlider2.ThumbPenColor = System.Drawing.Color.Empty;
this.barSlider2.ThumbRoundRectSize = new System.Drawing.Size(1, 1);
this.barSlider2.ThumbSize = new System.Drawing.Size(1, 1);
this.barSlider2.TickAdd = 0F;
this.barSlider2.TickColor = System.Drawing.Color.White;
this.barSlider2.TickDivide = 0F;
this.barSlider2.TickStyle = System.Windows.Forms.TickStyle.None;
this.barSlider2.UseInterlapsedBar = true;
this.barSlider2.Value = 30F;
//
// barSlider3
//
this.barSlider3.ActiveEditColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
this.barSlider3.BarInnerColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(80)))), ((int)(((byte)(80)))));
this.barSlider3.BarPenColorBottom = System.Drawing.Color.Empty;
this.barSlider3.BarPenColorMiddle = System.Drawing.Color.Empty;
this.barSlider3.BarPenColorTop = System.Drawing.Color.Empty;
this.barSlider3.BorderRoundRectSize = new System.Drawing.Size(32, 32);
this.barSlider3.DataType = null;
this.barSlider3.DrawSemitransparentThumb = false;
this.barSlider3.ElapsedInnerColor = System.Drawing.Color.FromArgb(((int)(((byte)(83)))), ((int)(((byte)(121)))), ((int)(((byte)(180)))));
this.barSlider3.ElapsedPenColorBottom = System.Drawing.Color.Empty;
this.barSlider3.ElapsedPenColorMiddle = System.Drawing.Color.Empty;
this.barSlider3.ElapsedPenColorTop = System.Drawing.Color.Empty;
this.barSlider3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F);
this.barSlider3.IncrementAmount = 0.01F;
this.barSlider3.InputName = "Param4";
this.barSlider3.LargeChange = 5F;
this.barSlider3.Location = new System.Drawing.Point(392, 5);
this.barSlider3.Maximum = 100F;
this.barSlider3.Minimum = 0F;
this.barSlider3.Name = "barSlider3";
this.barSlider3.Precision = 0.01F;
this.barSlider3.ScaleDivisions = 1;
this.barSlider3.ScaleSubDivisions = 2;
this.barSlider3.ShowDivisionsText = false;
this.barSlider3.ShowSmallScale = false;
this.barSlider3.Size = new System.Drawing.Size(122, 25);
this.barSlider3.SmallChange = 1F;
this.barSlider3.TabIndex = 12;
this.barSlider3.Text = "barSlider3";
this.barSlider3.ThumbInnerColor = System.Drawing.Color.Empty;
this.barSlider3.ThumbPenColor = System.Drawing.Color.Empty;
this.barSlider3.ThumbRoundRectSize = new System.Drawing.Size(1, 1);
this.barSlider3.ThumbSize = new System.Drawing.Size(1, 1);
this.barSlider3.TickAdd = 0F;
this.barSlider3.TickColor = System.Drawing.Color.White;
this.barSlider3.TickDivide = 0F;
this.barSlider3.TickStyle = System.Windows.Forms.TickStyle.None;
this.barSlider3.UseInterlapsedBar = true;
this.barSlider3.Value = 30F;
//
// barSlider4
//
this.barSlider4.ActiveEditColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
this.barSlider4.BarInnerColor = System.Drawing.Color.FromArgb(((int)(((byte)(80)))), ((int)(((byte)(80)))), ((int)(((byte)(80)))));
this.barSlider4.BarPenColorBottom = System.Drawing.Color.Empty;
this.barSlider4.BarPenColorMiddle = System.Drawing.Color.Empty;
this.barSlider4.BarPenColorTop = System.Drawing.Color.Empty;
this.barSlider4.BorderRoundRectSize = new System.Drawing.Size(32, 32);
this.barSlider4.DataType = null;
this.barSlider4.DrawSemitransparentThumb = false;
this.barSlider4.ElapsedInnerColor = System.Drawing.Color.FromArgb(((int)(((byte)(83)))), ((int)(((byte)(121)))), ((int)(((byte)(180)))));
this.barSlider4.ElapsedPenColorBottom = System.Drawing.Color.Empty;
this.barSlider4.ElapsedPenColorMiddle = System.Drawing.Color.Empty;
this.barSlider4.ElapsedPenColorTop = System.Drawing.Color.Empty;
this.barSlider4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8F);
this.barSlider4.IncrementAmount = 0.01F;
this.barSlider4.InputName = "Param3";
this.barSlider4.LargeChange = 5F;
this.barSlider4.Location = new System.Drawing.Point(264, 5);
this.barSlider4.Maximum = 100F;
this.barSlider4.Minimum = 0F;
this.barSlider4.Name = "barSlider4";
this.barSlider4.Precision = 0.01F;
this.barSlider4.ScaleDivisions = 1;
this.barSlider4.ScaleSubDivisions = 2;
this.barSlider4.ShowDivisionsText = false;
this.barSlider4.ShowSmallScale = false;
this.barSlider4.Size = new System.Drawing.Size(122, 25);
this.barSlider4.SmallChange = 1F;
this.barSlider4.TabIndex = 11;
this.barSlider4.Text = "barSlider4";
this.barSlider4.ThumbInnerColor = System.Drawing.Color.Empty;
this.barSlider4.ThumbPenColor = System.Drawing.Color.Empty;
this.barSlider4.ThumbRoundRectSize = new System.Drawing.Size(1, 1);
this.barSlider4.ThumbSize = new System.Drawing.Size(1, 1);
this.barSlider4.TickAdd = 0F;
this.barSlider4.TickColor = System.Drawing.Color.White;
this.barSlider4.TickDivide = 0F;
this.barSlider4.TickStyle = System.Windows.Forms.TickStyle.None;
this.barSlider4.UseInterlapsedBar = true;
this.barSlider4.Value = 30F;
//
// stPanel2
//
this.stPanel2.Controls.Add(this.barSlider2);
this.stPanel2.Controls.Add(this.barSlider1);
this.stPanel2.Controls.Add(this.barSlider3);
this.stPanel2.Controls.Add(this.barSlider4);
this.stPanel2.Location = new System.Drawing.Point(3, 87);
this.stPanel2.Name = "stPanel2";
this.stPanel2.Size = new System.Drawing.Size(555, 40);
this.stPanel2.TabIndex = 13;
//
// GFLXMaterialEditor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.stTabControl1);
this.Name = "GFLXMaterialEditor";
this.Size = new System.Drawing.Size(575, 769);
this.stTabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.stPanel1.ResumeLayout(false);
this.stFlowLayoutPanel1.ResumeLayout(false);
this.stDropDownPanel1.ResumeLayout(false);
this.stDropDownPanel1.PerformLayout();
this.stDropDownPanel2.ResumeLayout(false);
this.stDropDownPanel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom1)).EndInit();
this.stPanel2.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private Toolbox.Library.Forms.STTabControl stTabControl1;
private System.Windows.Forms.TabPage tabPage1;
private Toolbox.Library.Forms.STPanel stPanel1;
private System.Windows.Forms.TabPage tabPage2;
private Toolbox.Library.Forms.STFlowLayoutPanel stFlowLayoutPanel1;
private Toolbox.Library.Forms.STDropDownPanel stDropDownPanel1;
private Toolbox.Library.Forms.STDropDownPanel stDropDownPanel2;
private Toolbox.Library.Forms.ListViewCustom listViewCustom1;
private Toolbox.Library.Forms.STLabel stLabel2;
private Toolbox.Library.Forms.STTextBox stTextBox2;
private Toolbox.Library.Forms.STLabel stLabel1;
private Toolbox.Library.Forms.STTextBox stTextBox1;
private System.Windows.Forms.ColumnHeader columnHeader1;
private Toolbox.Library.Forms.PictureBoxCustom pictureBoxCustom1;
private Toolbox.Library.Forms.STComboBox stComboBox2;
private Toolbox.Library.Forms.STComboBox stComboBox1;
private Toolbox.Library.Forms.STLabel stLabel4;
private Toolbox.Library.Forms.STLabel stLabel3;
private BarSlider.BarSlider barSlider3;
private BarSlider.BarSlider barSlider4;
private BarSlider.BarSlider barSlider2;
private BarSlider.BarSlider barSlider1;
private Toolbox.Library.Forms.STPanel stPanel2;
}
}

View file

@ -0,0 +1,146 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Toolbox.Library.Forms;
using Toolbox.Library;
namespace FirstPlugin.Forms
{
public partial class GFLXMaterialEditor : STUserControl
{
private GFLXMaterialData MaterialData;
private ImageList TextureIconList;
public GFLXMaterialEditor()
{
InitializeComponent();
stTabControl1.myBackColor = FormThemes.BaseTheme.FormBackColor;
TextureIconList = new ImageList()
{
ColorDepth = ColorDepth.Depth32Bit,
ImageSize = new Size(22, 22),
};
listViewCustom1.LargeImageList = TextureIconList;
listViewCustom1.SmallImageList = TextureIconList;
stDropDownPanel1.ResetColors();
stDropDownPanel2.ResetColors();
ResetSliders();
}
private void ResetSliders()
{
barSlider1.SetTheme();
barSlider2.SetTheme();
barSlider3.SetTheme();
barSlider4.SetTheme();
barSlider1.Value = 0;
barSlider2.Value = 0;
barSlider3.Value = 0;
barSlider4.Value = 0;
}
public void LoadMaterial(GFLXMaterialData materialData)
{
MaterialData = materialData;
GFLXMaterialParamEditor paramEditor = new GFLXMaterialParamEditor();
paramEditor.Dock = DockStyle.Fill;
paramEditor.LoadParams(materialData);
tabPage2.Controls.Add(paramEditor);
Thread Thread = new Thread((ThreadStart)(() =>
{
foreach (var tex in materialData.TextureMaps)
{
Bitmap image = null;
foreach (var bntx in PluginRuntime.bntxContainers)
{
if (bntx.Textures.ContainsKey(tex.Name)) {
try {
image = bntx.Textures[tex.Name].GetBitmap();
}
catch {
image = Properties.Resources.TextureError;
}
}
}
AddTexture(tex.Name, image);
}
}));
Thread.Start();
}
private void AddTexture(string name, Bitmap image)
{
if (listViewCustom1.InvokeRequired)
{
listViewCustom1.Invoke((MethodInvoker)delegate {
// Running on the UI thread
ListViewItem item = new ListViewItem(name);
listViewCustom1.Items.Add(item);
if (image != null)
{
item.ImageIndex = TextureIconList.Images.Count;
TextureIconList.Images.Add(image);
var dummy = listViewCustom1.Handle;
}
});
}
}
private void listViewCustom1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listViewCustom1.SelectedIndices.Count > 0) {
int index = listViewCustom1.SelectedIndices[0];
var tex = MaterialData.TextureMaps[index];
stTextBox1.Text = tex.Name;
stTextBox2.Text = tex.SamplerName;
foreach (var bntx in PluginRuntime.bntxContainers) {
if (bntx.Textures.ContainsKey(tex.Name))
UpdateTexturePreview(bntx.Textures[tex.Name]);
}
}
else
{
ResetSliders();
pictureBoxCustom1.Image = null;
}
}
private void UpdateTexturePreview(STGenericTexture texture)
{
Thread Thread = new Thread((ThreadStart)(() =>
{
Bitmap image = null;
try {
image = texture.GetBitmap();
}
catch {
image = Properties.Resources.TextureError;
}
pictureBoxCustom1.Invoke((MethodInvoker)delegate {
// Running on the UI thread
pictureBoxCustom1.Image = image;
});
}));
Thread.Start();
}
}
}

View file

@ -0,0 +1,328 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="pictureBoxCustom1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAMAAACJuGjuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEXMzMzNzc3Ozs7Pz8/Q0NDR0dHS
0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm
5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6
+vr7+/v8/Pz9/f3+/v7///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDTbOhAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGXRF
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
</value>
</data>
</root>

View file

@ -0,0 +1,64 @@
namespace FirstPlugin.Forms
{
partial class PokemonLoaderSwShForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.listViewCustom1 = new Toolbox.Library.Forms.ListViewCustom();
this.SuspendLayout();
//
// listViewCustom1
//
this.listViewCustom1.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.listViewCustom1.Dock = System.Windows.Forms.DockStyle.Fill;
this.listViewCustom1.HideSelection = false;
this.listViewCustom1.Location = new System.Drawing.Point(0, 0);
this.listViewCustom1.Name = "listViewCustom1";
this.listViewCustom1.OwnerDraw = true;
this.listViewCustom1.Size = new System.Drawing.Size(800, 450);
this.listViewCustom1.TabIndex = 0;
this.listViewCustom1.UseCompatibleStateImageBehavior = false;
this.listViewCustom1.DoubleClick += new System.EventHandler(this.listViewCustom1_DoubleClick);
//
// PokemonLoaderSwShForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.contentContainer.Controls.Add(this.listViewCustom1);
this.Name = "PokemonLoaderSwShForm";
this.Text = "PokemonLoaderSwSh";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.PokemonLoaderSwShForm_FormClosing);
this.Load += new System.EventHandler(this.PokemonLoaderSwShForm_Load);
this.ResumeLayout(false);
}
#endregion
private Toolbox.Library.Forms.ListViewCustom listViewCustom1;
}
}

View file

@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using Toolbox.Library.Forms;
namespace FirstPlugin.Forms
{
public partial class PokemonLoaderSwShForm : STForm
{
private bool CancelOperation = false;
public string SelectedPokemon = "";
ImageList ImageList;
public PokemonLoaderSwShForm()
{
InitializeComponent();
ImageList = new ImageList()
{
ColorDepth = ColorDepth.Depth32Bit,
ImageSize = new Size(100, 100),
};
listViewCustom1.SmallImageList = ImageList;
listViewCustom1.LargeImageList = ImageList;
}
private void PokemonLoaderSwShForm_Load(object sender, EventArgs e)
{
string gamePath = Runtime.PkSwShGamePath;
if (Directory.Exists(gamePath))
{
string IconPath = $"{gamePath}/bin/appli/icon_pokemon";
if (!Directory.Exists(IconPath))
return;
Thread Thread = new Thread((ThreadStart)(() =>
{
foreach (var file in Directory.GetFiles(IconPath))
{
if (CancelOperation)
break;
if (Utils.GetExtension(file) == ".bntx")
{
var bntx = (BNTX)STFileLoader.OpenFileFormat(file);
string name = bntx.Text.Replace($"poke_icon_", string.Empty);
//All we need is the first 8 characters
name = name.Substring(0, 7);
Bitmap bitmap = null;
try
{
var tex = bntx.Textures.Values.FirstOrDefault();
bitmap = tex.GetBitmap();
}
catch
{
bitmap = Properties.Resources.TextureError;
}
AddTexture($"pm{name}.gfpak", bitmap);
}
}
})); Thread.Start();
}
}
private void AddTexture(string name, Bitmap image)
{
if (listViewCustom1.Disposing || listViewCustom1.IsDisposed) return;
if (listViewCustom1.InvokeRequired)
{
listViewCustom1.Invoke((MethodInvoker)delegate {
// Running on the UI thread
ListViewItem item = new ListViewItem(name);
listViewCustom1.Items.Add(item);
if (image != null)
{
item.ImageIndex = ImageList.Images.Count;
ImageList.Images.Add(image);
var dummy = listViewCustom1.Handle;
}
});
}
}
private void PokemonLoaderSwShForm_FormClosing(object sender, FormClosingEventArgs e) {
CancelOperation = true;
}
private void listViewCustom1_DoubleClick(object sender, EventArgs e) {
if (listViewCustom1.SelectedItems.Count > 0) {
CancelOperation = true;
SelectedPokemon = listViewCustom1.SelectedItems[0].Text;
DialogResult = DialogResult.OK;
}
}
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -104,6 +104,51 @@ namespace FirstPlugin
toolsExt[2] = new STToolStripItem("Breath Of The Wild");
toolsExt[2].DropDownItems.Add(new STToolStripItem("Actor Editor", ActorEditor));
toolsExt[1] = new STToolStripItem("Pokemon Sword/Shield");
toolsExt[1].DropDownItems.Add(new STToolStripItem("Pokemon Loader", PokemonLoaderSwSh));
}
private void PokemonLoaderSwSh(object sender, EventArgs args)
{
if (!System.IO.Directory.Exists(Runtime.PkSwShGamePath))
{
var result = MessageBox.Show("Please set your Pokemon Sword/Shield game path!");
if (result == DialogResult.OK)
{
FolderSelectDialog ofd = new FolderSelectDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
Runtime.PkSwShGamePath = ofd.SelectedPath;
Config.Save();
}
}
}
PokemonLoaderSwShForm form = new PokemonLoaderSwShForm();
if (form.ShowDialog() == DialogResult.OK) {
if (form.SelectedPokemon != string.Empty)
{
string path = $"{Runtime.PkSwShGamePath}/bin/archive/pokemon/{form.SelectedPokemon}";
if (System.IO.File.Exists(path)) {
var file = STFileLoader.OpenFileFormat(path);
var currentForm = Runtime.MainForm.ActiveMdiChild;
if (currentForm != null && currentForm is ObjectEditor &&
Runtime.AddFilesToActiveObjectEditor)
{
ObjectEditor editor = currentForm as ObjectEditor;
editor.AddIArchiveFile(file);
}
else
{
ObjectEditor editor = new ObjectEditor();
editor.AddIArchiveFile(file);
LibraryGUI.CreateMdiWindow(editor);
}
}
}
}
}
private void ActorEditor(object sender, EventArgs args)
@ -348,6 +393,7 @@ namespace FirstPlugin
Formats.Add(typeof(MKAGPDX_Model));
Formats.Add(typeof(GFBMDL));
// Formats.Add(typeof(GFBANM));
Formats.Add(typeof(GFBANMCFG));
Formats.Add(typeof(Turbo.Course_MapCamera_bin));
Formats.Add(typeof(SDF));
Formats.Add(typeof(IStorage));

View file

@ -173,6 +173,9 @@ namespace Toolbox.Library
case "TpGamePath":
Runtime.TpGamePath = node.InnerText;
break;
case "PkSwShGamePath":
Runtime.PkSwShGamePath = node.InnerText;
break;
case "BotwGamePath":
Runtime.BotwGamePath = node.InnerText;
break;
@ -291,6 +294,7 @@ namespace Toolbox.Library
case "TransformPaneChidlren":
bool.TryParse(node.InnerText, out Runtime.LayoutEditor.TransformChidlren);
break;
}
}
@ -470,6 +474,7 @@ namespace Toolbox.Library
PathsNode.AppendChild(createNode(doc, "BotwGamePath", Runtime.BotwGamePath.ToString()));
PathsNode.AppendChild(createNode(doc, "SpecularCubeMapPath", Runtime.PBR.SpecularCubeMapPath.ToString()));
PathsNode.AppendChild(createNode(doc, "DiffuseCubeMapPath", Runtime.PBR.DiffuseCubeMapPath.ToString()));
PathsNode.AppendChild(createNode(doc, "PkSwShGamePath", Runtime.PkSwShGamePath.ToString()));
}
private static void AppendSwitchKeyPathSettings(XmlDocument doc, XmlNode parentNode)

View file

@ -20,14 +20,11 @@ namespace Toolbox.Library
public class ExportSettings
{
public bool SuppressConfirmDialog = false;
public bool OptmizeZeroWeights = true;
public bool UseOldExporter = false;
public bool UseVertexColors = true;
public bool FlipTexCoordsVertical = true;
public bool OnlyExportRiggedBones = false;
public Version FileVersion = new Version();
@ -191,8 +188,39 @@ namespace Toolbox.Library
writer.WriteLibraryImages();
if (skeleton != null) {
//Search for bones with rigging first
List<string> riggedBones = new List<string>();
if (settings.OnlyExportRiggedBones)
{
for (int i = 0; i < Meshes.Count; i++)
{
for (int v = 0; v < Meshes[i].vertices.Count; v++)
{
var vertex = Meshes[i].vertices[v];
for (int j = 0; j < vertex.boneIds.Count; j++)
{
int id = -1;
if (NodeArray != null && NodeArray.Count > vertex.boneIds[j]) {
id = NodeArray[vertex.boneIds[j]];
}
else
id = vertex.boneIds[j];
if (id < skeleton.bones.Count && id != -1)
riggedBones.Add(skeleton.bones[id].Text);
}
}
}
}
foreach (var bone in skeleton.bones)
{
if (settings.OnlyExportRiggedBones && !riggedBones.Contains(bone.Text))
{
Console.WriteLine("Skipping " + bone.Text);
continue;
}
//Set the inverse matrix
var inverse = skeleton.GetBoneTransform(bone).Inverted();
var transform = bone.GetTransform();
@ -322,6 +350,8 @@ namespace Toolbox.Library
if (b > mesh.VertexSkinCount - 1)
continue;
if (vertex.boneWeights.Count > b)
{
if (vertex.boneWeights[b] == 0)

View file

@ -0,0 +1,136 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Threading.Tasks;
using System.Reflection;
using Toolbox.Library.IO;
using OpenTK;
namespace Toolbox.Library.IO.FlatBuffer
{
public class FlatBufferParse
{
public static T ParseFlatTable<T>(FileReader reader)
where T : FlatTable, new()
{
long origin = reader.Position;
int vtableSOffset = reader.ReadInt32();
var dataOffset = reader.ReadOffset(true, typeof(uint));
T section = new T();
using (reader.TemporarySeek(origin - vtableSOffset, System.IO.SeekOrigin.Begin))
{
ushort vTableSize = reader.ReadUInt16();
ushort tableSize = reader.ReadUInt16();
Console.WriteLine($"vTableSize {vTableSize}");
Console.WriteLine($"tableSize {tableSize}");
List<ushort> pointers = new List<ushort>();
uint looper = 4;
while (looper < vTableSize)
{
pointers.Add(reader.ReadUInt16());
looper += 2;
}
section.LayoutPointers = pointers.ToArray();
}
using (reader.TemporarySeek(dataOffset, System.IO.SeekOrigin.Begin))
{
section.Read(reader);
}
return section;
}
}
public class FlatTableParse : Attribute { }
public class FlatTable
{
public ushort LayoutSize { get; set; }
public ushort LayoutStride { get; set; }
public ushort[] LayoutPointers { get; set; }
public void Read(FileReader reader)
{
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());
if (propertyType == typeof(string))
{
var offset = reader.ReadOffset(true, typeof(uint));
reader.SeekBegin(offset);
prop.SetValue(this, reader.ReadString(Syroot.BinaryData.BinaryStringFormat.ByteLengthPrefix));
}
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(FlatTable))
{
var offset = reader.ReadOffset(true, typeof(uint));
reader.SeekBegin(offset);
}
else if (propertyType is IEnumerable<FlatTable>)
{
}
}
}
}
}
}

View file

@ -63,7 +63,7 @@ namespace Syroot.IOExtension
/// representation.
/// </summary>
/// <param name="raw">The raw representation of the internally stored bits.</param>
internal Half(ushort raw)
public Half(ushort raw)
{
Raw = raw;
}

View file

@ -31,6 +31,7 @@ namespace Toolbox.Library
public static bool BotwTable = false;
}
public static string PkSwShGamePath = "";
public static string Mk8GamePath = "";
public static string Mk8dGamePath = "";
public static string SmoGamePath = "";

View file

@ -345,12 +345,21 @@
<DependentUpon>GenericTextureImporterList.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Editors\TextureImport\GenericTextureImporterSettings.cs" />
<Compile Include="Forms\Editors\UV\UVEditorAdvanced.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Forms\Editors\UV\UVEditorAdvanced.Designer.cs">
<DependentUpon>UVEditorAdvanced.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Editors\UV\UVEditorForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Editors\UV\UVEditorForm.Designer.cs">
<DependentUpon>UVEditorForm.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Editors\UV\UVViewport.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Forms\SizeTables\FileTableViewTPHD.cs">
<SubType>UserControl</SubType>
</Compile>
@ -394,6 +403,7 @@
<Compile Include="IO\Extensions\StreamExport.cs" />
<Compile Include="IO\Extensions\UintExtension.cs" />
<Compile Include="IO\FileStreamStorage.cs" />
<Compile Include="IO\FlatBuffer\FlatBufferParse.cs" />
<Compile Include="IO\HSVPixel.cs" />
<Compile Include="IO\IOComoon.cs" />
<Compile Include="IO\Colors\STColor.cs" />
@ -1130,6 +1140,9 @@
<EmbeddedResource Include="Forms\Editors\UV\UVEditor2.resx">
<DependentUpon>UVEditor2.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Editors\UV\UVEditorAdvanced.resx">
<DependentUpon>UVEditorAdvanced.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Editors\UV\UVEditorForm.resx">
<DependentUpon>UVEditorForm.cs</DependentUpon>
</EmbeddedResource>

View file

@ -119,6 +119,8 @@
this.chkTpFileTable = new Toolbox.Library.Forms.STCheckBox();
this.stLabel17 = new Toolbox.Library.Forms.STLabel();
this.chkBotwFileTable = new Toolbox.Library.Forms.STCheckBox();
this.stLabel18 = new Toolbox.Library.Forms.STLabel();
this.pathPokemonSwShTB = new Toolbox.Library.Forms.STTextBox();
this.contentContainer.SuspendLayout();
this.panel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.cameraMaxSpeedUD)).BeginInit();
@ -1027,6 +1029,8 @@
//
// tabPage3
//
this.tabPage3.Controls.Add(this.stLabel18);
this.tabPage3.Controls.Add(this.pathPokemonSwShTB);
this.tabPage3.Controls.Add(this.stLabel13);
this.tabPage3.Controls.Add(this.botwGamePathTB);
this.tabPage3.Controls.Add(this.stLabel14);
@ -1058,7 +1062,7 @@
//
this.botwGamePathTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.botwGamePathTB.ContextMenuStrip = this.stContextMenuStrip1;
this.botwGamePathTB.Location = new System.Drawing.Point(112, 120);
this.botwGamePathTB.Location = new System.Drawing.Point(128, 120);
this.botwGamePathTB.Name = "botwGamePathTB";
this.botwGamePathTB.Size = new System.Drawing.Size(258, 20);
this.botwGamePathTB.TabIndex = 8;
@ -1091,7 +1095,7 @@
//
this.tpGamePathTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.tpGamePathTB.ContextMenuStrip = this.stContextMenuStrip1;
this.tpGamePathTB.Location = new System.Drawing.Point(112, 94);
this.tpGamePathTB.Location = new System.Drawing.Point(128, 94);
this.tpGamePathTB.Name = "tpGamePathTB";
this.tpGamePathTB.Size = new System.Drawing.Size(258, 20);
this.tpGamePathTB.TabIndex = 6;
@ -1110,7 +1114,7 @@
//
this.SMOPathTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.SMOPathTB.ContextMenuStrip = this.stContextMenuStrip1;
this.SMOPathTB.Location = new System.Drawing.Point(112, 68);
this.SMOPathTB.Location = new System.Drawing.Point(128, 68);
this.SMOPathTB.Name = "SMOPathTB";
this.SMOPathTB.Size = new System.Drawing.Size(258, 20);
this.SMOPathTB.TabIndex = 4;
@ -1129,7 +1133,7 @@
//
this.mk8DPathTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.mk8DPathTB.ContextMenuStrip = this.stContextMenuStrip1;
this.mk8DPathTB.Location = new System.Drawing.Point(112, 42);
this.mk8DPathTB.Location = new System.Drawing.Point(128, 42);
this.mk8DPathTB.Name = "mk8DPathTB";
this.mk8DPathTB.Size = new System.Drawing.Size(258, 20);
this.mk8DPathTB.TabIndex = 2;
@ -1149,7 +1153,7 @@
this.mk8PathTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.mk8PathTB.ContextMenuStrip = this.stContextMenuStrip1;
this.mk8PathTB.Cursor = System.Windows.Forms.Cursors.Default;
this.mk8PathTB.Location = new System.Drawing.Point(112, 16);
this.mk8PathTB.Location = new System.Drawing.Point(128, 16);
this.mk8PathTB.Name = "mk8PathTB";
this.mk8PathTB.Size = new System.Drawing.Size(258, 20);
this.mk8PathTB.TabIndex = 0;
@ -1280,6 +1284,26 @@
this.chkBotwFileTable.UseVisualStyleBackColor = true;
this.chkBotwFileTable.CheckedChanged += new System.EventHandler(this.chkBotwFileTable_CheckedChanged);
//
// stLabel18
//
this.stLabel18.AutoSize = true;
this.stLabel18.Location = new System.Drawing.Point(6, 148);
this.stLabel18.Name = "stLabel18";
this.stLabel18.Size = new System.Drawing.Size(119, 13);
this.stLabel18.TabIndex = 11;
this.stLabel18.Text = "Pokemon Sword/Shield";
//
// pathPokemonSwShTB
//
this.pathPokemonSwShTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.pathPokemonSwShTB.ContextMenuStrip = this.stContextMenuStrip1;
this.pathPokemonSwShTB.Location = new System.Drawing.Point(128, 146);
this.pathPokemonSwShTB.Name = "pathPokemonSwShTB";
this.pathPokemonSwShTB.Size = new System.Drawing.Size(258, 20);
this.pathPokemonSwShTB.TabIndex = 10;
this.pathPokemonSwShTB.Click += new System.EventHandler(this.pathPokemonSwShTB_Click);
this.pathPokemonSwShTB.TextChanged += new System.EventHandler(this.pathPokemonSwShTB_TextChanged);
//
// Settings
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -1416,5 +1440,7 @@
private Toolbox.Library.Forms.STCheckBox chkBotwFileTable;
private Toolbox.Library.Forms.STCheckBox chkFrameCamera;
private Toolbox.Library.Forms.STCheckBox chkAlwaysCompressOnSave;
private Library.Forms.STLabel stLabel18;
private Library.Forms.STTextBox pathPokemonSwShTB;
}
}

View file

@ -575,6 +575,10 @@ namespace Toolbox
botwGamePathTB.Text = "";
Runtime.BotwGamePath = "";
break;
case "pathPokemonSwShTB":
pathPokemonSwShTB.Text = "";
Runtime.PkSwShGamePath = "";
break;
}
}
}
@ -661,5 +665,31 @@ namespace Toolbox
private void chkAlwaysCompressOnSave_CheckedChanged(object sender, EventArgs e) {
Runtime.AlwaysCompressOnSave = chkAlwaysCompressOnSave.Checked;
}
private void pathPokemonSwShTB_TextChanged(object sender, EventArgs e)
{
}
private void pathPokemonSwShTB_Click(object sender, EventArgs e) {
FolderSelectDialog sfd = new FolderSelectDialog();
if (sfd.ShowDialog() == DialogResult.OK)
{
if (!IsValidPokemonSwShDirectory(sfd.SelectedPath))
throw new Exception("Invalid path choosen. You need Bin/appli/icon_pokemon atleast for pokemon icons");
pathPokemonSwShTB.Text = sfd.SelectedPath;
Runtime.PkSwShGamePath = pathPokemonSwShTB.Text;
}
}
private bool IsValidPokemonSwShDirectory(string GamePath)
{
//Search for pokemon icons
string RstbPath = System.IO.Path.Combine($"{GamePath}",
"Bin", "appli", "icon_pokemon", "poke_icon_0000_00s_n.bntx");
return System.IO.File.Exists(RstbPath);
}
}
}

Binary file not shown.

BIN
Toolbox/Lib/FlatBuffers.dll Normal file

Binary file not shown.

BIN
Toolbox/Lib/FlatBuffers.pdb Normal file

Binary file not shown.

View file

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -134,7 +134,6 @@ void main()
ivec4 index = ivec4(vBone);
vec4 objPos = vec4(vPosition.xyz, 1.0);
if (vBone.x != -1.0)
objPos = skin(objPos.xyz, index);

View file

@ -63,6 +63,17 @@ uniform int GreenChannel;
uniform int BlueChannel;
uniform int AlphaChannel;
//Parameters
uniform float ColorUVScaleU;
uniform float ColorUVScaleV;
uniform float ColorUVTranslateU;
uniform float ColorUVTranslateV;
uniform float NormalMapUVScaleU;
uniform float NormalMapUVScaleV;
uniform float NormalMapUVTranslateU;
uniform float NormalMapUVTranslateV;
uniform samplerCube irradianceMap;
uniform samplerCube specularIbl;
uniform sampler2D brdfLUT;
@ -127,7 +138,11 @@ void main()
vec3 albedo = vec3(1);
if (HasDiffuse == 1)
{
vec4 DiffuseTex = pow(texture(DiffuseMap, f_texcoord0).rgba, vec4(gamma));
vec2 colorUV = f_texcoord0;
colorUV.x *= ColorUVScaleU + ColorUVTranslateU;
colorUV.y *= ColorUVScaleV + ColorUVTranslateV;
vec4 DiffuseTex = pow(texture(DiffuseMap, colorUV).rgba, vec4(gamma));
//Comp Selectors
albedo.r = GetComponent(RedChannel, DiffuseTex);
@ -248,8 +263,12 @@ void main()
}
else if (renderType == 3) //DiffuseColor
{
vec2 colorUV = displayTexCoord;
colorUV.x *= ColorUVScaleU + ColorUVTranslateU;
colorUV.y *= ColorUVScaleV + ColorUVTranslateV;
//Comp Selectors
vec4 diffuseMapColor = vec4(texture(DiffuseMap, displayTexCoord).rgb, 1);
vec4 diffuseMapColor = vec4(texture(DiffuseMap, colorUV).rgb, 1);
diffuseMapColor.r = GetComponent(RedChannel, diffuseMapColor);
diffuseMapColor.g = GetComponent(GreenChannel, diffuseMapColor);
diffuseMapColor.b = GetComponent(BlueChannel, diffuseMapColor);
@ -257,7 +276,12 @@ void main()
fragColor = vec4(diffuseMapColor.rgb, 1);
}
else if (renderType == 4) //Display Normal
{
if (HasNormalMap == 1)
fragColor.rgb = texture(NormalMap, displayTexCoord).rgb;
else
fragColor.rgb = vec3(0);
}
else if (renderType == 5) // vertexColor
fragColor = vertexColor;
else if (renderType == 6) //Display Ambient Occlusion

View file

@ -45,11 +45,6 @@ uniform int NoSkinning;
uniform int RigidSkinning;
uniform int SingleBoneIndex;
//Parameters
uniform float ColorUVScaleU;
uniform float ColorUVScaleV;
uniform float ColorUVTranslateU;
uniform float ColorUVTranslateV;
vec4 skin(vec3 pos, ivec4 index)
@ -130,9 +125,6 @@ void main()
f_texcoord2 = vUV2;
tangent = vTangent;
f_texcoord0.x *= ColorUVScaleU + ColorUVTranslateU;
f_texcoord0.y *= ColorUVScaleV + ColorUVTranslateV;
gl_Position = position;
objectPosition = position.xyz;

View file

@ -188,6 +188,8 @@ void main()
fragColor = vec4(diffuseMapColor.rgb, 1);
}
else if (renderType == 4) //Display Normal
fragColor.rgb = texture(NormalMap, displayTexCoord).rgb;
else if (renderType == 5) // vertexColor
fragColor = vertexColor;
else if (renderType == 6) //Display Ambient Occlusion

View file

@ -403,6 +403,9 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\FirstPlugin.Plg.dll" />
<Content Include="Lib\FlatBuffers.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\GL_Core.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>