Push support for V10 BFRES saving, TXTG load/saving, Anim fixes, and more.
This commit is contained in:
parent
15e6c1c7fd
commit
2c75de1f1c
Binary file not shown.
@ -7,6 +7,8 @@ using Toolbox;
|
||||
using System.Windows.Forms;
|
||||
using Toolbox.Library;
|
||||
using Toolbox.Library.IO;
|
||||
using System.IO;
|
||||
using VGAudio.Utilities;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
@ -80,9 +82,24 @@ namespace FirstPlugin
|
||||
uint CompressionType = reader.ReadUInt32();
|
||||
uint DecompressedSize = reader.ReadUInt32();
|
||||
uint CompressedSize = reader.ReadUInt32();
|
||||
|
||||
byte[] input = reader.ReadBytes((int)CompressedSize);
|
||||
if (CompressionType == 1) input = BPE.Decompress(input, DecompressedSize, CompressedSize);
|
||||
if (CompressionType == 2) input = LZ77_WII.Decompress(input);
|
||||
if (CompressionType == 3) input = LZ77_WII.Decompress(input); //same as 2
|
||||
|
||||
using (var r = new FileReader(input))
|
||||
{
|
||||
for (int i = 0; i < FileCount; i++)
|
||||
{
|
||||
r.SeekBegin(files[i].Offset - DataOffset);
|
||||
files[i].FileData = r.ReadBytes((int)files[i].Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
|
||||
@ -146,13 +163,15 @@ namespace FirstPlugin
|
||||
public class FileEntry : ArchiveFileInfo
|
||||
{
|
||||
public uint Hash { get; set; }
|
||||
public uint Offset { get; set; }
|
||||
public uint Size { get; set; }
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
Hash = reader.ReadUInt32();
|
||||
FileName = GetName(reader);
|
||||
uint Size = reader.ReadUInt32();
|
||||
uint Offset = reader.ReadUInt32();
|
||||
Size = reader.ReadUInt32();
|
||||
Offset = reader.ReadUInt32();
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,5 +183,114 @@ namespace FirstPlugin
|
||||
return reader.ReadZeroTerminatedString();
|
||||
}
|
||||
}
|
||||
|
||||
class BPE
|
||||
{
|
||||
//Decompiled from MasterF0X tool for BPE decompression
|
||||
static int index = 0;
|
||||
static bool end = false;
|
||||
|
||||
public static byte[] Decompress(byte[] input, uint decompressedSize, uint cs)
|
||||
{
|
||||
char[] chArray1 = new char[16777215];
|
||||
char[] chArray2 = new char[16777215];
|
||||
char[] chArray3 = new char[16777215];
|
||||
|
||||
var mem = new MemoryStream();
|
||||
BinaryWriter binaryWriter = new BinaryWriter(mem);
|
||||
label_26:
|
||||
int num1;
|
||||
int num2;
|
||||
while (index < input.Length)
|
||||
{
|
||||
if (end)
|
||||
{
|
||||
binaryWriter.Close();
|
||||
end = false;
|
||||
index = 0;
|
||||
num1 = 0;
|
||||
num2 = 0;
|
||||
return mem.ToArray();
|
||||
}
|
||||
for (int index = 0; index < 256; ++index)
|
||||
chArray1[index] = (char)index;
|
||||
int num3 = (int)getc(input, cs);
|
||||
int index1 = 0;
|
||||
while (true)
|
||||
{
|
||||
if (num3 > (int)sbyte.MaxValue)
|
||||
{
|
||||
index1 += num3 - (int)sbyte.MaxValue;
|
||||
num3 = 0;
|
||||
}
|
||||
if (index1 != 256)
|
||||
{
|
||||
int num4 = 0;
|
||||
while (num4 <= num3)
|
||||
{
|
||||
chArray1[index1] = getc(input, cs);
|
||||
if (index1 != (int)chArray1[index1])
|
||||
chArray2[index1] = getc(input, cs);
|
||||
++num4;
|
||||
++index1;
|
||||
}
|
||||
if (index1 != 256)
|
||||
num3 = (int)getc(input, cs);
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
int num5 = 256 * (int)getc(input, cs) + (int)getc(input, cs);
|
||||
int num6 = 0;
|
||||
while (true)
|
||||
{
|
||||
int index2;
|
||||
if (num6 > 0)
|
||||
index2 = (int)chArray3[--num6];
|
||||
else if (num5-- != 0)
|
||||
index2 = (int)getc(input, cs);
|
||||
else
|
||||
goto label_26;
|
||||
if (index2 == (int)chArray1[index2])
|
||||
{
|
||||
binaryWriter.Write((byte)index2);
|
||||
}
|
||||
else
|
||||
{
|
||||
char[] chArray4 = chArray3;
|
||||
int index3 = num6;
|
||||
int num7 = index3 + 1;
|
||||
int num8 = (int)chArray2[index2];
|
||||
chArray4[index3] = (char)num8;
|
||||
char[] chArray5 = chArray3;
|
||||
int index4 = num7;
|
||||
num6 = index4 + 1;
|
||||
int num9 = (int)chArray1[index2];
|
||||
chArray5[index4] = (char)num9;
|
||||
}
|
||||
}
|
||||
}
|
||||
binaryWriter.Close();
|
||||
end = false;
|
||||
index = 0;
|
||||
num1 = 0;
|
||||
num2 = 0;
|
||||
return mem.ToArray();
|
||||
}
|
||||
|
||||
static char getc(byte[] input, uint uncompS)
|
||||
{
|
||||
if (index >= uncompS)
|
||||
{
|
||||
end = true;
|
||||
return '0';
|
||||
}
|
||||
char ch = (char)input[index];
|
||||
++index;
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ using Syroot.NintenTools.NSW.Bfres;
|
||||
using Toolbox.Library;
|
||||
using ResU = Syroot.NintenTools.Bfres;
|
||||
using Toolbox.Library.Animations;
|
||||
using AampLibraryCSharp;
|
||||
using static FirstPlugin.CSAB;
|
||||
|
||||
namespace Bfres.Structs
|
||||
{
|
||||
@ -26,76 +28,94 @@ namespace Bfres.Structs
|
||||
else return AnimCurveKeyType.Single;
|
||||
}
|
||||
|
||||
public static Animation.KeyGroup CreateTrackWiiU(ResU.AnimCurve animCurve)
|
||||
public static Animation.KeyGroup CreateTrackWiiU(ResU.AnimCurve curve, bool valuesAsInts = false)
|
||||
{
|
||||
Animation.KeyGroup track = new Animation.KeyGroup();
|
||||
track.AnimDataOffset = animCurve.AnimDataOffset;
|
||||
track.Scale = animCurve.Scale;
|
||||
track.Offset = animCurve.Offset;
|
||||
track.StartFrame = animCurve.StartFrame;
|
||||
track.EndFrame = animCurve.EndFrame;
|
||||
track.Delta = animCurve.Delta;
|
||||
track.AnimDataOffset = curve.AnimDataOffset;
|
||||
track.Scale = curve.Scale;
|
||||
track.Offset = curve.Offset;
|
||||
track.StartFrame = curve.StartFrame;
|
||||
track.EndFrame = curve.EndFrame;
|
||||
track.Delta = curve.Delta;
|
||||
|
||||
float tanscale = animCurve.Delta;
|
||||
float tanscale = curve.Delta;
|
||||
if (tanscale == 0)
|
||||
tanscale = 1;
|
||||
|
||||
if (animCurve.Scale == 0)
|
||||
animCurve.Scale = 1;
|
||||
if (curve.Scale == 0)
|
||||
curve.Scale = 1;
|
||||
|
||||
for (int i = 0; i < (ushort)animCurve.Frames.Length; i++)
|
||||
float valueScale = curve.Scale > 0 ? curve.Scale : 1;
|
||||
|
||||
for (int i = 0; i < curve.Frames.Length; i++)
|
||||
{
|
||||
switch (animCurve.CurveType)
|
||||
var frame = curve.Frames[i];
|
||||
if (frame == 0 && track.Keys.Any(x => x.Frame == 0))
|
||||
track.Keys.RemoveAt(0);
|
||||
|
||||
switch (curve.CurveType)
|
||||
{
|
||||
case ResU.AnimCurveType.Cubic: //4 elements are stored for cubic
|
||||
track.InterpolationType = InterpolationType.HERMITE;
|
||||
var coef0 = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale);
|
||||
var coef1 = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale);
|
||||
var coef2 = animCurve.Offset + (animCurve.Keys[i, 2] * animCurve.Scale);
|
||||
var coef3 = animCurve.Offset + (animCurve.Keys[i, 3] * animCurve.Scale);
|
||||
var slopes = GetSlopes(animCurve, i);
|
||||
case ResU.AnimCurveType.Cubic:
|
||||
{
|
||||
track.InterpolationType = InterpolationType.HERMITE;
|
||||
//Important to not offset the other 3 values, just the first one!
|
||||
var value = curve.Keys[i, 0] * valueScale + curve.Offset;
|
||||
var slopes = GetSlopes(curve, i);
|
||||
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
{
|
||||
IsKeyed = true,
|
||||
InterType = InterpolationType.HERMITE,
|
||||
Frame = (int)animCurve.Frames[i],
|
||||
Value = coef0,
|
||||
// Slope1 = slopes[0],
|
||||
// Slope2 = slopes[1],
|
||||
});
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
{
|
||||
Frame = frame,
|
||||
Value = value,
|
||||
In = slopes[0],
|
||||
Out = slopes[1],
|
||||
});
|
||||
}
|
||||
break;
|
||||
case ResU.AnimCurveType.Linear: //2 elements are stored for linear
|
||||
track.InterpolationType = InterpolationType.LINEAR;
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
case ResU.AnimCurveType.Linear:
|
||||
{
|
||||
IsKeyed = true,
|
||||
InterType = InterpolationType.LINEAR,
|
||||
Frame = (int)animCurve.Frames[i],
|
||||
Value = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale),
|
||||
Delta = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale),
|
||||
});
|
||||
track.InterpolationType = InterpolationType.LINEAR;
|
||||
var value = curve.Keys[i, 0] * valueScale + curve.Offset;
|
||||
var delta = curve.Keys[i, 1] * valueScale;
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
{
|
||||
Frame = frame,
|
||||
Value = value,
|
||||
Delta = delta,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case ResU.AnimCurveType.StepInt: //1 element are stored for step
|
||||
track.InterpolationType = InterpolationType.STEP;
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
case ResU.AnimCurveType.StepBool:
|
||||
{
|
||||
IsKeyed = true,
|
||||
InterType = InterpolationType.STEP,
|
||||
Frame = (int)animCurve.Frames[i],
|
||||
Value = (int)animCurve.Offset + (int)animCurve.Keys[i, 0] * animCurve.Scale,
|
||||
});
|
||||
|
||||
Console.WriteLine($"Frame {animCurve.Frames[i]} FrameINT {(int)animCurve.Frames[i]} Offset " + (int)animCurve.Offset + " " + ((int)animCurve.Offset + (int)animCurve.Keys[i, 0] * animCurve.Scale));
|
||||
track.InterpolationType = InterpolationType.STEP;
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
{
|
||||
Frame = frame,
|
||||
Value = curve.KeyStepBoolData[i] ? 1 : 0,
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unsupported anim type!");
|
||||
{
|
||||
track.InterpolationType = InterpolationType.STEP;
|
||||
var value = curve.Keys[i, 0] + curve.Offset;
|
||||
if (valuesAsInts)
|
||||
value = (int)curve.Keys[i, 0] + curve.Offset;
|
||||
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
{
|
||||
Frame = frame,
|
||||
Value = value,
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return track;
|
||||
}
|
||||
|
||||
//Method to extract the slopes from a cubic curve
|
||||
//Need to get the time, delta, out and next in slope values
|
||||
public static float[] GetSlopes(AnimCurve curve, float index)
|
||||
{
|
||||
float[] slopes = new float[2];
|
||||
@ -106,9 +126,9 @@ namespace Bfres.Structs
|
||||
for (int i = 0; i < curve.Frames.Length; i++)
|
||||
{
|
||||
var coef0 = curve.Keys[i, 0] * curve.Scale + curve.Offset;
|
||||
var coef1 = curve.Keys[i, 1] * curve.Scale + curve.Offset;
|
||||
var coef2 = curve.Keys[i, 2] * curve.Scale + curve.Offset;
|
||||
var coef3 = curve.Keys[i, 3] * curve.Scale + curve.Offset;
|
||||
var coef1 = curve.Keys[i, 1] * curve.Scale;
|
||||
var coef2 = curve.Keys[i, 2] * curve.Scale;
|
||||
var coef3 = curve.Keys[i, 3] * curve.Scale;
|
||||
float time = 0;
|
||||
float delta = 0;
|
||||
if (i < curve.Frames.Length - 1)
|
||||
@ -118,7 +138,7 @@ namespace Bfres.Structs
|
||||
time = curve.Frames[i + 1] - curve.Frames[i];
|
||||
}
|
||||
|
||||
var slopeData = CurveInterpolationHelper.GetCubicSlopes(time, delta,
|
||||
var slopeData = GetCubicSlopes(time, delta,
|
||||
new float[4] { coef0, coef1, coef2, coef3, });
|
||||
|
||||
if (index == i)
|
||||
@ -135,6 +155,7 @@ namespace Bfres.Structs
|
||||
return slopes;
|
||||
}
|
||||
|
||||
|
||||
public static float[] GetSlopes(ResU.AnimCurve curve, float index)
|
||||
{
|
||||
float[] slopes = new float[2];
|
||||
@ -145,9 +166,9 @@ namespace Bfres.Structs
|
||||
for (int i = 0; i < curve.Frames.Length; i++)
|
||||
{
|
||||
var coef0 = curve.Keys[i, 0] * curve.Scale + curve.Offset;
|
||||
var coef1 = curve.Keys[i, 1] * curve.Scale + curve.Offset;
|
||||
var coef2 = curve.Keys[i, 2] * curve.Scale + curve.Offset;
|
||||
var coef3 = curve.Keys[i, 3] * curve.Scale + curve.Offset;
|
||||
var coef1 = curve.Keys[i, 1] * curve.Scale;
|
||||
var coef2 = curve.Keys[i, 2] * curve.Scale;
|
||||
var coef3 = curve.Keys[i, 3] * curve.Scale;
|
||||
float time = 0;
|
||||
float delta = 0;
|
||||
if (i < curve.Frames.Length - 1)
|
||||
@ -157,7 +178,7 @@ namespace Bfres.Structs
|
||||
time = curve.Frames[i + 1] - curve.Frames[i];
|
||||
}
|
||||
|
||||
var slopeData = CurveInterpolationHelper.GetCubicSlopes(time, delta,
|
||||
var slopeData = GetCubicSlopes(time, delta,
|
||||
new float[4] { coef0, coef1, coef2, coef3, });
|
||||
|
||||
if (index == i)
|
||||
@ -174,6 +195,14 @@ namespace Bfres.Structs
|
||||
return slopes;
|
||||
}
|
||||
|
||||
public static float[] GetCubicSlopes(float time, float delta, float[] coef)
|
||||
{
|
||||
float outSlope = coef[1] / time;
|
||||
float param = coef[3] - (-2 * delta);
|
||||
float inSlope = param / time - outSlope;
|
||||
return new float[2] { inSlope, coef[1] == 0 ? 0 : outSlope };
|
||||
}
|
||||
|
||||
public static BooleanKeyGroup CreateBooleanTrackWiiU(ResU.AnimCurve animCurve)
|
||||
{
|
||||
BooleanKeyGroup track = new BooleanKeyGroup();
|
||||
@ -235,75 +264,86 @@ namespace Bfres.Structs
|
||||
|
||||
return track;
|
||||
}
|
||||
public static Animation.KeyGroup CreateTrack(AnimCurve animCurve)
|
||||
public static Animation.KeyGroup CreateTrack(AnimCurve curve, bool valuesAsInts = false)
|
||||
{
|
||||
Animation.KeyGroup track = new Animation.KeyGroup();
|
||||
track.AnimDataOffset = animCurve.AnimDataOffset;
|
||||
track.Scale = animCurve.Scale;
|
||||
track.Offset = animCurve.Offset;
|
||||
track.StartFrame = animCurve.StartFrame;
|
||||
track.EndFrame = animCurve.EndFrame;
|
||||
track.Delta = animCurve.Delta;
|
||||
track.AnimDataOffset = curve.AnimDataOffset;
|
||||
track.Scale = curve.Scale;
|
||||
track.Offset = curve.Offset;
|
||||
track.StartFrame = curve.StartFrame;
|
||||
track.EndFrame = curve.EndFrame;
|
||||
track.Delta = curve.Delta;
|
||||
|
||||
float tanscale = animCurve.Delta;
|
||||
float tanscale = curve.Delta;
|
||||
if (tanscale == 0)
|
||||
tanscale = 1;
|
||||
|
||||
if (animCurve.Scale == 0)
|
||||
animCurve.Scale = 1;
|
||||
if (curve.Scale == 0)
|
||||
curve.Scale = 1;
|
||||
|
||||
for (int i = 0; i < (ushort)animCurve.Frames.Length; i++)
|
||||
float valueScale = curve.Scale > 0 ? curve.Scale : 1;
|
||||
|
||||
for (int i = 0; i < curve.Frames.Length; i++)
|
||||
{
|
||||
switch (animCurve.CurveType)
|
||||
var frame = curve.Frames[i];
|
||||
if (frame == 0 && track.Keys.Any(x => x.Frame == 0))
|
||||
track.Keys.RemoveAt(0);
|
||||
|
||||
switch (curve.CurveType)
|
||||
{
|
||||
case AnimCurveType.Cubic: //4 elements are stored for cubic
|
||||
track.InterpolationType = InterpolationType.HERMITE;
|
||||
var coef0 = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale);
|
||||
var coef1 = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale);
|
||||
var coef2 = animCurve.Offset + (animCurve.Keys[i, 2] * animCurve.Scale);
|
||||
var coef3 = animCurve.Offset + (animCurve.Keys[i, 3] * animCurve.Scale);
|
||||
var slopes = GetSlopes(animCurve, i);
|
||||
|
||||
var inSlope = slopes[0] * animCurve.Scale + animCurve.Offset;
|
||||
var outSlope = slopes[1] * animCurve.Scale + animCurve.Offset;
|
||||
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
case AnimCurveType.Cubic:
|
||||
{
|
||||
IsKeyed = true,
|
||||
InterType = InterpolationType.HERMITE,
|
||||
Frame = (int)animCurve.Frames[i],
|
||||
Value = coef0,
|
||||
Slope1 = inSlope,
|
||||
Slope2 = outSlope,
|
||||
});
|
||||
track.InterpolationType = InterpolationType.HERMITE;
|
||||
//Important to not offset the other 3 values, just the first one!
|
||||
var value = curve.Keys[i, 0] * valueScale + curve.Offset;
|
||||
var slopes = GetSlopes(curve, i);
|
||||
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
{
|
||||
Frame = frame,
|
||||
Value = value,
|
||||
In = slopes[0],
|
||||
Out = slopes[1],
|
||||
});
|
||||
}
|
||||
break;
|
||||
case AnimCurveType.Linear: //2 elements are stored for linear
|
||||
track.InterpolationType = InterpolationType.LINEAR;
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
case AnimCurveType.Linear:
|
||||
{
|
||||
IsKeyed = true,
|
||||
InterType = InterpolationType.LINEAR,
|
||||
Frame = (int)animCurve.Frames[i],
|
||||
Value = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale),
|
||||
|
||||
Value1 = animCurve.Offset + (animCurve.Keys[i, 0] * animCurve.Scale),
|
||||
Delta = animCurve.Offset + (animCurve.Keys[i, 1] * animCurve.Scale),
|
||||
});
|
||||
track.InterpolationType = InterpolationType.LINEAR;
|
||||
var value = curve.Keys[i, 0] * valueScale + curve.Offset;
|
||||
var delta = curve.Keys[i, 1] * valueScale;
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
{
|
||||
Frame = frame,
|
||||
Value = value,
|
||||
Delta = delta,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case AnimCurveType.StepInt: //1 element are stored for step
|
||||
track.InterpolationType = InterpolationType.STEP;
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
case AnimCurveType.StepBool:
|
||||
{
|
||||
IsKeyed = true,
|
||||
InterType = InterpolationType.STEP,
|
||||
Frame = (int)animCurve.Frames[i],
|
||||
Value = (int)animCurve.Offset + (int)animCurve.Keys[i, 0] * animCurve.Scale,
|
||||
Value1 = (int)animCurve.Offset + (int)animCurve.Keys[i, 0] * animCurve.Scale,
|
||||
|
||||
});
|
||||
track.InterpolationType = InterpolationType.STEP;
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
{
|
||||
Frame = frame,
|
||||
Value = curve.KeyStepBoolData[i] ? 1 : 0,
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unsupported anim type!");
|
||||
{
|
||||
track.InterpolationType = InterpolationType.STEP;
|
||||
var value = curve.Keys[i, 0] + curve.Offset;
|
||||
if (valuesAsInts)
|
||||
value = (int)curve.Keys[i, 0] + curve.Offset;
|
||||
|
||||
track.Keys.Add(new Animation.KeyFrame()
|
||||
{
|
||||
Frame = frame,
|
||||
Value = value,
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,7 +431,7 @@ namespace Bfres.Structs
|
||||
{
|
||||
int index = (int)SamplerInfo.CurveIndex;
|
||||
|
||||
Animation.KeyGroup keyGroup = CurveHelper.CreateTrack(matanim.Curves[index]);
|
||||
Animation.KeyGroup keyGroup = CurveHelper.CreateTrack(matanim.Curves[index], true);
|
||||
|
||||
sampler.AnimDataOffset = matanim.Curves[index].AnimDataOffset;
|
||||
sampler.Keys = keyGroup.Keys;
|
||||
|
@ -610,6 +610,7 @@ namespace Bfres.Structs
|
||||
Dictionary<string, List<FSHP.VertexAttribute>> AttributeMatcher = new Dictionary<string, List<FSHP.VertexAttribute>>();
|
||||
|
||||
bool IsWiiU = (resFileU != null);
|
||||
var boneMappings = Model != null ? Model.Skeleton.userIndices : new ushort[0];
|
||||
|
||||
int MatStartIndex = materials.Count;
|
||||
string ext = System.IO.Path.GetExtension(FileName);
|
||||
@ -1365,6 +1366,9 @@ namespace Bfres.Structs
|
||||
|
||||
if (IsEdited)
|
||||
UpdateVertexData();
|
||||
|
||||
if (Model != null)
|
||||
Model.Skeleton.userIndices = boneMappings;
|
||||
}
|
||||
|
||||
public FMAT GetMaterial(int index)
|
||||
|
@ -11,6 +11,7 @@ using Toolbox.Library.Animations;
|
||||
using Toolbox.Library.Forms;
|
||||
using SELib;
|
||||
using FirstPlugin.Forms;
|
||||
using static Toolbox.Library.Animations.Animation;
|
||||
|
||||
namespace Bfres.Structs
|
||||
{
|
||||
@ -748,16 +749,16 @@ namespace Bfres.Structs
|
||||
keyGroup.AnimDataOffset = bn.Curves[curve].AnimDataOffset;
|
||||
switch (keyGroup.AnimDataOffset)
|
||||
{
|
||||
case (int)TrackType.XPOS: bone.XPOS.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.YPOS: bone.YPOS.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.ZPOS: bone.ZPOS.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.XROT: bone.XROT.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.YROT: bone.YROT.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.ZROT: bone.ZROT.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.WROT: bone.WROT.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.XSCA: bone.XSCA.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.YSCA: bone.YSCA.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.ZSCA: bone.ZSCA.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.XPOS: bone.XPOS = keyGroup; break;
|
||||
case (int)TrackType.YPOS: bone.YPOS = keyGroup; break;
|
||||
case (int)TrackType.ZPOS: bone.ZPOS = keyGroup; break;
|
||||
case (int)TrackType.XROT: bone.XROT = keyGroup; break;
|
||||
case (int)TrackType.YROT: bone.YROT = keyGroup; break;
|
||||
case (int)TrackType.ZROT: bone.ZROT = keyGroup; break;
|
||||
case (int)TrackType.WROT: bone.WROT = keyGroup; break;
|
||||
case (int)TrackType.XSCA: bone.XSCA = keyGroup; break;
|
||||
case (int)TrackType.YSCA: bone.YSCA = keyGroup; break;
|
||||
case (int)TrackType.ZSCA: bone.ZSCA = keyGroup; break;
|
||||
default: throw new Exception("Unknown Anim Offset " + keyGroup.AnimDataOffset);
|
||||
}
|
||||
}
|
||||
@ -811,16 +812,16 @@ namespace Bfres.Structs
|
||||
keyGroup.AnimDataOffset = bn.Curves[curve].AnimDataOffset;
|
||||
switch (keyGroup.AnimDataOffset)
|
||||
{
|
||||
case (int)TrackType.XPOS: bone.XPOS.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.YPOS: bone.YPOS.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.ZPOS: bone.ZPOS.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.XROT: bone.XROT.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.YROT: bone.YROT.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.ZROT: bone.ZROT.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.WROT: bone.WROT.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.XSCA: bone.XSCA.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.YSCA: bone.YSCA.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.ZSCA: bone.ZSCA.Keys.AddRange(keyGroup.Keys); break;
|
||||
case (int)TrackType.XPOS: bone.XPOS = keyGroup; break;
|
||||
case (int)TrackType.YPOS: bone.YPOS = keyGroup; break;
|
||||
case (int)TrackType.ZPOS: bone.ZPOS = keyGroup; break;
|
||||
case (int)TrackType.XROT: bone.XROT = keyGroup; break;
|
||||
case (int)TrackType.YROT: bone.YROT = keyGroup; break;
|
||||
case (int)TrackType.ZROT: bone.ZROT = keyGroup; break;
|
||||
case (int)TrackType.WROT: bone.WROT = keyGroup; break;
|
||||
case (int)TrackType.XSCA: bone.XSCA = keyGroup; break;
|
||||
case (int)TrackType.YSCA: bone.YSCA = keyGroup; break;
|
||||
case (int)TrackType.ZSCA: bone.ZSCA = keyGroup; break;
|
||||
default: throw new Exception("Unknown Anim Offset " + keyGroup.AnimDataOffset);
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ namespace Bfres.Structs
|
||||
{
|
||||
int index = (int)SamplerInfo.CurveIndex;
|
||||
|
||||
Animation.KeyGroup keyGroup = CurveHelper.CreateTrackWiiU(matanim.Curves[index]);
|
||||
Animation.KeyGroup keyGroup = CurveHelper.CreateTrackWiiU(matanim.Curves[index], true);
|
||||
sampler.AnimDataOffset = matanim.Curves[index].AnimDataOffset;
|
||||
sampler.Keys = keyGroup.Keys;
|
||||
|
||||
|
@ -1534,7 +1534,9 @@ namespace FirstPlugin
|
||||
|
||||
//Max mip level will be set automatically unless overwritten
|
||||
//The tex format can be adjusted in the function if necessary. Will normally be set to format in settings
|
||||
public void Replace(string FileName, uint MaxMipLevel = 0, uint ArrayIndex = 0, TEX_FORMAT DefaultFormat = TEX_FORMAT.BC1_UNORM_SRGB, SurfaceDim surfaceDim = SurfaceDim.Dim2D)
|
||||
public void Replace(string FileName, uint MaxMipLevel = 0, uint ArrayIndex = 0,
|
||||
TEX_FORMAT DefaultFormat = TEX_FORMAT.BC1_UNORM_SRGB, SurfaceDim surfaceDim = SurfaceDim.Dim2D,
|
||||
int alignment = 512)
|
||||
{
|
||||
Console.WriteLine("surfaceDim" + surfaceDim);
|
||||
|
||||
@ -1545,6 +1547,9 @@ namespace FirstPlugin
|
||||
BinaryTextureImporterList importer = new BinaryTextureImporterList();
|
||||
|
||||
setting.SurfaceDim = surfaceDim;
|
||||
setting.Alignment = alignment;
|
||||
//Check if alignment is required for combining individual levels or not
|
||||
setting.CombineMipLevel = alignment != 0 ? true : false;
|
||||
|
||||
var ImageDataCached = new List<List<byte[]>>();
|
||||
if (Texture != null && Texture.TextureData != null)
|
||||
|
@ -244,7 +244,7 @@ namespace FirstPlugin
|
||||
writer.Write((byte)mip);
|
||||
writer.Write((byte)1);
|
||||
|
||||
var surface = Zstb.SCompress(ImageList[array][mip]);
|
||||
var surface = Zstb.SCompress(ImageList[array][mip], 20);
|
||||
surfaceSizes.Add((uint)surface.Length);
|
||||
|
||||
surfaceData.Add(surface);
|
||||
@ -293,7 +293,7 @@ namespace FirstPlugin
|
||||
{
|
||||
//Replace the data using an instance of a switch texture
|
||||
var tex = new TextureData();
|
||||
tex.Replace(FileName, MipCount, 0, Format);
|
||||
tex.Replace(FileName, MipCount, 0, Format, Syroot.NintenTools.NSW.Bntx.GFX.SurfaceDim.Dim2D, 1);
|
||||
|
||||
//Get swappable array level
|
||||
ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase));
|
||||
@ -310,6 +310,9 @@ namespace FirstPlugin
|
||||
if (tex.Texture == null)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < ImageList[0].Count; i++)
|
||||
Console.WriteLine($"SIZE 1 mip{i} {ImageList[0][i].Length}");
|
||||
|
||||
//Ensure the format matches if image requires multiple surface levels
|
||||
if (ImageList.Count > 1 && this.Format != tex.Format)
|
||||
throw new Exception($"Imported texture must use the original format for surface injecting! Expected {this.Format} but got {tex.Format}! If you need ASTC, use an astc encoder with .astc file format.");
|
||||
@ -326,6 +329,10 @@ namespace FirstPlugin
|
||||
ImageList.Add(surface);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ImageList[0].Count; i++)
|
||||
Console.WriteLine($"SIZE 2 mip{i} {ImageList[0][i].Length}");
|
||||
|
||||
|
||||
Width = tex.Texture.Width;
|
||||
Height = tex.Texture.Height;
|
||||
MipCount = tex.Texture.MipCount;
|
||||
@ -363,6 +370,7 @@ namespace FirstPlugin
|
||||
{ 0x203, TEX_FORMAT.BC1_UNORM_SRGB },
|
||||
{ 0x302, TEX_FORMAT.BC1_UNORM },
|
||||
{ 0x606, TEX_FORMAT.BC4_UNORM },
|
||||
{ 0x607, TEX_FORMAT.BC4_UNORM },
|
||||
{ 0x702, TEX_FORMAT.BC5_UNORM },
|
||||
{ 0x703, TEX_FORMAT.BC5_UNORM },
|
||||
{ 0x707, TEX_FORMAT.BC5_UNORM },
|
||||
|
@ -1557,6 +1557,7 @@
|
||||
<Compile Include="FileFormats\Texture\NUTEXB.cs" />
|
||||
<Compile Include="FileFormats\Texture\TexConv.cs" />
|
||||
<Compile Include="FileFormats\Texture\XTX.cs" />
|
||||
<Compile Include="FileFormats\Texture\TXTG.cs" />
|
||||
<Compile Include="FileFormats\Rom\XCI.cs" />
|
||||
<Compile Include="GetSwitchKeys.cs" />
|
||||
<Compile Include="GL\BFRES\BFRES_Render.cs" />
|
||||
|
@ -821,8 +821,8 @@ namespace FirstPlugin
|
||||
{
|
||||
if (mat.shaderassign.options.ContainsKey(propertyName))
|
||||
{
|
||||
float value = float.Parse(mat.shaderassign.options[propertyName]);
|
||||
shader.SetFloat(propertyName, value);
|
||||
//float value = float.Parse(mat.shaderassign.options[propertyName]);
|
||||
//shader.SetFloat(propertyName, value);
|
||||
}
|
||||
|
||||
Dictionary<string, BfresShaderParam> matParams = mat.matparam;
|
||||
|
@ -61,6 +61,8 @@
|
||||
this.chkBoxFlipUvsY = new Toolbox.Library.Forms.STCheckBox();
|
||||
this.chkBoxImportBones = new Toolbox.Library.Forms.STCheckBox();
|
||||
this.panel8 = new Toolbox.Library.Forms.STPanel();
|
||||
this.stLabel4 = new Toolbox.Library.Forms.STLabel();
|
||||
this.lodCountUD = new Toolbox.Library.Forms.NumericUpDownUint();
|
||||
this.chkCreateDummyLODs = new Toolbox.Library.Forms.STCheckBox();
|
||||
this.stLabel3 = new Toolbox.Library.Forms.STLabel();
|
||||
this.gamePresetCB = new Toolbox.Library.Forms.STComboBox();
|
||||
@ -103,8 +105,6 @@
|
||||
this.stCheckBox1 = new Toolbox.Library.Forms.STCheckBox();
|
||||
this.chkMapOriginalMaterials = new Toolbox.Library.Forms.STCheckBox();
|
||||
this.ogSkinCountChkBox = new Toolbox.Library.Forms.STCheckBox();
|
||||
this.lodCountUD = new Toolbox.Library.Forms.NumericUpDownUint();
|
||||
this.stLabel4 = new Toolbox.Library.Forms.STLabel();
|
||||
this.contentContainer.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
this.panel2.SuspendLayout();
|
||||
@ -114,6 +114,7 @@
|
||||
this.panel6.SuspendLayout();
|
||||
this.panel7.SuspendLayout();
|
||||
this.panel8.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.lodCountUD)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
||||
this.panel9.SuspendLayout();
|
||||
this.tabControl1.SuspendLayout();
|
||||
@ -121,7 +122,6 @@
|
||||
this.tabPageAdvanced.SuspendLayout();
|
||||
this.stPanel1.SuspendLayout();
|
||||
this.tabPage1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.lodCountUD)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// contentContainer
|
||||
@ -492,6 +492,27 @@
|
||||
this.panel8.Size = new System.Drawing.Size(524, 341);
|
||||
this.panel8.TabIndex = 11;
|
||||
//
|
||||
// stLabel4
|
||||
//
|
||||
this.stLabel4.AutoSize = true;
|
||||
this.stLabel4.Location = new System.Drawing.Point(237, 291);
|
||||
this.stLabel4.Name = "stLabel4";
|
||||
this.stLabel4.Size = new System.Drawing.Size(63, 13);
|
||||
this.stLabel4.TabIndex = 39;
|
||||
this.stLabel4.Text = "LOD Count:";
|
||||
//
|
||||
// lodCountUD
|
||||
//
|
||||
this.lodCountUD.Location = new System.Drawing.Point(319, 289);
|
||||
this.lodCountUD.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.lodCountUD.Name = "lodCountUD";
|
||||
this.lodCountUD.Size = new System.Drawing.Size(120, 20);
|
||||
this.lodCountUD.TabIndex = 38;
|
||||
//
|
||||
// chkCreateDummyLODs
|
||||
//
|
||||
this.chkCreateDummyLODs.AutoSize = true;
|
||||
@ -582,6 +603,7 @@
|
||||
this.chkBoxRotNegative90Y.Text = "Rotate -90 degrees";
|
||||
this.chkBoxRotNegative90Y.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
this.chkBoxRotNegative90Y.UseVisualStyleBackColor = true;
|
||||
this.chkBoxRotNegative90Y.CheckedChanged += new System.EventHandler(this.chkBoxSettings_CheckedChanged);
|
||||
//
|
||||
// textBoxMaterialPath
|
||||
//
|
||||
@ -814,7 +836,7 @@
|
||||
this.tabPageAdvanced.Location = new System.Drawing.Point(4, 25);
|
||||
this.tabPageAdvanced.Name = "tabPageAdvanced";
|
||||
this.tabPageAdvanced.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPageAdvanced.Size = new System.Drawing.Size(530, 333);
|
||||
this.tabPageAdvanced.Size = new System.Drawing.Size(530, 347);
|
||||
this.tabPageAdvanced.TabIndex = 0;
|
||||
this.tabPageAdvanced.Text = "Advanced Settings";
|
||||
//
|
||||
@ -831,7 +853,7 @@
|
||||
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(524, 327);
|
||||
this.stPanel1.Size = new System.Drawing.Size(524, 341);
|
||||
this.stPanel1.TabIndex = 17;
|
||||
//
|
||||
// tabPage1
|
||||
@ -848,7 +870,7 @@
|
||||
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(530, 333);
|
||||
this.tabPage1.Size = new System.Drawing.Size(530, 347);
|
||||
this.tabPage1.TabIndex = 2;
|
||||
this.tabPage1.Text = "Inject Mode";
|
||||
this.tabPage1.UseVisualStyleBackColor = true;
|
||||
@ -959,27 +981,6 @@
|
||||
this.ogSkinCountChkBox.Text = "Keep Original Skin Count (can help crashes)";
|
||||
this.ogSkinCountChkBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// lodCountUD
|
||||
//
|
||||
this.lodCountUD.Location = new System.Drawing.Point(319, 289);
|
||||
this.lodCountUD.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.lodCountUD.Name = "lodCountUD";
|
||||
this.lodCountUD.Size = new System.Drawing.Size(120, 20);
|
||||
this.lodCountUD.TabIndex = 38;
|
||||
//
|
||||
// stLabel4
|
||||
//
|
||||
this.stLabel4.AutoSize = true;
|
||||
this.stLabel4.Location = new System.Drawing.Point(237, 291);
|
||||
this.stLabel4.Name = "stLabel4";
|
||||
this.stLabel4.Size = new System.Drawing.Size(63, 13);
|
||||
this.stLabel4.TabIndex = 39;
|
||||
this.stLabel4.Text = "LOD Count:";
|
||||
//
|
||||
// BfresModelImportSettings
|
||||
//
|
||||
this.ClientSize = new System.Drawing.Size(547, 412);
|
||||
@ -1003,6 +1004,7 @@
|
||||
this.panel7.PerformLayout();
|
||||
this.panel8.ResumeLayout(false);
|
||||
this.panel8.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.lodCountUD)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
||||
this.panel9.ResumeLayout(false);
|
||||
this.panel9.PerformLayout();
|
||||
@ -1012,7 +1014,6 @@
|
||||
this.stPanel1.ResumeLayout(false);
|
||||
this.tabPage1.ResumeLayout(false);
|
||||
this.tabPage1.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.lodCountUD)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
@ -492,10 +492,12 @@ namespace FirstPlugin
|
||||
|
||||
int assimpIndex = assimpMeshListView.SelectedIndices[0];
|
||||
|
||||
if (objectNameTB.Text == originalMeshListView.Items[assimpIndex].Text)
|
||||
objectNameTB.BackColor = System.Drawing.Color.Green;
|
||||
else
|
||||
objectNameTB.BackColor = System.Drawing.Color.DarkRed;
|
||||
objectNameTB.BackColor = System.Drawing.Color.DarkRed;
|
||||
foreach (ListViewItem item in originalMeshListView.Items)
|
||||
{
|
||||
if (objectNameTB.Text == item.Text)
|
||||
objectNameTB.BackColor = System.Drawing.Color.Green;
|
||||
}
|
||||
|
||||
NewMeshlist[assimpIndex].ObjectName = objectNameTB.Text;
|
||||
}
|
||||
|
@ -28,17 +28,66 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.chkFilterDefaults = new Toolbox.Library.Forms.STCheckBox();
|
||||
this.shaderOptionsListView = new Toolbox.Library.Forms.STListView();
|
||||
this.ovlColumn1 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
|
||||
this.ovlColumn2 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
|
||||
this.btnScrolDown = new Toolbox.Library.Forms.STButton();
|
||||
this.btnScrollUp = new Toolbox.Library.Forms.STButton();
|
||||
this.btnEdit = new Toolbox.Library.Forms.STButton();
|
||||
this.btnRemove = new Toolbox.Library.Forms.STButton();
|
||||
this.btnAdd = new Toolbox.Library.Forms.STButton();
|
||||
this.shaderOptionsListView = new Toolbox.Library.Forms.STListView();
|
||||
this.ovlColumn1 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
|
||||
this.ovlColumn2 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));
|
||||
((System.ComponentModel.ISupportInitialize)(this.shaderOptionsListView)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// chkFilterDefaults
|
||||
//
|
||||
this.chkFilterDefaults.AutoSize = true;
|
||||
this.chkFilterDefaults.Checked = true;
|
||||
this.chkFilterDefaults.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkFilterDefaults.Location = new System.Drawing.Point(165, 7);
|
||||
this.chkFilterDefaults.Name = "chkFilterDefaults";
|
||||
this.chkFilterDefaults.Size = new System.Drawing.Size(120, 17);
|
||||
this.chkFilterDefaults.TabIndex = 31;
|
||||
this.chkFilterDefaults.Text = "Filter Default Values";
|
||||
this.chkFilterDefaults.UseVisualStyleBackColor = true;
|
||||
this.chkFilterDefaults.CheckedChanged += new System.EventHandler(this.chkFilterDefaults_CheckedChanged);
|
||||
//
|
||||
// shaderOptionsListView
|
||||
//
|
||||
this.shaderOptionsListView.AllColumns.Add(this.ovlColumn1);
|
||||
this.shaderOptionsListView.AllColumns.Add(this.ovlColumn2);
|
||||
this.shaderOptionsListView.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.shaderOptionsListView.CellEditUseWholeCell = false;
|
||||
this.shaderOptionsListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.ovlColumn1,
|
||||
this.ovlColumn2});
|
||||
this.shaderOptionsListView.Cursor = System.Windows.Forms.Cursors.Default;
|
||||
this.shaderOptionsListView.HideSelection = false;
|
||||
this.shaderOptionsListView.Location = new System.Drawing.Point(3, 32);
|
||||
this.shaderOptionsListView.Name = "shaderOptionsListView";
|
||||
this.shaderOptionsListView.ShowGroups = false;
|
||||
this.shaderOptionsListView.Size = new System.Drawing.Size(449, 400);
|
||||
this.shaderOptionsListView.TabIndex = 30;
|
||||
this.shaderOptionsListView.UseCompatibleStateImageBehavior = false;
|
||||
this.shaderOptionsListView.View = System.Windows.Forms.View.Details;
|
||||
this.shaderOptionsListView.SelectedIndexChanged += new System.EventHandler(this.shaderOptionsListView_SelectedIndexChanged);
|
||||
this.shaderOptionsListView.DoubleClick += new System.EventHandler(this.shaderOptionsListView_DoubleClick);
|
||||
//
|
||||
// ovlColumn1
|
||||
//
|
||||
this.ovlColumn1.AspectName = "Name";
|
||||
this.ovlColumn1.Text = "Name";
|
||||
this.ovlColumn1.Width = 170;
|
||||
//
|
||||
// ovlColumn2
|
||||
//
|
||||
this.ovlColumn2.AspectName = "Value";
|
||||
this.ovlColumn2.Text = "Value";
|
||||
this.ovlColumn2.Width = 385;
|
||||
//
|
||||
// btnScrolDown
|
||||
//
|
||||
this.btnScrolDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
@ -97,45 +146,11 @@
|
||||
this.btnAdd.UseVisualStyleBackColor = true;
|
||||
this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);
|
||||
//
|
||||
// shaderOptionsListView
|
||||
//
|
||||
this.shaderOptionsListView.AllColumns.Add(this.ovlColumn1);
|
||||
this.shaderOptionsListView.AllColumns.Add(this.ovlColumn2);
|
||||
this.shaderOptionsListView.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.shaderOptionsListView.CellEditUseWholeCell = false;
|
||||
this.shaderOptionsListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.ovlColumn1,
|
||||
this.ovlColumn2});
|
||||
this.shaderOptionsListView.Cursor = System.Windows.Forms.Cursors.Default;
|
||||
this.shaderOptionsListView.Location = new System.Drawing.Point(3, 32);
|
||||
this.shaderOptionsListView.Name = "shaderOptionsListView";
|
||||
this.shaderOptionsListView.ShowGroups = false;
|
||||
this.shaderOptionsListView.Size = new System.Drawing.Size(449, 400);
|
||||
this.shaderOptionsListView.TabIndex = 30;
|
||||
this.shaderOptionsListView.UseCompatibleStateImageBehavior = false;
|
||||
this.shaderOptionsListView.View = System.Windows.Forms.View.Details;
|
||||
this.shaderOptionsListView.SelectedIndexChanged += new System.EventHandler(this.shaderOptionsListView_SelectedIndexChanged);
|
||||
this.shaderOptionsListView.DoubleClick += new System.EventHandler(this.shaderOptionsListView_DoubleClick);
|
||||
//
|
||||
// ovlColumn1
|
||||
//
|
||||
this.ovlColumn1.AspectName = "Name";
|
||||
this.ovlColumn1.HeaderForeColor = System.Drawing.Color.Empty;
|
||||
this.ovlColumn1.Text = "Name";
|
||||
this.ovlColumn1.Width = 170;
|
||||
//
|
||||
// ovlColumn2
|
||||
//
|
||||
this.ovlColumn2.AspectName = "Value";
|
||||
this.ovlColumn2.Text = "Value";
|
||||
this.ovlColumn2.Width = 385;
|
||||
//
|
||||
// ShaderOptionsEditor
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.chkFilterDefaults);
|
||||
this.Controls.Add(this.shaderOptionsListView);
|
||||
this.Controls.Add(this.btnScrolDown);
|
||||
this.Controls.Add(this.btnScrollUp);
|
||||
@ -146,6 +161,7 @@
|
||||
this.Size = new System.Drawing.Size(496, 435);
|
||||
((System.ComponentModel.ISupportInitialize)(this.shaderOptionsListView)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
@ -159,5 +175,6 @@
|
||||
private Toolbox.Library.Forms.STListView shaderOptionsListView;
|
||||
private BrightIdeasSoftware.OLVColumn ovlColumn1;
|
||||
private BrightIdeasSoftware.OLVColumn ovlColumn2;
|
||||
private Toolbox.Library.Forms.STCheckBox chkFilterDefaults;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ namespace FirstPlugin.Forms
|
||||
{
|
||||
public partial class ShaderOptionsEditor : UserControl
|
||||
{
|
||||
private bool FilterDefaults => chkFilterDefaults.Checked;
|
||||
|
||||
public ShaderOptionsEditor()
|
||||
{
|
||||
InitializeComponent();
|
||||
@ -47,7 +49,12 @@ namespace FirstPlugin.Forms
|
||||
shaderOptionsListView.ForeColor = FormThemes.BaseTheme.FormForeColor;
|
||||
|
||||
foreach (var option in material.shaderassign.options)
|
||||
{
|
||||
if (FilterDefaults && option.Value == "<Default Value>")
|
||||
continue;
|
||||
|
||||
options.Add(new Options() { Name = option.Key, Value = option.Value });
|
||||
}
|
||||
|
||||
shaderOptionsListView.SetObjects(options);
|
||||
options.Clear();
|
||||
@ -140,5 +147,10 @@ namespace FirstPlugin.Forms
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void chkFilterDefaults_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
InitializeShaderOptionList(material);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
this.stLabel5 = new Toolbox.Library.Forms.STLabel();
|
||||
this.stLabel4 = new Toolbox.Library.Forms.STLabel();
|
||||
this.stLabel3 = new Toolbox.Library.Forms.STLabel();
|
||||
this.textBox1 = new System.Windows.Forms.TextBox();
|
||||
this.stFlowLayoutPanel1.SuspendLayout();
|
||||
this.stDropDownPanel1.SuspendLayout();
|
||||
this.stDropDownPanel2.SuspendLayout();
|
||||
@ -51,7 +52,10 @@
|
||||
this.stFlowLayoutPanel1.AutoScroll = true;
|
||||
this.stFlowLayoutPanel1.Controls.Add(this.stDropDownPanel1);
|
||||
this.stFlowLayoutPanel1.Controls.Add(this.stDropDownPanel2);
|
||||
this.stFlowLayoutPanel1.Controls.Add(this.textBox1);
|
||||
this.stFlowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.stFlowLayoutPanel1.FixedHeight = false;
|
||||
this.stFlowLayoutPanel1.FixedWidth = true;
|
||||
this.stFlowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.stFlowLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.stFlowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
|
||||
@ -75,8 +79,8 @@
|
||||
this.stDropDownPanel1.PanelName = "Skeleton Info";
|
||||
this.stDropDownPanel1.PanelValueName = "";
|
||||
this.stDropDownPanel1.SetIcon = null;
|
||||
this.stDropDownPanel1.SetIconAlphaColor = System.Drawing.Color.Empty;
|
||||
this.stDropDownPanel1.SetIconColor = System.Drawing.Color.Empty;
|
||||
this.stDropDownPanel1.SetIconAlphaColor = System.Drawing.Color.White;
|
||||
this.stDropDownPanel1.SetIconColor = System.Drawing.Color.White;
|
||||
this.stDropDownPanel1.Size = new System.Drawing.Size(434, 108);
|
||||
this.stDropDownPanel1.TabIndex = 0;
|
||||
//
|
||||
@ -86,6 +90,7 @@
|
||||
this.scalingModeCB.BorderStyle = System.Windows.Forms.ButtonBorderStyle.Solid;
|
||||
this.scalingModeCB.ButtonColor = System.Drawing.Color.Empty;
|
||||
this.scalingModeCB.FormattingEnabled = true;
|
||||
this.scalingModeCB.IsReadOnly = false;
|
||||
this.scalingModeCB.Location = new System.Drawing.Point(114, 64);
|
||||
this.scalingModeCB.Name = "scalingModeCB";
|
||||
this.scalingModeCB.Size = new System.Drawing.Size(172, 21);
|
||||
@ -107,6 +112,7 @@
|
||||
this.rotationModeCB.BorderStyle = System.Windows.Forms.ButtonBorderStyle.Solid;
|
||||
this.rotationModeCB.ButtonColor = System.Drawing.Color.Empty;
|
||||
this.rotationModeCB.FormattingEnabled = true;
|
||||
this.rotationModeCB.IsReadOnly = false;
|
||||
this.rotationModeCB.Location = new System.Drawing.Point(114, 37);
|
||||
this.rotationModeCB.Name = "rotationModeCB";
|
||||
this.rotationModeCB.Size = new System.Drawing.Size(172, 21);
|
||||
@ -139,8 +145,8 @@
|
||||
this.stDropDownPanel2.PanelName = "Matricies";
|
||||
this.stDropDownPanel2.PanelValueName = "";
|
||||
this.stDropDownPanel2.SetIcon = null;
|
||||
this.stDropDownPanel2.SetIconAlphaColor = System.Drawing.Color.Empty;
|
||||
this.stDropDownPanel2.SetIconColor = System.Drawing.Color.Empty;
|
||||
this.stDropDownPanel2.SetIconAlphaColor = System.Drawing.Color.White;
|
||||
this.stDropDownPanel2.SetIconColor = System.Drawing.Color.White;
|
||||
this.stDropDownPanel2.Size = new System.Drawing.Size(434, 182);
|
||||
this.stDropDownPanel2.TabIndex = 5;
|
||||
//
|
||||
@ -200,6 +206,19 @@
|
||||
this.stLabel3.TabIndex = 5;
|
||||
this.stLabel3.Text = "Smooth Matrix Indices";
|
||||
//
|
||||
// textBox1
|
||||
//
|
||||
this.textBox1.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.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.textBox1.Location = new System.Drawing.Point(3, 293);
|
||||
this.textBox1.Multiline = true;
|
||||
this.textBox1.Name = "textBox1";
|
||||
this.textBox1.Size = new System.Drawing.Size(428, 332);
|
||||
this.textBox1.TabIndex = 13;
|
||||
this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
|
||||
//
|
||||
// FSKLEditor
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
@ -209,6 +228,7 @@
|
||||
this.Name = "FSKLEditor";
|
||||
this.Size = new System.Drawing.Size(434, 628);
|
||||
this.stFlowLayoutPanel1.ResumeLayout(false);
|
||||
this.stFlowLayoutPanel1.PerformLayout();
|
||||
this.stDropDownPanel1.ResumeLayout(false);
|
||||
this.stDropDownPanel1.PerformLayout();
|
||||
this.stDropDownPanel2.ResumeLayout(false);
|
||||
@ -232,5 +252,6 @@
|
||||
private Toolbox.Library.Forms.STLabel stLabel5;
|
||||
private Toolbox.Library.Forms.STLabel stLabel4;
|
||||
private Toolbox.Library.Forms.STLabel stLabel3;
|
||||
private System.Windows.Forms.TextBox textBox1;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,9 @@ namespace FirstPlugin.Forms
|
||||
|
||||
BackColor = FormThemes.BaseTheme.FormBackColor;
|
||||
ForeColor = FormThemes.BaseTheme.FormForeColor;
|
||||
|
||||
textBox1.BackColor = FormThemes.BaseTheme.ListViewBackColor;
|
||||
textBox1.ForeColor = FormThemes.BaseTheme.FormForeColor;
|
||||
}
|
||||
|
||||
public FSKL activeSkeleton;
|
||||
@ -61,6 +64,12 @@ namespace FirstPlugin.Forms
|
||||
scalingModeCB.SelectedItem = fskl.node.Skeleton.FlagsScaling;
|
||||
}
|
||||
|
||||
if (fskl.node.Skeleton != null && fskl.node.Skeleton.userIndices != null)
|
||||
{
|
||||
var indices = string.Join(",", fskl.node.Skeleton.userIndices);
|
||||
this.textBox1.Text = indices;
|
||||
}
|
||||
|
||||
IsLoaded = true;
|
||||
}
|
||||
|
||||
@ -129,5 +138,23 @@ namespace FirstPlugin.Forms
|
||||
}
|
||||
LibraryGUI.UpdateViewport();
|
||||
}
|
||||
|
||||
private void textBox1_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (activeSkeleton.node.Skeleton != null)
|
||||
{
|
||||
List<ushort> indices = new List<ushort>();
|
||||
|
||||
foreach (var line in textBox1.Text.Split(','))
|
||||
{
|
||||
if (string.IsNullOrEmpty(line))
|
||||
continue;
|
||||
|
||||
if (ushort.TryParse(line, out ushort id))
|
||||
indices.Add(id);
|
||||
}
|
||||
activeSkeleton.node.Skeleton.userIndices = indices.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ namespace FirstPlugin
|
||||
{
|
||||
}
|
||||
|
||||
public bool CombineMipLevel = true;
|
||||
public int Alignment = 512;
|
||||
public bool GammaFix = false;
|
||||
public string TexName;
|
||||
public AccessFlags AccessFlags = AccessFlags.Texture;
|
||||
@ -279,17 +281,20 @@ namespace FirstPlugin
|
||||
|
||||
for (int i = 0; i < arrayFaces.Count; i++)
|
||||
{
|
||||
List<byte[]> mipmaps = SwizzleSurfaceMipMaps(tex, arrayFaces[i], tex.MipCount);
|
||||
List<byte[]> mipmaps = SwizzleSurfaceMipMaps(tex, arrayFaces[i], tex.MipCount, settings.Alignment);
|
||||
tex.TextureData.Add(mipmaps);
|
||||
|
||||
//Combine mip map data
|
||||
byte[] combinedMips = Utils.CombineByteArray(mipmaps.ToArray());
|
||||
tex.TextureData[i][0] = combinedMips;
|
||||
if (settings.Alignment != 1)
|
||||
{
|
||||
byte[] combinedMips = Utils.CombineByteArray(mipmaps.ToArray());
|
||||
tex.TextureData[i][0] = combinedMips;
|
||||
}
|
||||
}
|
||||
|
||||
return tex;
|
||||
}
|
||||
public static List<byte[]> SwizzleSurfaceMipMaps(Texture tex, byte[] data, uint MipCount)
|
||||
public static List<byte[]> SwizzleSurfaceMipMaps(Texture tex, byte[] data, uint MipCount, int alignment = 512)
|
||||
{
|
||||
var TexFormat = TextureData.ConvertFormat(tex.Format);
|
||||
|
||||
@ -319,7 +324,7 @@ namespace FirstPlugin
|
||||
{
|
||||
blockHeight = TegraX1Swizzle.GetBlockHeight(DIV_ROUND_UP(tex.Height, blkHeight));
|
||||
tex.BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1;
|
||||
tex.Alignment = 512;
|
||||
tex.Alignment = alignment;
|
||||
tex.ReadTextureLayout = 1;
|
||||
|
||||
linesPerBlockHeight = blockHeight * 8;
|
||||
@ -346,6 +351,9 @@ namespace FirstPlugin
|
||||
|
||||
|
||||
byte[] AlignedData = new byte[(TegraX1Swizzle.round_up(SurfaceSize, (uint)tex.Alignment) - SurfaceSize)];
|
||||
if (tex.Alignment == 1)
|
||||
AlignedData = new byte[0];
|
||||
|
||||
SurfaceSize += (uint)AlignedData.Length;
|
||||
|
||||
// Console.WriteLine("SurfaceSize Aligned " + AlignedData);
|
||||
@ -372,8 +380,10 @@ namespace FirstPlugin
|
||||
SurfaceSize += Pitch * TegraX1Swizzle.round_up(height__, Math.Max(1, blockHeight >> blockHeightShift) * 8);
|
||||
}
|
||||
|
||||
byte[] SwizzledData = TegraX1Swizzle.swizzle(width_, height_, depth_, blkWidth, blkHeight, blkDepth, target, bpp, (uint)tex.TileMode, (int)Math.Max(0, tex.BlockHeightLog2 - blockHeightShift), data_);
|
||||
byte[] SwizzledData = TegraX1Swizzle.swizzle(width_, height_, depth_, blkWidth, blkHeight, blkDepth, target, bpp, (uint)tex.TileMode, (int)Math.Max(0, tex.BlockHeightLog2 - blockHeightShift), data_, size);
|
||||
mipmaps.Add(AlignedData.Concat(SwizzledData).ToArray());
|
||||
|
||||
Console.WriteLine("SwizzledData " + SwizzledData.Length);
|
||||
}
|
||||
tex.ImageSize = SurfaceSize;
|
||||
|
||||
|
@ -462,6 +462,8 @@ namespace FirstPlugin
|
||||
Formats.Add(typeof(NKN));
|
||||
Formats.Add(typeof(MetroidDreadLibrary.BSMAT));
|
||||
Formats.Add(typeof(TRANM));
|
||||
Formats.Add(typeof(GFA));
|
||||
Formats.Add(typeof(TXTG));
|
||||
|
||||
//Formats.Add(typeof(XLINK_FILE));
|
||||
|
||||
@ -478,7 +480,6 @@ namespace FirstPlugin
|
||||
if (Runtime.DEVELOPER_DEBUG_MODE)
|
||||
{
|
||||
Formats.Add(typeof(BFSAR));
|
||||
Formats.Add(typeof(GFA));
|
||||
}
|
||||
|
||||
|
||||
|
@ -299,46 +299,56 @@ namespace Toolbox.Library.Animations
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int LastFound = 0;
|
||||
float LastFrame;
|
||||
public float GetValue(float frame)
|
||||
private float GetWrapFrame(float frame)
|
||||
{
|
||||
if (Keys.Count == 0)
|
||||
return 0;
|
||||
var lastFrame = Keys.Last().Frame;
|
||||
if (frame < 0 || lastFrame < 0)
|
||||
return frame;
|
||||
|
||||
float startFrame = Keys.First().Frame;
|
||||
return frame;
|
||||
}
|
||||
|
||||
public virtual float GetValue(float frame, float startFrame = 0)
|
||||
{
|
||||
if (Keys.Count == 0) return 0;
|
||||
if (Keys.Count == 1) return Keys[0].Value;
|
||||
KeyFrame LK = Keys.First();
|
||||
KeyFrame RK = Keys.Last();
|
||||
|
||||
float Frame = GetWrapFrame(frame - startFrame);
|
||||
foreach (KeyFrame keyFrame in Keys)
|
||||
{
|
||||
if (keyFrame.Frame <= frame) LK = keyFrame;
|
||||
if (keyFrame.Frame >= frame && keyFrame.Frame < RK.Frame) RK = keyFrame;
|
||||
if (keyFrame.Frame <= Frame) LK = keyFrame;
|
||||
if (keyFrame.Frame >= Frame && keyFrame.Frame < RK.Frame) RK = keyFrame;
|
||||
}
|
||||
if (LK == RK)
|
||||
return LK.Value;
|
||||
|
||||
if (LK.Frame != RK.Frame)
|
||||
return GetInterpolatedValue(Frame, LK, RK);
|
||||
}
|
||||
|
||||
private float GetInterpolatedValue(float Frame, KeyFrame LK, KeyFrame RK)
|
||||
{
|
||||
float FrameDiff = Frame - LK.Frame;
|
||||
float Weight = FrameDiff / (RK.Frame - LK.Frame);
|
||||
|
||||
switch (InterpolationType)
|
||||
{
|
||||
// float FrameDiff = frame - LK.Frame;
|
||||
// float Weight = 1.0f / (RK.Frame - LK.Frame);
|
||||
// float Weight = FrameDiff / (RK.Frame - LK.Frame);
|
||||
case InterpolationType.CONSTANT: return LK.Value;
|
||||
case InterpolationType.STEP: return LK.Value;
|
||||
case InterpolationType.LINEAR: return InterpolationHelper.Lerp(LK.Value, RK.Value, Weight);
|
||||
case InterpolationType.HERMITE:
|
||||
float length = RK.Frame - LK.Frame;
|
||||
|
||||
float FrameDiff = frame - LK.Frame;
|
||||
float Weight = FrameDiff / (RK.Frame - LK.Frame);
|
||||
|
||||
Console.WriteLine($"frame diff {FrameDiff} frame {frame} LK {LK.Frame} RK {RK} ratio {Weight}");
|
||||
|
||||
switch (InterpolationType)
|
||||
{
|
||||
case InterpolationType.CONSTANT: return LK.Value;
|
||||
case InterpolationType.STEP: return LK.Value;
|
||||
case InterpolationType.LINEAR: return InterpolationHelper.Lerp(LK.Value, RK.Value, Weight);
|
||||
case InterpolationType.HERMITE:
|
||||
float val = Hermite(frame, LK.Frame, RK.Frame, LK.In, LK.Out != -1 ? LK.Out : RK.In, LK.Value, RK.Value);
|
||||
return val;
|
||||
}
|
||||
return InterpolationHelper.HermiteInterpolate(Frame,
|
||||
LK.Frame,
|
||||
RK.Frame,
|
||||
LK.Value,
|
||||
RK.Value,
|
||||
LK.Out * length,
|
||||
RK.In * length);
|
||||
}
|
||||
|
||||
return LK.Value;
|
||||
}
|
||||
|
||||
@ -508,7 +518,7 @@ namespace Toolbox.Library.Animations
|
||||
float x = node.XROT.HasAnimation() ? node.XROT.GetValue(Frame) : b.EulerRotation.X;
|
||||
float y = node.YROT.HasAnimation() ? node.YROT.GetValue(Frame) : b.EulerRotation.Y;
|
||||
float z = node.ZROT.HasAnimation() ? node.ZROT.GetValue(Frame) : b.EulerRotation.Z;
|
||||
b.rot = EulerToQuat(z, y, x);
|
||||
b.rot = STMath.FromEulerAngles(new Vector3(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -558,16 +568,37 @@ namespace Toolbox.Library.Animations
|
||||
// return (((cf0 * t + cf1) * t + cf2) * t + cf3);
|
||||
}
|
||||
|
||||
public static float Hermite(float frame, float frame1, float frame2, float outSlope, float inSlope, float val1, float val2)
|
||||
public static float HermiteInterpolate(float frame, float frame1, float frame2,
|
||||
float inSlope, float outSlope, float p0, float p1)
|
||||
{
|
||||
if (frame == frame1) return val1;
|
||||
if (frame == frame2) return val2;
|
||||
if (frame == frame1) return p0;
|
||||
if (frame == frame2) return p1;
|
||||
|
||||
float distance = frame - frame1;
|
||||
float invDuration = 1f / (frame2 - frame1);
|
||||
float t = distance * invDuration;
|
||||
float t1 = t - 1f;
|
||||
return (val1 + ((((val1 - val2) * ((2f * t) - 3f)) * t) * t)) + ((distance * t1) * ((t1 * outSlope) + (t * inSlope)));
|
||||
float t = (frame - frame1) / (frame2 - frame1);
|
||||
return GetPointHermite(p0, p1, outSlope, inSlope, t);
|
||||
}
|
||||
|
||||
private static float GetPointHermite(float p0, float p1, float s0, float s1, float t)
|
||||
{
|
||||
float cf0 = (p0 * 2) + (p1 * -2) + (s0 * 1) + (s1 * 1);
|
||||
float cf1 = (p0 * -3) + (p1 * 3) + (s0 * -2) + (s1 * -1);
|
||||
float cf2 = (p0 * 0) + (p1 * 0) + (s0 * 1) + (s1 * 0);
|
||||
float cf3 = (p0 * 1) + (p1 * 0) + (s0 * 0) + (s1 * 0);
|
||||
return GetPointCubic(cf0, cf1, cf2, cf3, t);
|
||||
}
|
||||
|
||||
private static float GetPointBezier(float p0, float p1, float p2, float p3, float t)
|
||||
{
|
||||
float cf0 = (p0 * -1) + (p1 * 3) + (p2 * -3) + (p3 * 1);
|
||||
float cf1 = (p0 * 3) + (p1 * -6) + (p2 * 3) + (p3 * 0);
|
||||
float cf2 = (p0 * -3) + (p1 * 3) + (p2 * 0) + (p3 * 0);
|
||||
float cf3 = (p0 * 1) + (p1 * 0) + (p2 * 0) + (p3 * 0);
|
||||
return GetPointCubic(cf0, cf1, cf2, cf3, t);
|
||||
}
|
||||
|
||||
private static float GetPointCubic(float cf0, float cf1, float cf2, float cf3, float t)
|
||||
{
|
||||
return (((cf0 * t + cf1) * t + cf2) * t + cf3);
|
||||
}
|
||||
|
||||
public static float Lerp(float av, float bv, float v0, float v1, float t)
|
||||
|
@ -23,27 +23,40 @@ namespace Toolbox.Library.Animations
|
||||
return Result;
|
||||
}
|
||||
|
||||
public static float BezierInterpolate(float frame, float frame1, float frame2,
|
||||
float inSlope, float outSlope, float p0, float p1)
|
||||
public static float BezierInterpolate(float frame, float FrameL, float frameR,
|
||||
float inSlope, float outSlope, float p0, float p1)
|
||||
{
|
||||
if (frame == frame1) return p0;
|
||||
if (frame == frame2) return p1;
|
||||
if (frame == FrameL) return p0;
|
||||
if (frame == frameR) return p1;
|
||||
|
||||
float t = (frame - frame1) / (frame2 - frame1);
|
||||
return GetPointBezier(p0, p1, outSlope, inSlope, t);
|
||||
float t = (frame - FrameL) / (frameR - FrameL);
|
||||
return GetPointBezier(p0, p1, inSlope, outSlope, t);
|
||||
}
|
||||
|
||||
public static float CubicHermiteInterpolate(float frame, float FrameL, float frameR,
|
||||
float cf0, float cf1, float cf2, float cf3)
|
||||
{
|
||||
float t = (frame - FrameL) / (frameR - FrameL);
|
||||
return GetPointCubic(cf3, cf2, cf1, cf0, t);
|
||||
}
|
||||
|
||||
private static float GetPointCubic(float cf0, float cf1, float cf2, float cf3, float t)
|
||||
{
|
||||
return (((cf0 * t + cf1) * t + cf2) * t + cf3);
|
||||
}
|
||||
|
||||
public static float HermiteInterpolate(float frame, float frame1, float frame2,
|
||||
float inSlope, float outSlope, float p0, float p1)
|
||||
float p0, float p1, float s0, float s1)
|
||||
{
|
||||
if (frame == frame1) return p0;
|
||||
if (frame == frame2) return p1;
|
||||
|
||||
float t = (frame - frame1) / (frame2 - frame1);
|
||||
return GetPointHermite(p0, p1, outSlope, inSlope, t);
|
||||
return GetPointHermite(p0, p1, s0, s1, t);
|
||||
}
|
||||
|
||||
private static float GetPointHermite(float p0, float p1, float s0, float s1, float t) {
|
||||
private static float GetPointHermite(float p0, float p1, float s0, float s1, float t)
|
||||
{
|
||||
float cf0 = (p0 * 2) + (p1 * -2) + (s0 * 1) + (s1 * 1);
|
||||
float cf1 = (p0 * -3) + (p1 * 3) + (s0 * -2) + (s1 * -1);
|
||||
float cf2 = (p0 * 0) + (p1 * 0) + (s0 * 1) + (s1 * 0);
|
||||
@ -51,7 +64,8 @@ namespace Toolbox.Library.Animations
|
||||
return GetPointCubic(cf0, cf1, cf2, cf3, t);
|
||||
}
|
||||
|
||||
private static float GetPointBezier(float p0, float p1, float p2, float p3, float t) {
|
||||
private static float GetPointBezier(float p0, float p1, float p2, float p3, float t)
|
||||
{
|
||||
float cf0 = (p0 * -1) + (p1 * 3) + (p2 * -3) + (p3 * 1);
|
||||
float cf1 = (p0 * 3) + (p1 * -6) + (p2 * 3) + (p3 * 0);
|
||||
float cf2 = (p0 * -3) + (p1 * 3) + (p2 * 0) + (p3 * 0);
|
||||
@ -59,11 +73,8 @@ namespace Toolbox.Library.Animations
|
||||
return GetPointCubic(cf0, cf1, cf2, cf3, t);
|
||||
}
|
||||
|
||||
private static float GetPointCubic(float cf0, float cf1, float cf2, float cf3, float t) {
|
||||
return (((cf0 * t + cf1) * t + cf2) * t + cf3);
|
||||
}
|
||||
|
||||
public static float[] CalculateCubicCoef(float frameA, float frameB, float valueA, float valueB, float inSlope, float outSlope) {
|
||||
public static float[] CalculateCubicCoef(float frameA, float frameB, float valueA, float valueB, float inSlope, float outSlope)
|
||||
{
|
||||
return CalculateCubicCoef(frameB - frameA, valueA, valueB, inSlope, outSlope);
|
||||
}
|
||||
|
||||
|
@ -70,9 +70,9 @@ namespace Toolbox.Library
|
||||
return decompressor.Unwrap(b, MaxDecompressedSize);
|
||||
}
|
||||
}
|
||||
public static byte[] SCompress(byte[] b)
|
||||
public static byte[] SCompress(byte[] b, int level = 5)
|
||||
{
|
||||
using (var compressor = new ZstdNet.Compressor())
|
||||
using (var compressor = new ZstdNet.Compressor(new ZstdNet.CompressionOptions(level)))
|
||||
{
|
||||
return compressor.Wrap(b);
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ namespace Toolbox.Library.Animations
|
||||
}
|
||||
}
|
||||
|
||||
return Animation.Hermite (frame+1, f1.input, f2.input, weighted ? f1.t1 : 0, weighted ? f2.t1 : 0, f1.output, f2.output);
|
||||
return Animation.HermiteInterpolate (frame+1, f1.input, f2.input, weighted ? f1.t1 : 0, weighted ? f2.t1 : 0, f1.output, f2.output);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,9 @@ namespace Toolbox.Library
|
||||
{
|
||||
public static class STMath
|
||||
{
|
||||
public const float Deg2Rad = (float)System.Math.PI / 180.0f;
|
||||
public const float Rad2Deg = 180.0f / (float)System.Math.PI;
|
||||
|
||||
private const long SizeOfKb = 1024;
|
||||
private const long SizeOfMb = SizeOfKb * 1024;
|
||||
private const long SizeOfGb = SizeOfMb * 1024;
|
||||
@ -40,11 +43,13 @@ namespace Toolbox.Library
|
||||
|
||||
//From https://github.com/Ploaj/SSBHLib/blob/e37b0d83cd088090f7802be19b1d05ec998f2b6a/CrossMod/Tools/CrossMath.cs#L42
|
||||
//Seems to give good results
|
||||
public static Vector3 ToEulerAngles(double X, double Y, double Z, double W) {
|
||||
public static Vector3 ToEulerAngles(double X, double Y, double Z, double W)
|
||||
{
|
||||
return ToEulerAngles(new Quaternion((float)X, (float)Y, (float)Z, (float)W));
|
||||
}
|
||||
|
||||
public static Vector3 ToEulerAngles(float X, float Y, float Z, float W) {
|
||||
public static Vector3 ToEulerAngles(float X, float Y, float Z, float W)
|
||||
{
|
||||
return ToEulerAngles(new Quaternion(X, Y, Z, W));
|
||||
}
|
||||
|
||||
@ -80,6 +85,70 @@ namespace Toolbox.Library
|
||||
return q;
|
||||
}
|
||||
|
||||
public static Matrix4 RotationFromTo(Vector3 start, Vector3 end)
|
||||
{
|
||||
var axis = Vector3.Cross(start, end).Normalized();
|
||||
var angle = (float)Math.Acos(Vector3.Dot(start, end));
|
||||
return Matrix4.CreateFromAxisAngle(axis, angle);
|
||||
}
|
||||
|
||||
public static Quaternion QuatRotationFromTo(Vector3 start, Vector3 end)
|
||||
{
|
||||
var axis = Vector3.Cross(start, end).Normalized();
|
||||
var angle = (float)Math.Acos(Vector3.Dot(start, end));
|
||||
return Quaternion.FromAxisAngle(axis, angle);
|
||||
}
|
||||
|
||||
public static Vector3 GetEulerAngle(Matrix4 m)
|
||||
{
|
||||
float pitch, yaw, roll; // 3 angles
|
||||
yaw = Rad2Deg * (float)Math.Asin(GetValue(m, 8));
|
||||
if (GetValue(m, 10) < 0)
|
||||
{
|
||||
if (yaw >= 0) yaw = 180.0f - yaw;
|
||||
else yaw = -180.0f - yaw;
|
||||
}
|
||||
|
||||
// find roll (around z-axis) and pitch (around x-axis)
|
||||
// if forward vector is (1,0,0) or (-1,0,0), then m[0]=m[4]=m[9]=m[10]=0
|
||||
if (m.M11 > -double.Epsilon && m.M11 < double.Epsilon)
|
||||
{
|
||||
roll = 0; //@@ assume roll=0
|
||||
pitch = Rad2Deg * (float)Math.Atan2(GetValue(m, 1), GetValue(m, 5));
|
||||
}
|
||||
else
|
||||
{
|
||||
roll = Rad2Deg * (float)Math.Atan2(-GetValue(m, 4), GetValue(m, 0));
|
||||
pitch = Rad2Deg * (float)Math.Atan2(-GetValue(m, 9), GetValue(m, 10));
|
||||
}
|
||||
return new Vector3(pitch, yaw, roll) * Deg2Rad;
|
||||
}
|
||||
|
||||
static float GetValue(Matrix4 mat, int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return mat.M11;
|
||||
case 1: return mat.M12;
|
||||
case 2: return mat.M13;
|
||||
case 3: return mat.M14;
|
||||
case 4: return mat.M21;
|
||||
case 5: return mat.M22;
|
||||
case 6: return mat.M23;
|
||||
case 7: return mat.M24;
|
||||
case 8: return mat.M31;
|
||||
case 9: return mat.M32;
|
||||
case 10: return mat.M33;
|
||||
case 11: return mat.M34;
|
||||
case 12: return mat.M41;
|
||||
case 13: return mat.M42;
|
||||
case 14: return mat.M43;
|
||||
case 15: return mat.M44;
|
||||
default:
|
||||
throw new Exception("Invalid index for 4x4 matrix!");
|
||||
}
|
||||
}
|
||||
|
||||
public static float Clamp(float v, float min, float max)
|
||||
{
|
||||
if (v < min) return min;
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Toolbox.Library
|
||||
{
|
||||
@ -104,6 +105,37 @@ namespace Toolbox.Library
|
||||
return GetImageData(texture, ImageData, ArrayLevel, MipLevel, DepthLevel, BlockHeightLog2, target, LinearTileMode);
|
||||
}
|
||||
|
||||
public static byte[] GetDirectImageData(STGenericTexture texture, byte[] ImageData, int mipLevel, int target = 1, bool LinearTileMode = false)
|
||||
{
|
||||
uint blkWidth = STGenericTexture.GetBlockWidth(texture.Format);
|
||||
uint blkHeight = STGenericTexture.GetBlockHeight(texture.Format);
|
||||
uint blkDepth = STGenericTexture.GetBlockDepth(texture.Format);
|
||||
var blockHeightMip0 = GetBlockHeight(DIV_ROUND_UP(texture.Height, blkHeight));
|
||||
uint bpp = STGenericTexture.GetBytesPerPixel(texture.Format);
|
||||
uint TileMode = LinearTileMode ? 1u : 0u;
|
||||
|
||||
uint width = Math.Max(1, texture.Width >> mipLevel);
|
||||
uint height = Math.Max(1, texture.Height >> mipLevel);
|
||||
uint depth = Math.Max(1, texture.Depth >> mipLevel);
|
||||
uint heightInBlocks = DIV_ROUND_UP(height, blkHeight);
|
||||
// tegra_swizzle only allows block heights supported by the TRM (1,2,4,8,16,32).
|
||||
var mipBlockHeightLog2 = (int)Math.Log(GetMipBlockHeight(heightInBlocks, blockHeightMip0), 2);
|
||||
|
||||
try
|
||||
{
|
||||
byte[] result = deswizzle(width, height, depth, blkWidth, blkHeight, blkDepth, target, bpp, TileMode, mipBlockHeightLog2, ImageData);
|
||||
return result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.Windows.Forms.MessageBox.Show($"Failed to swizzle texture {texture.Text}!");
|
||||
Console.WriteLine(e);
|
||||
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static byte[] GetImageData(STGenericTexture texture, byte[] ImageData, int ArrayLevel, int MipLevel, int DepthLevel, uint BlockHeightLog2, int target = 1, bool LinearTileMode = false)
|
||||
{
|
||||
uint bpp = STGenericTexture.GetBytesPerPixel(texture.Format);
|
||||
@ -179,7 +211,7 @@ namespace Toolbox.Library
|
||||
}
|
||||
|
||||
private static unsafe byte[] SwizzleDeswizzleBlockLinear(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth,
|
||||
uint bpp, int blockHeightLog2, byte[] data, bool deswizzle)
|
||||
uint bpp, int blockHeightLog2, byte[] data, bool deswizzle, uint size, uint alignment = 512)
|
||||
{
|
||||
// This function expects the surface dimensions in blocks rather than pixels for block compressed formats.
|
||||
// This ensures the bytes per pixel parameter is used correctly.
|
||||
@ -245,17 +277,17 @@ namespace Toolbox.Library
|
||||
public static byte[] deswizzle(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth, int roundPitch, uint bpp, uint tileMode, int blockHeightLog2, byte[] data)
|
||||
{
|
||||
if (tileMode == 1)
|
||||
return SwizzlePitchLinear(width, height, depth, blkWidth, blkHeight, blkDepth, roundPitch, bpp, blockHeightLog2, data, true);
|
||||
return SwizzlePitchLinear(width, height, depth, blkWidth, blkHeight, blkDepth, roundPitch, bpp, blockHeightLog2, data, true, 0);
|
||||
else
|
||||
return SwizzleDeswizzleBlockLinear(width, height, depth, blkWidth, blkHeight, blkDepth, bpp, blockHeightLog2, data, true);
|
||||
return SwizzleDeswizzleBlockLinear(width, height, depth, blkWidth, blkHeight, blkDepth, bpp, blockHeightLog2, data, true, 0);
|
||||
}
|
||||
|
||||
public static byte[] swizzle(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth, int roundPitch, uint bpp, uint tileMode, int blockHeightLog2, byte[] data)
|
||||
public static byte[] swizzle(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth, int roundPitch, uint bpp, uint tileMode, int blockHeightLog2, byte[] data, uint size)
|
||||
{
|
||||
if (tileMode == 1)
|
||||
return SwizzlePitchLinear(width, height, depth, blkWidth, blkHeight, blkDepth, roundPitch, bpp, blockHeightLog2, data, false);
|
||||
return SwizzlePitchLinear(width, height, depth, blkWidth, blkHeight, blkDepth, roundPitch, bpp, blockHeightLog2, data, false, size);
|
||||
else
|
||||
return SwizzleDeswizzleBlockLinear(width, height, depth, blkWidth, blkHeight, blkDepth, bpp, blockHeightLog2, data, false);
|
||||
return SwizzleDeswizzleBlockLinear(width, height, depth, blkWidth, blkHeight, blkDepth, bpp, blockHeightLog2, data, false, size);
|
||||
}
|
||||
|
||||
|
||||
@ -283,7 +315,7 @@ namespace Toolbox.Library
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
private static byte[] SwizzlePitchLinear(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth, int roundPitch, uint bpp, int blockHeightLog2, byte[] data, bool deswizzle)
|
||||
private static byte[] SwizzlePitchLinear(uint width, uint height, uint depth, uint blkWidth, uint blkHeight, uint blkDepth, int roundPitch, uint bpp, int blockHeightLog2, byte[] data, bool deswizzle, uint size)
|
||||
{
|
||||
// TODO: Investigate doing this more efficiently in Rust.
|
||||
width = DIV_ROUND_UP(width, blkWidth);
|
||||
|
@ -439,6 +439,7 @@
|
||||
<Compile Include="IO\Colors\STColor.cs" />
|
||||
<Compile Include="IO\Colors\STColor8.cs" />
|
||||
<Compile Include="IO\SubStream.cs" />
|
||||
<Compile Include="Maths\STMath.cs" />
|
||||
<Compile Include="OpenGL\GLShaderGeneric.cs" />
|
||||
<Compile Include="OpenGL\IPickableObject.cs" />
|
||||
<Compile Include="OpenGL\OpenGL2DEnums.cs" />
|
||||
@ -872,7 +873,6 @@
|
||||
<Compile Include="IO\Extensions\StreamReaderExtensions.cs" />
|
||||
<Compile Include="IO\Extensions\StringExtension.cs" />
|
||||
<Compile Include="IO\STStream.cs" />
|
||||
<Compile Include="Maths\Math.cs" />
|
||||
<Compile Include="Plugin\GenericPluginLoader.cs" />
|
||||
<Compile Include="Forms\Animation\AnimationPanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
@ -965,6 +965,7 @@
|
||||
<Compile Include="Util\ImageUtilty.cs" />
|
||||
<Compile Include="Util\OpenGLUtils.cs" />
|
||||
<Compile Include="Util\Util.cs" />
|
||||
<Compile Include="Util\WebUtil.cs" />
|
||||
<Compile Include="XML\XmlDoc.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
34
Switch_Toolbox_Library/Util/WebUtil.cs
Normal file
34
Switch_Toolbox_Library/Util/WebUtil.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Toolbox.Library
|
||||
{
|
||||
public class WebUtil
|
||||
{
|
||||
public static void OpenDonation() {
|
||||
OpenURLEncoded("aHR0cHM6Ly9rby1maS5jb20vc2ltcGx5a3hn");
|
||||
}
|
||||
|
||||
public static void OpenURLEncoded(string encodedString)
|
||||
{
|
||||
byte[] data = Convert.FromBase64String(encodedString);
|
||||
OpenURL(Encoding.UTF8.GetString(data));
|
||||
}
|
||||
|
||||
public static void OpenURL(string url)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
|
||||
Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }); // Works ok on windows
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) {
|
||||
Process.Start("xdg-open", url); // Works ok on linux
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) {
|
||||
Process.Start("open", url); // Not tested
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
@ -2013,7 +2013,7 @@
|
||||
</member>
|
||||
<member name="M:Syroot.NintenTools.NSW.Bfres.Core.ResFileLoader.ReadOffsets(System.Int32)">
|
||||
<summary>
|
||||
Reads BFRES offsets which is the absolute addresses.
|
||||
Reads BFRES offsets which is the absolute addresses.+
|
||||
</summary>
|
||||
<param name="count">The number of offsets to read.</param>
|
||||
<returns>The absolute addresses of the offsets.</returns>
|
||||
@ -2275,7 +2275,7 @@
|
||||
<param name="str">The name to save.</param>
|
||||
<param name="encoding">The <see cref="T:System.Text.Encoding"/> in which the name will be stored.</param>
|
||||
</member>
|
||||
<member name="M:Syroot.NintenTools.NSW.Bfres.Core.ResFileSaver.SaveStrings(System.Collections.Generic.IEnumerable{System.String},System.Text.Encoding)">
|
||||
<member name="M:Syroot.NintenTools.NSW.Bfres.Core.ResFileSaver.SaveStrings(System.Collections.Generic.IEnumerable{System.String},System.Boolean,System.Text.Encoding)">
|
||||
<summary>
|
||||
Reserves space for offsets to the <paramref name="strings"/> written later in the string pool with the
|
||||
specified <paramref name="encoding"/>
|
||||
@ -3160,6 +3160,11 @@
|
||||
Gets or sets the <see cref="T:Syroot.NintenTools.NSW.Bfres.Material"/> instance applied on the <see cref="P:Syroot.NintenTools.NSW.Bfres.Model.Shapes"/> to color their surface.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:Syroot.NintenTools.NSW.Bfres.Model.ShaderAssigns">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Syroot.NintenTools.NSW.Bfres.Model.UserDataDict">
|
||||
<summary>
|
||||
Gets or sets customly attached <see cref="P:Syroot.NintenTools.NSW.Bfres.Model.UserData"/> names.
|
||||
@ -3713,7 +3718,7 @@
|
||||
rigidbodies (no skinning), 1 equal rigid skinning and 2 or more smooth skinning.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Syroot.NintenTools.NSW.Bfres.VertexBuffer.VertexCount">
|
||||
<member name="F:Syroot.NintenTools.NSW.Bfres.VertexBuffer.VertexCount">
|
||||
<summary>
|
||||
Gets the number of vertices stored by the <see cref="P:Syroot.NintenTools.NSW.Bfres.VertexBuffer.Buffers"/>. It is calculated from the size of the first
|
||||
<see cref="!:Buffer"/> in bytes divided by the <see cref="P:Syroot.NintenTools.NSW.Bfres.VertexBuffer.StrideArray"/>.
|
||||
@ -4850,6 +4855,16 @@
|
||||
Gets or sets <see cref="T:Syroot.NintenTools.NSW.Bfres.AnimCurve"/> instances animating properties of objects stored in this section.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Syroot.NintenTools.NSW.Bfres.BoneAnim.UserDataDict">
|
||||
<summary>
|
||||
Gets or sets customly attached <see cref="P:Syroot.NintenTools.NSW.Bfres.BoneAnim.UserData"/> names.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Syroot.NintenTools.NSW.Bfres.BoneAnim.UserData">
|
||||
<summary>
|
||||
Gets or sets customly attached <see cref="P:Syroot.NintenTools.NSW.Bfres.BoneAnim.UserData"/> instances.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Syroot.NintenTools.NSW.Bfres.BoneAnim.BaseData">
|
||||
<summary>
|
||||
Gets or sets initial transformation values. Only stores specific transformations according to
|
||||
@ -5173,6 +5188,12 @@
|
||||
Euler XYZ, 3 components.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Syroot.NintenTools.NSW.Bfres.StringCache">
|
||||
<summary>
|
||||
A cache of strings that are saved through raw IDs in place of the pointer field of a name offset.
|
||||
This is used and required for TOTK models.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Syroot.NintenTools.NSW.Bfres.VisibilityAnim">
|
||||
<summary>
|
||||
Represents an FVIS subfile in a <see cref="T:Syroot.NintenTools.NSW.Bfres.ResFile"/>, storing visibility animations of <see cref="T:Syroot.NintenTools.NSW.Bfres.Bone"/> or
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user