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

Update grezzo formats to support skeleton animations

This commit is contained in:
KillzXGaming 2019-11-26 17:05:37 -05:00
parent 1bb7c44f20
commit 8f81c561f3
5 changed files with 436 additions and 77 deletions

View File

@ -10,6 +10,7 @@ using Toolbox.Library.IO;
using Toolbox.Library.Rendering;
using Grezzo.CmbEnums;
using OpenTK.Graphics.OpenGL;
using FirstPlugin.Forms;
namespace FirstPlugin
{
@ -41,20 +42,6 @@ namespace FirstPlugin
}
}
Viewport viewport
{
get
{
var editor = LibraryGUI.GetObjectEditor();
return editor.GetViewport();
}
set
{
var editor = LibraryGUI.GetObjectEditor();
editor.LoadViewport(value);
}
}
public ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
@ -102,25 +89,23 @@ namespace FirstPlugin
bool DrawablesLoaded = false;
public override void OnClick(TreeView treeView)
{
if (Runtime.UseOpenGL)
ViewportEditor editor = (ViewportEditor)LibraryGUI.GetActiveContent(typeof(ViewportEditor));
bool HasModels = DrawableContainer.Drawables.Count > 0;
if (editor == null)
{
if (viewport == null)
{
viewport = new Viewport(ObjectEditor.GetDrawableContainers());
viewport.Dock = DockStyle.Fill;
}
if (!DrawablesLoaded)
{
ObjectEditor.AddContainer(DrawableContainer);
DrawablesLoaded = true;
}
viewport.ReloadDrawables(DrawableContainer);
LibraryGUI.LoadEditor(viewport);
viewport.Text = Text;
editor = new ViewportEditor(HasModels);
editor.Dock = DockStyle.Fill;
LibraryGUI.LoadEditor(editor);
}
if (!DrawablesLoaded)
{
ObjectEditor.AddContainer(DrawableContainer);
DrawablesLoaded = true;
}
if (Runtime.UseOpenGL)
editor.LoadViewport(DrawableContainer);
}
public CMB_Renderer Renderer;
@ -129,7 +114,7 @@ namespace FirstPlugin
public Header header;
STTextureFolder texFolder;
STSkeleton Skeleton;
public STSkeleton Skeleton;
public void Load(System.IO.Stream stream)
{
@ -137,11 +122,14 @@ namespace FirstPlugin
Renderer = new CMB_Renderer();
DrawableContainer.Drawables.Add(Renderer);
Skeleton = new STSkeleton();
//These models/skeletons come out massive so scale them with an overridden scale
Skeleton.PreviewScale = Renderer.PreviewScale;
Skeleton.BonePointScale = 40;
Renderer.Skeleton = Skeleton;
DrawableContainer.Drawables.Add(Skeleton);
header = new Header();
@ -285,6 +273,13 @@ namespace FirstPlugin
var shape = header.SectionData.SkeletalMeshChunk.ShapeChunk.SeperateShapes[(int)mesh.SepdIndex];
genericMesh.Shape = shape;
List<ushort> SkinnedBoneTable = new List<ushort>();
foreach (var prim in shape.Primatives)
{
if (prim.BoneIndexTable != null)
SkinnedBoneTable.AddRange(prim.BoneIndexTable);
}
//Now load the vertex and face data
if (shape.Position.VertexData != null)
{
@ -345,8 +340,8 @@ namespace FirstPlugin
}
}
bool HasSkinning = shape.Primatives[0].SkinningMode != SkinningMode.SINGLE_BONE
&& shape.BoneIndices.Type == CmbDataType.UByte; //Noclip checks the type for ubyte so do the same
bool HasSkinning = shape.Primatives[0].SkinningMode != SkinningMode.SINGLE_BONE
&& shape.BoneIndices.Type == CmbDataType.UByte; //Noclip checks the type for ubyte so do the same
bool HasWeights = shape.Primatives[0].SkinningMode == SkinningMode.SMOOTH_SKINNING;
@ -355,8 +350,12 @@ namespace FirstPlugin
var BoneIndices = shape.BoneIndices.VertexData[v];
for (int j = 0; j < shape.boneDimension; j++)
{
// ushort index = shape.Primatives[0].BoneIndexTable[(uint)BoneIndices[j]];
vert.boneIds.Add((int)BoneIndices[j]);
if (BoneIndices[j] < SkinnedBoneTable.Count)
vert.boneIds.Add((int)SkinnedBoneTable[(int)BoneIndices[j]]);
// Console.WriteLine("boneIds " + BoneIndices[j]);
// ushort index = shape.Primatives[0].BoneIndexTable[(uint)BoneIndices[j]];
// vert.boneIds.Add((int)BoneIndices[j]);
}
}
if (shape.BoneWeights.VertexData != null && HasWeights && shape.BoneWeights.VertexData.Length > v)
@ -364,6 +363,7 @@ namespace FirstPlugin
var BoneWeights = shape.BoneWeights.VertexData[v];
for (int j = 0; j < shape.boneDimension; j++)
{
Console.WriteLine("weight " + BoneWeights[j]);
vert.boneWeights.Add(BoneWeights[j]);
}
}
@ -694,8 +694,6 @@ namespace FirstPlugin
int StrideSize = CalculateStrideSize(VertexAttribute.Type, elementCount);
int VertexCount = (int)Slice.Size / StrideSize;
Console.WriteLine($"{VertexAttribute.GetType()} {VertexAttribute.Type} {elementCount} {StrideSize} {VertexCount}");
VertexAttribute.VertexData = new Syroot.Maths.Vector4F[VertexCount];
for (int v = 0; v < VertexCount; v++)
{

View File

@ -8,10 +8,11 @@ using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using Toolbox.Library.Animations;
using OpenTK;
namespace FirstPlugin
{
public class CSAB : STSkeletonAnimation, IFileFormat
public class CSAB : TreeNodeFile, IFileFormat, IAnimationContainer
{
public FileType FileType { get; set; } = FileType.Animation;
@ -39,15 +40,31 @@ namespace FirstPlugin
}
}
public STAnimation AnimationController => header;
public override void OnClick(TreeView treeview)
{
}
public Header header;
public void Load(System.IO.Stream stream)
{
header = new Header();
header.Read(new FileReader(stream));
try
{
header = new Header();
header.Read(new FileReader(stream));
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
this.Text = FileName;
foreach (var bone in header.Nodes)
AnimGroups.Add(bone);
header.AnimGroups.Add(bone);
}
public void Unload()
@ -72,12 +89,95 @@ namespace FirstPlugin
HERMITE = 0x02,
};
public class Header
public class Header : STSkeletonAnimation
{
public GameVersion Version;
public List<AnimationNode> Nodes = new List<AnimationNode>();
public override STSkeleton GetActiveSkeleton()
{
var containers = Toolbox.Library.Forms.ObjectEditor.GetDrawableContainers();
foreach (var container in containers) {
foreach (var draw in container.Drawables)
if (draw is STSkeleton)
return (STSkeleton)draw;
}
return base.GetActiveSkeleton();
}
public override void NextFrame()
{
if (Frame > FrameCount) return;
var skeleton = GetActiveSkeleton();
if (Frame == 0)
skeleton.reset();
bool Updated = false; // no need to update skeleton of animations that didn't change
foreach (var node in Nodes)
{
Console.WriteLine($"node.BoneIndex {node.BoneIndex}");
if (node.BoneIndex < skeleton.bones.Count) {
var b = skeleton.bones[node.BoneIndex];
if (b == null) continue;
Updated = true;
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);
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;
if (node.RotationX.HasKeys || node.RotationY.HasKeys || node.RotationZ.HasKeys)
{
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];
b.rot = EulerToQuat(z, y, x);
}
}
}
if (Updated) {
skeleton.update();
}
}
public static Quaternion EulerToQuat(float z, float y, float x)
{
{
Quaternion xRotation = Quaternion.FromAxisAngle(Vector3.UnitX, x);
Quaternion yRotation = Quaternion.FromAxisAngle(Vector3.UnitY, y);
Quaternion zRotation = Quaternion.FromAxisAngle(Vector3.UnitZ, z);
Quaternion q = (zRotation * yRotation * xRotation);
if (q.W < 0)
q *= -1;
//return xRotation * yRotation * zRotation;
return q;
}
}
public void Read(FileReader reader)
{
reader.SetByteOrder(false);
@ -106,17 +206,43 @@ namespace FirstPlugin
uint unknown6 = reader.ReadUInt32();//0x00
uint unknown7 = reader.ReadUInt32();//0x00
uint unknown8 = reader.ReadUInt32();//0x00
reader.SeekBegin(0x28);
if (Version >= GameVersion.MM3D)
reader.SeekBegin(0x34);
uint duration = reader.ReadUInt32();
reader.SeekBegin(0x30);
if (Version >= GameVersion.MM3D)
reader.SeekBegin(0x3C);
uint nodeCount = reader.ReadUInt32();
uint boneCount = reader.ReadUInt32();
if (nodeCount != boneCount) throw new Exception("Unexpected bone and node count!");
FrameCount = duration;
Console.WriteLine($"duration {duration}");
Console.WriteLine($"boneCount {boneCount}");
uint nodeSize = 0x18;
reader.SeekBegin(0x38);
if (Version >= GameVersion.MM3D)
{
nodeSize = 0x24;
reader.SeekBegin(0x44);
}
ushort[] BoneIndexTable = reader.ReadUInt16s((int)boneCount);
reader.Align(4);
uint[] nodeOffsets = reader.ReadUInt32s((int)nodeCount);
for (int i = 0; i < nodeCount; i++)
{
reader.SeekBegin(nodeOffsets[i] + 0x18);
reader.SeekBegin(nodeOffsets[i] + nodeSize);
AnimationNode node = new AnimationNode();
node.Read(reader, Version);
Nodes.Add(node);
@ -177,7 +303,7 @@ namespace FirstPlugin
long pos = reader.Position;
uint Offset = reader.ReadUInt16();
if (Offset == 0) return null;
if (Offset == 0) return new AnimTrack();
reader.SeekBegin(startPos + Offset);
var track = new AnimTrack(reader, version);
@ -191,7 +317,9 @@ namespace FirstPlugin
public List<LinearKeyFrame> KeyFramesLinear = new List<LinearKeyFrame>();
public List<HermiteKeyFrame> KeyFramesHermite = new List<HermiteKeyFrame>();
public uint InterpolationType;
public uint TrackInterpolationType;
public AnimTrack() { }
public AnimTrack(FileReader reader, GameVersion version)
{
@ -199,19 +327,22 @@ namespace FirstPlugin
if (version >= GameVersion.MM3D)
{
InterpolationType = reader.ReadByte();
reader.ReadByte(); //unk
TrackInterpolationType = reader.ReadByte();
numKeyFrames = reader.ReadUInt16();
}
else
{
InterpolationType = reader.ReadUInt32();
TrackInterpolationType = reader.ReadUInt32();
numKeyFrames = reader.ReadUInt32();
uint unknown = reader.ReadUInt32();
uint endFrame = reader.ReadUInt32();
}
if (InterpolationType == (uint)AnimationTrackType.LINEAR)
if (TrackInterpolationType == (uint)AnimationTrackType.LINEAR)
{
InterpolationType = STInterpoaltionType.Linear;
if (version >= GameVersion.MM3D)
{
float scale = reader.ReadSingle();
@ -219,33 +350,48 @@ namespace FirstPlugin
for (uint i = 0; i < numKeyFrames; i++)
{
LinearKeyFrame keyFrame = new LinearKeyFrame();
keyFrame.Time = i;
keyFrame.Value = reader.ReadUInt16() * scale - bias;
KeyFramesLinear.Add(keyFrame);
float Value = reader.ReadUInt16() * scale - bias;
KeyFrames.Add(new STKeyFrame()
{
Frame = i,
Value = Value
});
}
}
else
{
for (int i = 0; i < numKeyFrames; i++)
{
LinearKeyFrame keyFrame = new LinearKeyFrame();
keyFrame.Time = reader.ReadUInt32();
keyFrame.Value = reader.ReadSingle();
KeyFramesLinear.Add(keyFrame);
uint Time = reader.ReadUInt32();
float Value = reader.ReadSingle();
KeyFrames.Add(new STKeyFrame()
{
Frame = Time,
Value = Value
});
}
}
}
else if (InterpolationType == (uint)AnimationTrackType.HERMITE)
else if (TrackInterpolationType == (uint)AnimationTrackType.HERMITE)
{
InterpolationType = STInterpoaltionType.Hermite;
for (int i = 0; i < numKeyFrames; i++)
{
HermiteKeyFrame keyFrame = new HermiteKeyFrame();
keyFrame.Time = reader.ReadUInt32();
keyFrame.Value = reader.ReadSingle();
keyFrame.TangentIn = reader.ReadSingle();
keyFrame.TangentOut = reader.ReadSingle();
KeyFramesHermite.Add(keyFrame);
uint Time = reader.ReadUInt32();
float Value = reader.ReadSingle();
float TangentIn = reader.ReadSingle();
float TangentOut = reader.ReadSingle();
KeyFrames.Add(new STHermiteKeyFrame()
{
Frame = Time,
TangentIn = TangentIn,
TangentOut = TangentOut,
Value = Value,
});
}
}
else

View File

@ -151,6 +151,7 @@ namespace FirstPlugin
var info = (SystemGarFileInfo)GarFileInfos[i];
files.Add(new FileEntry()
{
OpenFileFormatOnLoad = info.ext == "csab",
FileName = $"{info.Name}.{info.ext}",
FileData = reader.getSection(info.FileOffset, info.FileSize)
});
@ -187,6 +188,8 @@ namespace FirstPlugin
{
files.Add(new FileEntry()
{
OpenFileFormatOnLoad = ((ZarFileInfo)GarFileInfos[i]).FileName.Contains("csab"),
FileName = ((ZarFileInfo)GarFileInfos[i]).FileName,
FileData = reader.getSection(Offsets[i], ((ZarFileInfo)GarFileInfos[i]).FileSize)
});
@ -195,6 +198,8 @@ namespace FirstPlugin
{
files.Add(new FileEntry()
{
OpenFileFormatOnLoad = ((GarFileInfo)GarFileInfos[i]).FileName.Contains("csab"),
FileName = ((GarFileInfo)GarFileInfos[i]).FileName,
FileData = reader.getSection(Offsets[i], ((GarFileInfo)GarFileInfos[i]).FileSize)
});

View File

@ -0,0 +1,196 @@
// <auto-generated>
// automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>
namespace FlatBuffers.Gfbpmcatalog
{
using global::System;
using global::FlatBuffers;
public struct Catalog : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static Catalog GetRootAsCatalog(ByteBuffer _bb) { return GetRootAsCatalog(_bb, new Catalog()); }
public static Catalog GetRootAsCatalog(ByteBuffer _bb, Catalog 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 Catalog __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public Model? Context(int j) { int o = __p.__offset(4); return o != 0 ? (Model?)(new Model()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
public int ContextLength { get { int o = __p.__offset(4); return o != 0 ? __p.__vector_len(o) : 0; } }
public static Offset<Catalog> CreateCatalog(FlatBufferBuilder builder,
VectorOffset ContextOffset = default(VectorOffset))
{
builder.StartObject(1);
Catalog.AddContext(builder, ContextOffset);
return Catalog.EndCatalog(builder);
}
public static void StartCatalog(FlatBufferBuilder builder) { builder.StartObject(1); }
public static void AddContext(FlatBufferBuilder builder, VectorOffset ContextOffset) { builder.AddOffset(0, ContextOffset.Value, 0); }
public static VectorOffset CreateContextVector(FlatBufferBuilder builder, Offset<Model>[] 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 CreateContextVectorBlock(FlatBufferBuilder builder, Offset<Model>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
public static void StartContextVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
public static Offset<Catalog> EndCatalog(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<Catalog>(o);
}
public static void FinishCatalogBuffer(FlatBufferBuilder builder, Offset<Catalog> offset) { builder.Finish(offset.Value); }
public static void FinishSizePrefixedCatalogBuffer(FlatBufferBuilder builder, Offset<Catalog> offset) { builder.FinishSizePrefixed(offset.Value); }
};
public struct UnkTable : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static UnkTable GetRootAsUnkTable(ByteBuffer _bb) { return GetRootAsUnkTable(_bb, new UnkTable()); }
public static UnkTable GetRootAsUnkTable(ByteBuffer _bb, UnkTable 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 UnkTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public ushort Unk { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetUshort(o + __p.bb_pos) : (ushort)0; } }
public static Offset<UnkTable> CreateUnkTable(FlatBufferBuilder builder,
ushort unk = 0)
{
builder.StartObject(1);
UnkTable.AddUnk(builder, unk);
return UnkTable.EndUnkTable(builder);
}
public static void StartUnkTable(FlatBufferBuilder builder) { builder.StartObject(1); }
public static void AddUnk(FlatBufferBuilder builder, ushort unk) { builder.AddUshort(0, unk, 0); }
public static Offset<UnkTable> EndUnkTable(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<UnkTable>(o);
}
};
public struct Model : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static Model GetRootAsModel(ByteBuffer _bb) { return GetRootAsModel(_bb, new Model()); }
public static Model GetRootAsModel(ByteBuffer _bb, Model 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 Model __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public ushort PokemonID { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetUshort(o + __p.bb_pos) : (ushort)0; } }
public ushort IsSpecial { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetUshort(o + __p.bb_pos) : (ushort)0; } }
public sbyte IsFemale { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetSbyte(o + __p.bb_pos) : (sbyte)0; } }
public sbyte IsRare { get { int o = __p.__offset(10); return o != 0 ? __p.bb.GetSbyte(o + __p.bb_pos) : (sbyte)0; } }
public string ModelPath { get { int o = __p.__offset(12); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
#if ENABLE_SPAN_T
public Span<byte> GetModelPathBytes() { return __p.__vector_as_span(12); }
#else
public ArraySegment<byte>? GetModelPathBytes() { return __p.__vector_as_arraysegment(12); }
#endif
public byte[] GetModelPathArray() { return __p.__vector_as_array<byte>(12); }
public string ConfigPath { get { int o = __p.__offset(14); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
#if ENABLE_SPAN_T
public Span<byte> GetConfigPathBytes() { return __p.__vector_as_span(14); }
#else
public ArraySegment<byte>? GetConfigPathBytes() { return __p.__vector_as_arraysegment(14); }
#endif
public byte[] GetConfigPathArray() { return __p.__vector_as_array<byte>(14); }
public string PackageFile { get { int o = __p.__offset(16); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
#if ENABLE_SPAN_T
public Span<byte> GetPackageFileBytes() { return __p.__vector_as_span(16); }
#else
public ArraySegment<byte>? GetPackageFileBytes() { return __p.__vector_as_arraysegment(16); }
#endif
public byte[] GetPackageFileArray() { return __p.__vector_as_array<byte>(16); }
public Animation? Animations(int j) { int o = __p.__offset(18); return o != 0 ? (Animation?)(new Animation()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
public int AnimationsLength { get { int o = __p.__offset(18); return o != 0 ? __p.__vector_len(o) : 0; } }
public static Offset<Model> CreateModel(FlatBufferBuilder builder,
ushort pokemonID = 0,
ushort isSpecial = 0,
sbyte isFemale = 0,
sbyte isRare = 0,
StringOffset modelPathOffset = default(StringOffset),
StringOffset configPathOffset = default(StringOffset),
StringOffset packageFileOffset = default(StringOffset),
VectorOffset animationsOffset = default(VectorOffset))
{
builder.StartObject(8);
Model.AddAnimations(builder, animationsOffset);
Model.AddPackageFile(builder, packageFileOffset);
Model.AddConfigPath(builder, configPathOffset);
Model.AddModelPath(builder, modelPathOffset);
Model.AddIsSpecial(builder, isSpecial);
Model.AddPokemonID(builder, pokemonID);
Model.AddIsRare(builder, isRare);
Model.AddIsFemale(builder, isFemale);
return Model.EndModel(builder);
}
public static void StartModel(FlatBufferBuilder builder) { builder.StartObject(8); }
public static void AddPokemonID(FlatBufferBuilder builder, ushort pokemonID) { builder.AddUshort(0, pokemonID, 0); }
public static void AddIsSpecial(FlatBufferBuilder builder, ushort isSpecial) { builder.AddUshort(1, isSpecial, 0); }
public static void AddIsFemale(FlatBufferBuilder builder, sbyte isFemale) { builder.AddSbyte(2, isFemale, 0); }
public static void AddIsRare(FlatBufferBuilder builder, sbyte isRare) { builder.AddSbyte(3, isRare, 0); }
public static void AddModelPath(FlatBufferBuilder builder, StringOffset modelPathOffset) { builder.AddOffset(4, modelPathOffset.Value, 0); }
public static void AddConfigPath(FlatBufferBuilder builder, StringOffset configPathOffset) { builder.AddOffset(5, configPathOffset.Value, 0); }
public static void AddPackageFile(FlatBufferBuilder builder, StringOffset packageFileOffset) { builder.AddOffset(6, packageFileOffset.Value, 0); }
public static void AddAnimations(FlatBufferBuilder builder, VectorOffset animationsOffset) { builder.AddOffset(7, animationsOffset.Value, 0); }
public static VectorOffset CreateAnimationsVector(FlatBufferBuilder builder, Offset<Animation>[] 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<Animation>[] 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<Model> EndModel(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<Model>(o);
}
};
public struct Animation : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static Animation GetRootAsAnimation(ByteBuffer _bb) { return GetRootAsAnimation(_bb, new Animation()); }
public static Animation GetRootAsAnimation(ByteBuffer _bb, Animation 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 Animation __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public string Type { get { int o = __p.__offset(4); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
#if ENABLE_SPAN_T
public Span<byte> GetTypeBytes() { return __p.__vector_as_span(4); }
#else
public ArraySegment<byte>? GetTypeBytes() { return __p.__vector_as_arraysegment(4); }
#endif
public byte[] GetTypeArray() { return __p.__vector_as_array<byte>(4); }
public string ConfigPath { get { int o = __p.__offset(6); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
#if ENABLE_SPAN_T
public Span<byte> GetConfigPathBytes() { return __p.__vector_as_span(6); }
#else
public ArraySegment<byte>? GetConfigPathBytes() { return __p.__vector_as_arraysegment(6); }
#endif
public byte[] GetConfigPathArray() { return __p.__vector_as_array<byte>(6); }
public static Offset<Animation> CreateAnimation(FlatBufferBuilder builder,
StringOffset typeOffset = default(StringOffset),
StringOffset configPathOffset = default(StringOffset))
{
builder.StartObject(2);
Animation.AddConfigPath(builder, configPathOffset);
Animation.AddType(builder, typeOffset);
return Animation.EndAnimation(builder);
}
public static void StartAnimation(FlatBufferBuilder builder) { builder.StartObject(2); }
public static void AddType(FlatBufferBuilder builder, StringOffset typeOffset) { builder.AddOffset(0, typeOffset.Value, 0); }
public static void AddConfigPath(FlatBufferBuilder builder, StringOffset configPathOffset) { builder.AddOffset(1, configPathOffset.Value, 0); }
public static Offset<Animation> EndAnimation(FlatBufferBuilder builder)
{
int o = builder.EndObject();
return new Offset<Animation>(o);
}
};
}

View File

@ -337,14 +337,22 @@ namespace Toolbox.Library.Forms
GetArchiveMenus(e.Node, (ArchiveFileInfo)e.Node.Tag);
}
if (e.Node is IContextMenuNode)
{
bool IsRoot = e.Node.Parent == null;
bool HasChildren = e.Node.Nodes.Count > 0;
bool IsRoot = e.Node.Parent == null;
bool HasChildren = e.Node.Nodes.Count > 0;
IContextMenuNode node = null;
if (e.Node is IContextMenuNode) {
node = (IContextMenuNode)e.Node;
}
else if (e.Node.Tag != null && e.Node.Tag is IContextMenuNode) {
node = (IContextMenuNode)e.Node.Tag;
}
if (node != null)
{
if (IsRoot)
{
foreach (var item in ((IContextMenuNode)e.Node).GetContextMenuItems())
foreach (var item in node.GetContextMenuItems())
{
if (item.Text != "Delete" && item.Text != "Remove")
treeNodeContextMenu.Items.Add(item);
@ -353,12 +361,12 @@ namespace Toolbox.Library.Forms
}
else
{
treeNodeContextMenu.Items.AddRange(((IContextMenuNode)e.Node).GetContextMenuItems());
treeNodeContextMenu.Items.AddRange(node.GetContextMenuItems());
}
bool HasCollpase = false;
bool HasExpand = false;
foreach (var item in ((IContextMenuNode)e.Node).GetContextMenuItems())
foreach (var item in node.GetContextMenuItems())
{
if (item.Text == "Collapse All")
HasCollpase = true;
@ -378,8 +386,7 @@ namespace Toolbox.Library.Forms
treeViewCustom1.SelectedNode = e.Node;
SuppressAfterSelectEvent = false;
}
if (treeNodeContextMenu.Items.Count > 0)
if (treeNodeContextMenu.Items.Count > 0)
treeNodeContextMenu.Show(Cursor.Position);
}
else
@ -829,10 +836,17 @@ namespace Toolbox.Library.Forms
private void treeViewCustom1_KeyPress(object sender, KeyEventArgs e)
{
if (treeViewCustom1.SelectedNode != null && treeViewCustom1.SelectedNode is IContextMenuNode)
{
IContextMenuNode node = (IContextMenuNode)treeViewCustom1.SelectedNode;
if (treeViewCustom1.SelectedNode == null) return;
IContextMenuNode node = null;
if (treeViewCustom1.SelectedNode is IContextMenuNode) {
node = (IContextMenuNode)treeViewCustom1.SelectedNode;
}
else if (treeViewCustom1.SelectedNode.Tag != null && treeViewCustom1.SelectedNode.Tag is IContextMenuNode) {
node = (IContextMenuNode)treeViewCustom1.SelectedNode.Tag;
}
if (node != null) {
var Items = node.GetContextMenuItems();
foreach (ToolStripItem toolstrip in Items)
{