private void LoadSkeleton() { ObjectTreeNode skeletonFolder = new ObjectTreeNode("Skeleton"); this.AddChild(skeletonFolder); for (int i = 0; i < Header.ObjectCount; i++) { var info = Header.ObjectData.Objects[i]; var name = Header.ObjectData.ObjectNames[i]; if (name == string.Empty) { name = $"Object_{i}"; } //Add a dummy bone. Some bone data is set at runtime and uses large random values if (info.ChildrenCount > Header.ObjectCount) { Skeleton.Bones.Add(new HSFBoneWrapper(info, Skeleton) { Name = name, ParentIndex = -1, Position = new Vector3(), Scale = Vector3.One, EulerRotation = new Vector3(), }); } else { Skeleton.Bones.Add(new HSFBoneWrapper(info, Skeleton) { Name = name, ParentIndex = -1, Position = new OpenTK.Vector3( info.BaseTransform.Translate.X, info.BaseTransform.Translate.Y, info.BaseTransform.Translate.Z) * HSF_Renderer.PreviewScale, EulerRotation = new OpenTK.Vector3( MathHelper.DegreesToRadians(info.BaseTransform.Rotate.X), MathHelper.DegreesToRadians(info.BaseTransform.Rotate.Y), MathHelper.DegreesToRadians(info.BaseTransform.Rotate.Z)), Scale = new OpenTK.Vector3( info.BaseTransform.Scale.X == 0 ? 1 : info.BaseTransform.Scale.X, info.BaseTransform.Scale.Y == 0 ? 1 : info.BaseTransform.Scale.Y, info.BaseTransform.Scale.Z == 0 ? 1 : info.BaseTransform.Scale.Z), }); } } for (int i = 0; i < Header.ObjectCount; i++) { if (Header.ObjectData.Objects[i].ChildrenCount > Header.ObjectCount) { Skeleton.Bones[i].ParentIndex = -1; } else { Skeleton.Bones[i].ParentIndex = Header.ObjectData.Objects[i].ParentIndex; } } var boneNodes = Skeleton.CreateBoneTree(); foreach (var bone in boneNodes) { skeletonFolder.AddChild(bone); } Skeleton.PreviewScale = 0.05f; Skeleton.Reset(); Skeleton.Update(); }