Fix bugs related to bones.

Fixed bones not displaying when creating new skeletons.
Fixed importing dae bones not displaying properly in the tree.
Fixed bones not clearing when a model is removed
This commit is contained in:
KillzXGaming 2019-03-24 11:24:40 -04:00
parent 89e8980cdb
commit 233b11a022
19 changed files with 222 additions and 96 deletions

Binary file not shown.

View file

@ -146,6 +146,29 @@ namespace FirstPlugin
editor.Refresh();
}
//Used for adding new skeleton drawables
public void AddSkeletonDrawable(STSkeleton skeleton)
{
BfresEditor bfresEditor = (BfresEditor)LibraryGUI.Instance.GetActiveContent(typeof(BfresEditor));
if (bfresEditor != null)
{
bfresEditor.AddDrawable(skeleton);
}
drawables.Add(skeleton);
}
public void RemoveSkeletonDrawable(STSkeleton skeleton)
{
BfresEditor bfresEditor = (BfresEditor)LibraryGUI.Instance.GetActiveContent(typeof(BfresEditor));
if (bfresEditor != null)
{
bfresEditor.RemoveDrawable(skeleton);
}
drawables.Remove(skeleton);
}
List<AbstractGlDrawable> drawables = new List<AbstractGlDrawable>();
public void LoadEditors(object SelectedSection)
{

View file

@ -148,8 +148,8 @@ namespace Bfres.Structs
fmdl.ModelU.Shapes.Add("NewShape", shape);
fmdl.ModelU.Materials.Add("NewMaterial", new ResU.Material() { Name = "NewMaterial" });
BfresWiiU.ReadModel(fmdl, fmdl.ModelU);
((BFRES)Parent).AddSkeletonDrawable(fmdl.Skeleton);
}
else
{
@ -175,6 +175,7 @@ namespace Bfres.Structs
fmdl.Model.VertexBuffers.Add(VertexBuffer);
BfresSwitch.ReadModel(fmdl, fmdl.Model);
((BFRES)Parent).AddSkeletonDrawable(fmdl.Skeleton);
}
AddNode(fmdl, "NewModel");
@ -244,6 +245,9 @@ namespace Bfres.Structs
fmdl.ModelU.Skeleton = skeleton;
fmdl.ModelU.Shapes.Add("NeShape", new ResU.Shape() { Name = "NeShape" });
fmdl.ModelU.VertexBuffers.Add(new ResU.VertexBuffer() { });
BfresWiiU.ReadModel(fmdl, fmdl.ModelU);
((BFRES)Parent).AddSkeletonDrawable(fmdl.Skeleton);
}
else
{
@ -259,6 +263,7 @@ namespace Bfres.Structs
fmdl.Model.VertexBuffers.Add(new ResNX.VertexBuffer() { });
BfresSwitch.ReadModel(fmdl, fmdl.Model);
((BFRES)Parent).AddSkeletonDrawable(fmdl.Skeleton);
}
fmdl.Replace(FileName, resFileNX, resFileU);
@ -387,14 +392,13 @@ namespace Bfres.Structs
{
foreach (var node in Nodes)
{
if (node is STGenericWrapper)
if (node is STGenericWrapper)
{
((STGenericWrapper)node).Unload();
RemoveChild(((STGenericWrapper)node));
}
}
Nodes.Clear();
}
}

View file

@ -99,6 +99,8 @@ namespace Bfres.Structs
if (dialogResult == DialogResult.Yes)
{
((BFRES)Parent.Parent).RemoveSkeletonDrawable(Skeleton);
shapes.Clear();
materials.Clear();
@ -418,6 +420,16 @@ namespace Bfres.Structs
}
}
public override void Unload()
{
if (Parent != null)
((BFRES)Parent.Parent).RemoveSkeletonDrawable(Skeleton);
shapes.Clear();
materials.Clear();
Nodes.Clear();
}
public override string ExportFilter => FileFilters.GetFilter(typeof(FMDL));
public override void Export(string FileName)
@ -589,9 +601,9 @@ namespace Bfres.Structs
//Todo find better way. Currently uses import settings now
shape.ApplyImportSettings(csvsettings, GetMaterial(shape.MaterialIndex));
shape.VertexSkinCount = obj.GetMaxSkinInfluenceCount();
shape.BoneIndices = shape.GetIndices(Skeleton);
shape.SaveShape(IsWiiU);
shape.SaveVertexBuffer();
shape.BoneIndices = new List<ushort>();
if (IsWiiU)
{
@ -609,6 +621,16 @@ namespace Bfres.Structs
});
}
if (IsWiiU)
{
BfresWiiU.ReadShapesVertices(shape, shape.ShapeU, shape.VertexBufferU, this);
}
else
{
BfresSwitch.ReadShapesVertices(shape, shape.Shape, shape.VertexBuffer, this);
}
Nodes["FshpFolder"].Nodes.Add(shape);
shapes.Add(shape);
}
@ -794,15 +816,11 @@ namespace Bfres.Structs
if (assimp.skeleton.bones.Count > 0)
{
Skeleton.bones.Clear();
foreach (var bone in assimp.skeleton.bones)
{
Skeleton.bones.Add(bone);
}
if (IsWiiU)
BfresWiiU.SaveSkeleton(Skeleton);
BfresWiiU.SaveSkeleton(Skeleton, assimp.skeleton.bones);
else
BfresSwitch.SaveSkeleton(Skeleton);
BfresSwitch.SaveSkeleton(Skeleton, assimp.skeleton.bones);
}
}
@ -854,10 +872,10 @@ namespace Bfres.Structs
shape.CreateIndexList(obj, this);
shape.ApplyImportSettings(settings, GetMaterial(shape.MaterialIndex));
shape.VertexSkinCount = obj.GetMaxSkinInfluenceCount();
shape.BoneIndices = shape.GetIndices(Skeleton);
shape.SaveShape(IsWiiU);
shape.SaveVertexBuffer();
shape.BoneIndices = new List<ushort>();
if (IsWiiU)
{

View file

@ -876,15 +876,28 @@ namespace Bfres.Structs
else
Shape = BfresSwitch.SaveShape(this);
}
public IList<ushort> GetIndices()
public List<ushort> GetIndices(FSKL fskl)
{
IList<ushort> indices = new List<ushort>();
List<ushort> indices = new List<ushort>();
List<string> BoneNodes = new List<string>();
foreach (Vertex vtx in vertices)
{
foreach (int index in vtx.boneIds)
{
var bone = fskl.bones[fskl.Node_Array[index]];
ushort ind = (ushort)fskl.bones.IndexOf(bone);
if (!indices.Contains(ind))
{
STConsole.WriteLine($"Saving bone index {bone.Name} {index}");
indices.Add(ind);
}
}
}
STConsole.WriteLine($"Total Indices for {Text} {indices.Count}");
return indices;
}
public Vector3 TransformLocal(Vector3 position, bool IsPos = true)

View file

@ -211,6 +211,36 @@ namespace Bfres.Structs
SmoothMatrixIndex = genericBone.SmoothMatrixIndex;
}
public void GenericToBfresBone()
{
if (BoneU != null)
{
BoneU.Position = new Syroot.Maths.Vector3F(position[0], position[1], position[2]);
BoneU.Scale = new Syroot.Maths.Vector3F(scale[0], scale[1], scale[2]);
BoneU.Rotation = new Syroot.Maths.Vector4F(rotation[0], rotation[1], rotation[2], rotation[3]);
BoneU.Name = Text;
BoneU.Flags = FlagVisible ? ResU.BoneFlags.Visible : 0;
BoneU.ParentIndex = (ushort)parentIndex;
BoneU.SmoothMatrixIndex = SmoothMatrixIndex;
BoneU.RigidMatrixIndex = RigidMatrixIndex;
SetTransforms();
}
else
{
Bone.Position = new Syroot.Maths.Vector3F(position[0], position[1], position[2]);
Bone.Scale = new Syroot.Maths.Vector3F(scale[0], scale[1], scale[2]);
Bone.Rotation = new Syroot.Maths.Vector4F(rotation[0], rotation[1], rotation[2], rotation[3]);
Bone.Name = Text;
Bone.Flags = FlagVisible ? BoneFlags.Visible : 0;
Bone.ParentIndex = (ushort)parentIndex;
Bone.SmoothMatrixIndex = SmoothMatrixIndex;
Bone.RigidMatrixIndex = RigidMatrixIndex;
SetTransforms();
}
}
public void SetTransforms()
{
if (BoneU != null)

View file

@ -125,7 +125,6 @@ namespace FirstPlugin
Shape.KeyShapes = new List<KeyShape>();
Shape.KeyShapeDict = new ResDict();
Shape.Name = fshp.Text;
Shape.SkinBoneIndices = fshp.GetIndices();
Shape.TargetAttribCount = (byte)fshp.TargetAttribCount;
Shape.SkinBoneIndices = fshp.BoneIndices;
Shape.SubMeshBoundings = new List<Bounding>();
@ -525,11 +524,13 @@ namespace FirstPlugin
ReadBone(STBone, bone);
RenderableSkeleton.bones.Add(STBone);
}
foreach (var bone in RenderableSkeleton.bones)
foreach (var bone in RenderableSkeleton.bones){
if (bone.Parent == null)
{
skl.Nodes.Add(bone);
}
}
RenderableSkeleton.update();
RenderableSkeleton.reset();
@ -566,49 +567,55 @@ namespace FirstPlugin
bone.position[2] = bn.Position.Z;
}
public static void SaveSkeleton(FSKL fskl)
public static void SaveSkeleton(FSKL fskl, List<STBone> Bones)
{
fskl.node.Skeleton.Bones.Clear();
fskl.node.Skeleton.MatrixToBoneList = new List<ushort>();
fskl.node.Skeleton.InverseModelMatrices = new List<Syroot.Maths.Matrix3x4>();
fskl.node.Nodes.Clear();
ushort SmoothIndex = 0;
foreach (STBone genericBone in fskl.bones)
foreach (STBone genericBone in Bones)
{
STConsole.WriteLine($"Applying bone " + genericBone.Text);
genericBone.BillboardIndex = ushort.MaxValue;
STConsole.WriteLine($"Applying bone " + genericBone.Text);
//Clone a generic bone with the generic data
BfresBone bn = new BfresBone(fskl);
bn.CloneBaseInstance(genericBone);
//Set the bfres bone data
if (bn.Bone == null)
bn.Bone = new Bone();
bn.Bone.Position = new Syroot.Maths.Vector3F(bn.position[0], bn.position[1], bn.position[2]);
bn.Bone.Scale = new Syroot.Maths.Vector3F(bn.scale[0], bn.scale[1], bn.scale[2]);
bn.Bone.Rotation = new Syroot.Maths.Vector4F(bn.rotation[0], bn.rotation[1], bn.rotation[2], bn.rotation[3]);
bn.Bone.Name = bn.Text;
bn.Bone.Flags = bn.FlagVisible ? BoneFlags.Visible : 0;
bn.Bone.ParentIndex = (ushort)bn.parentIndex;
bn.Bone.SmoothMatrixIndex = bn.SmoothMatrixIndex;
bn.Bone.RigidMatrixIndex = bn.RigidMatrixIndex;
bn.SetTransforms();
fskl.node.Skeleton.Bones.Add(bn.Bone);
if (bn.Parent == null)
fskl.node.Nodes.Add(bn);
bn.GenericToBfresBone();
if (bn.SmoothMatrixIndex != short.MaxValue)
fskl.node.Skeleton.MatrixToBoneList.Add(SmoothIndex++);
fskl.node.Skeleton.InverseModelMatrices.Add(Syroot.Maths.Matrix3x4.Zero);
fskl.bones.Add(bn);
}
foreach (BfresBone wrapper in fskl.bones)
{
//Check duplicated names
// List<string> names = fskl.bones.Select(o => o.Text).ToList();
// wrapper.Text = Utils.RenameDuplicateString(names, wrapper.Text);
wrapper.Bone.Name = wrapper.Text;
fskl.node.Skeleton.Bones.Add(wrapper.Bone);
//Add bones to tree
if (wrapper.Parent == null)
{
fskl.node.Nodes.Add(wrapper);
}
}
fskl.update();
fskl.reset();
fskl.Node_Array = new int[fskl.node.Skeleton.MatrixToBoneList.Count];
int nodes = 0;
foreach (ushort node in fskl.node.Skeleton.MatrixToBoneList)

View file

@ -876,7 +876,7 @@ namespace FirstPlugin
}
return ShapeU;
}
public static void SaveSkeleton(FSKL fskl)
public static void SaveSkeleton(FSKL fskl, List<STBone> Bones)
{
fskl.node.SkeletonU.Bones.Clear();
fskl.node.SkeletonU.MatrixToBoneList = new List<ushort>();
@ -885,37 +885,42 @@ namespace FirstPlugin
fskl.node.Nodes.Clear();
ushort SmoothIndex = 0;
foreach (STBone genericBone in fskl.bones)
foreach (STBone genericBone in Bones)
{
genericBone.BillboardIndex = ushort.MaxValue;
//Clone a generic bone with the generic data
BfresBone bn = new BfresBone(fskl);
bn.CloneBaseInstance(genericBone);
//Set the bfres bone data
if (bn.BoneU == null)
bn.BoneU = new Bone();
bn.BoneU.Position = new Syroot.Maths.Vector3F(bn.position[0], bn.position[1], bn.position[2]);
bn.BoneU.Scale = new Syroot.Maths.Vector3F(bn.scale[0], bn.scale[1], bn.scale[2]);
bn.BoneU.Rotation = new Syroot.Maths.Vector4F(bn.rotation[0], bn.rotation[1], bn.rotation[2], bn.rotation[3]);
bn.BoneU.Name = bn.Text;
bn.BoneU.Flags = bn.FlagVisible ? BoneFlags.Visible : 0;
bn.BoneU.ParentIndex = (ushort)bn.parentIndex;
bn.SetTransforms();
bn.BoneU.SmoothMatrixIndex = bn.SmoothMatrixIndex;
bn.BoneU.RigidMatrixIndex = bn.RigidMatrixIndex;
fskl.node.SkeletonU.Bones.Add(bn.Text, bn.BoneU);
if (bn.Parent == null)
fskl.node.Nodes.Add(bn);
bn.GenericToBfresBone();
if (bn.SmoothMatrixIndex != short.MaxValue)
fskl.node.SkeletonU.MatrixToBoneList.Add(SmoothIndex++);
fskl.node.SkeletonU.InverseModelMatrices.Add(Syroot.Maths.Matrix3x4.Zero);
fskl.bones.Add(bn);
}
foreach (BfresBone wrapper in fskl.bones)
{
//Check duplicated names
List<string> names = fskl.bones.Select(o => o.Text).ToList();
wrapper.Text = Utils.RenameDuplicateString(names, wrapper.Text);
wrapper.BoneU.Name = wrapper.Text;
fskl.node.SkeletonU.Bones.Add(wrapper.Text, wrapper.BoneU);
//Add bones to tree
if (wrapper.Parent == null)
{
fskl.node.Nodes.Add(wrapper);
}
}
fskl.Node_Array = new int[fskl.node.SkeletonU.MatrixToBoneList.Count];
int nodes = 0;

View file

@ -108,6 +108,22 @@ namespace FirstPlugin.Forms
}
}
public void AddDrawable(AbstractGlDrawable draw)
{
Drawables.Add(draw);
if (!viewport.scene.staticObjects.Contains(draw) &&
!viewport.scene.objects.Contains(draw))
{
viewport.AddDrawable(draw);
}
}
public void RemoveDrawable(AbstractGlDrawable draw)
{
Drawables.Remove(draw);
viewport.RemoveDrawable(draw);
}
public override void OnControlClosing()
{

View file

@ -265,47 +265,54 @@ namespace Switch_Toolbox.Library
Matrix4x4 world = trafo * rootTransform;
var transformMat = AssimpHelper.TKMatrix(world);
int matchedBoneIndex = skeleton.bones.FindIndex(item => item.Name == node.Name);
tempBoneNodes.Add(node);
STBone bone = new STBone();
bone.skeletonParent = skeleton;
skeleton.bones.Add(bone);
bone.Text = node.Name;
bone.SmoothMatrixIndex = (short)skeleton.bones.IndexOf(bone);
bone.RigidMatrixIndex = -1; //Todo calculate these
STConsole.WriteLine($"-".Repeat(30));
STConsole.WriteLine($"Processing Bone {bone.Text}");
STConsole.WriteLine($"SmoothMatrixIndex {bone.SmoothMatrixIndex}");
STConsole.WriteLine($"RigidMatrixIndex {bone.RigidMatrixIndex}");
STConsole.WriteLine($"Transform Matrix {transformMat}");
STConsole.WriteLine($"-".Repeat(30));
if (IsRoot)
if (matchedBoneIndex < 0)
{
bone.parentIndex = -1;
transformMat = AssimpHelper.TKMatrix(world * Matrix4x4.FromRotationX(MathHelper.DegreesToRadians(BoneRotation)));
tempBoneNodes.Add(node);
STBone bone = new STBone();
bone.skeletonParent = skeleton;
skeleton.bones.Add(bone);
bone.Text = node.Name;
bone.SmoothMatrixIndex = (short)skeleton.bones.IndexOf(bone);
bone.RigidMatrixIndex = -1; //Todo calculate these
STConsole.WriteLine($"-".Repeat(30));
STConsole.WriteLine($"Processing Bone {bone.Text}");
STConsole.WriteLine($"SmoothMatrixIndex {bone.SmoothMatrixIndex}");
STConsole.WriteLine($"RigidMatrixIndex {bone.RigidMatrixIndex}");
STConsole.WriteLine($"Transform Matrix {transformMat}");
STConsole.WriteLine($"-".Repeat(30));
if (IsRoot)
{
bone.parentIndex = -1;
transformMat = AssimpHelper.TKMatrix(world * Matrix4x4.FromRotationX(MathHelper.DegreesToRadians(BoneRotation)));
}
else
{
if (tempBoneNodes.Contains(node.Parent))
bone.parentIndex = tempBoneNodes.IndexOf(node.Parent);
}
var scale = transformMat.ExtractScale();
var rotation = transformMat.ExtractRotation();
var position = transformMat.ExtractTranslation();
var rotEular = AssimpHelper.ToEular(rotation);
bone.position = new float[] { position.X, position.Y, position.Z };
bone.scale = new float[] { scale.X, scale.Y, scale.Z };
bone.rotation = new float[] { rotEular.X, rotEular.Y, rotEular.Z, 0 };
}
else
{
if (tempBoneNodes.Contains(node.Parent))
bone.parentIndex = tempBoneNodes.IndexOf(node.Parent);
STConsole.WriteLine($"Duplicate node name found for bone {node.Name}!", Color.Red);
}
var scale = transformMat.ExtractScale();
var rotation = transformMat.ExtractRotation();
var position = transformMat.ExtractTranslation();
var rotEular = AssimpHelper.ToEular(rotation);
bone.position = new float[] { position.X, position.Y, position.Z };
bone.scale = new float[] { scale.X, scale.Y, scale.Z };
bone.rotation = new float[] { rotEular.X, rotEular.Y, rotEular.Z, 0 };
foreach (Node child in node.Children)
CreateByNode(child, skeleton, SmoothIndex, RigidIndex, false, ref rootTransform);
}

View file

@ -112,9 +112,11 @@ namespace Switch_Toolbox.Library
public void AddDrawable(AbstractGlDrawable Drawabale)
{
if (Drawabale is EditableObject)
editor.editableDrawables.Add((EditableObject)Drawabale);
scene.objects.Add((EditableObject)Drawabale);
else
editor.staticDrawables.Add(Drawabale);
scene.staticObjects.Add(Drawabale);
UpdateScene();
}
public void RemoveDrawable(AbstractGlDrawable Drawabale)

View file

@ -224,7 +224,7 @@ namespace Switch_Toolbox.Library
{
CheckBuffers();
if (!Runtime.OpenTKInitialized || !Runtime.renderBones)
if (!Runtime.OpenTKInitialized || !Runtime.renderBones || solidColorShaderProgram == null)
return;
GL.UseProgram(0);

View file

@ -150,7 +150,7 @@ BakedData ShadowMapBaked(sampler2D ShadowMap, sampler2D LightMap, vec2 texCoordB
vec3 CalcBumpedNormal(vec3 normal, sampler2D normalMap, VertexAttributes vert, float texCoordIndex);
//float AmbientOcclusionBlend(sampler2D BakeShadowMap, VertexAttributes vert, float ao_density);
//vec3 EmissionPass(sampler2D EmissionMap, float emission_intensity, VertexAttributes vert, float texCoordIndex, vec3 emission_color);
vec3 EmissionPass(sampler2D EmissionMap, float emission_intensity, VertexAttributes vert, float texCoordIndex, vec3 emission_color);
// Shader code adapted from learnopengl.com's PBR tutorial:
// https://learnopengl.com/PBR/Theory
@ -253,9 +253,9 @@ void main()
float cavity = 1;
vec3 emission = vec3(0);
// if (HasEmissionMap == 1 || enable_emission == 1) //Can be without texture map
// emission.rgb += EmissionPass(EmissionMap, emission_intensity, vert, 0, emission_color);
vec3 emissionTerm = vec3(0);
if (HasEmissionMap == 1 || enable_emission == 1) //Can be without texture map
emissionTerm.rgb += EmissionPass(EmissionMap, emission_intensity, vert, 0, emission_color);
vec3 lightMapColor = vec3(1);
float lightMapIntensity = 0;
@ -310,7 +310,7 @@ void main()
diffuseTerm *= cavity;
diffuseTerm *= ao;
diffuseTerm *= shadow;
diffuseTerm += LightingDiffuse;
diffuseTerm += LightingDiffuse;
// Adjust for metalness.
// diffuseTerm *= clamp(1 - metallic, 0, 1);
@ -332,6 +332,7 @@ void main()
fragColor.rgb = vec3(0);
fragColor.rgb += diffuseTerm;
fragColor.rgb += specularTerm;
fragColor.rgb += emissionTerm;
// Global brightness adjustment.
fragColor.rgb *= 2.5;