Example #1
0
        public static RSkeleton CreateRSkeleton(Skel skel)
        {
            if (skel == null)
            {
                return(null);
            }

            var skeleton = new RSkeleton();

            for (int i = 0; i < skel.BoneEntries.Length; i++)
            {
                RBone bone = new RBone
                {
                    Name              = skel.BoneEntries[i].Name,
                    Id                = skel.BoneEntries[i].Id,
                    ParentId          = skel.BoneEntries[i].ParentId,
                    Transform         = skel.Transform[i].ToOpenTK(),
                    InvTransform      = skel.InvTransform[i].ToOpenTK(),
                    WorldTransform    = skel.WorldTransform[i].ToOpenTK(),
                    InvWorldTransform = skel.InvWorldTransform[i].ToOpenTK()
                };
                skeleton.Bones.Add(bone);
            }

            skeleton.Reset();

            return(skeleton);
        }
Example #2
0
 public override void Open()
 {
     if (Ssbh.TryParseSsbhFile(AbsolutePath, out var SSBHFile))
     {
         if (SSBHFile is Skel)
         {
             skel = (Skel)SSBHFile;
         }
     }
 }
Example #3
0
        public static void Save(string fileName, SBScene scene, string sourceSkelPath)
        {
            var Skeleton = scene.Skeleton;

            var skelFile = new Skel();

            skelFile.MajorVersion = 1;
            skelFile.MinorVersion = 0;

            List <SkelBoneEntry> BoneEntries        = new List <SkelBoneEntry>();
            List <Matrix4x4>     Transforms         = new List <Matrix4x4>();
            List <Matrix4x4>     InvTransforms      = new List <Matrix4x4>();
            List <Matrix4x4>     WorldTransforms    = new List <Matrix4x4>();
            List <Matrix4x4>     InvWorldTransforms = new List <Matrix4x4>();

            // Attempt to match bone order to an existing SKEL if possible.
            var sortedBones = Skeleton.Bones;

            if (!string.IsNullOrEmpty(sourceSkelPath))
            {
                sortedBones = GetBoneOrderBasedOnReference(Skeleton.Bones, sourceSkelPath);
            }

            short index = 0;

            foreach (var bone in sortedBones)
            {
                var boneEntry = new SkelBoneEntry
                {
                    Name = bone.Name,
                    Type = bone.Type,
                    Id   = index++
                };
                boneEntry.Type     = 1;
                boneEntry.ParentId = -1;
                if (bone.Parent != null)
                {
                    boneEntry.ParentId = (short)Array.IndexOf(sortedBones, bone.Parent);
                }
                BoneEntries.Add(boneEntry);

                Transforms.Add(bone.Transform.ToSsbh());
                InvTransforms.Add(bone.Transform.Inverted().ToSsbh());
                WorldTransforms.Add(bone.WorldTransform.ToSsbh());
                InvWorldTransforms.Add(bone.InvWorldTransform.ToSsbh());
            }

            skelFile.BoneEntries       = BoneEntries.ToArray();
            skelFile.Transform         = Transforms.ToArray();
            skelFile.InvTransform      = InvTransforms.ToArray();
            skelFile.WorldTransform    = WorldTransforms.ToArray();
            skelFile.InvWorldTransform = InvWorldTransforms.ToArray();

            Ssbh.TrySaveSsbhFile(fileName, skelFile);
        }
Example #4
0
        public static void Save(string FileName, SBScene Scene)
        {
            var Skeleton = Scene.Skeleton;

            var skelFile = new Skel();

            skelFile.MajorVersion = 1;
            skelFile.MinorVersion = 0;

            List <SkelBoneEntry> BoneEntries        = new List <SkelBoneEntry>();
            List <SkelMatrix>    Transforms         = new List <SkelMatrix>();
            List <SkelMatrix>    InvTransforms      = new List <SkelMatrix>();
            List <SkelMatrix>    WorldTransforms    = new List <SkelMatrix>();
            List <SkelMatrix>    InvWorldTransforms = new List <SkelMatrix>();

            short index = 0;
            Dictionary <SBBone, short> BoneToIndex = new Dictionary <SBBone, short>();
            var OrderedBones = SortBones(Skeleton.Bones);

            foreach (var bone in OrderedBones)
            {
                BoneToIndex.Add(bone, index);
                var boneentry = new SkelBoneEntry();
                boneentry.Name     = bone.Name;
                boneentry.Type     = bone.Type;
                boneentry.Id       = index++;
                boneentry.Type     = 1;
                boneentry.ParentId = -1;
                if (bone.Parent != null)// && BoneToIndex.ContainsKey(bone.Parent))
                {
                    boneentry.ParentId = (short)OrderedBones.IndexOf(bone.Parent);
                }
                BoneEntries.Add(boneentry);

                Transforms.Add(TKMatrix_to_Skel(bone.Transform));
                InvTransforms.Add(TKMatrix_to_Skel(bone.Transform.Inverted()));
                WorldTransforms.Add(TKMatrix_to_Skel(bone.WorldTransform));
                InvWorldTransforms.Add(TKMatrix_to_Skel(bone.InvWorldTransform));
            }

            skelFile.BoneEntries       = BoneEntries.ToArray();
            skelFile.Transform         = Transforms.ToArray();
            skelFile.InvTransform      = InvTransforms.ToArray();
            skelFile.WorldTransform    = WorldTransforms.ToArray();
            skelFile.InvWorldTransform = InvWorldTransforms.ToArray();

            Ssbh.TrySaveSsbhFile(FileName, skelFile);
        }
        public static void Render(Camera camera)
        {
            if (Skel == null)
            {
                return;
            }

            if (capsule == null)
            {
                capsule = new Capsule();
            }

            if (sphere == null)
            {
                sphere = new Sphere();
            }

            var capsuleShader = ShaderContainer.GetShader("Capsule");
            var sphereShader  = ShaderContainer.GetShader("Sphere");
            var polygonShader = ShaderContainer.GetShader("Polygon");


            if (RenderSettings.Instance.RenderHitCollisions)
            {
                GL.Disable(EnableCap.DepthTest);
                GL.Enable(EnableCap.Blend);
                GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
                foreach (var hit in HitData)
                {
                    if (hit.Enabled)
                    {
                        //some param files refer to bone hashes that don't exist on the skeleton
                        if (!BoneIDs.TryGetValue(hit.Bone, out int boneIndex))
                        {
                            continue;
                        }

                        Matrix4 bone  = Skel.GetAnimationSingleBindsTransform(boneIndex);
                        Vector4 color = new Vector4(hit.Color, 0.3f);
                        //if (BoneIDs[hit.Bone] == 0)//special purpose HitData attached to trans or top
                        //    color = new Vector4(1, 0.3f, 0.3f, 0.3f);
                        if (hit.Pos != hit.Pos2)
                        {
                            capsule.Render(capsuleShader, hit.Size, hit.Pos, hit.Pos2, bone, camera.MvpMatrix, color);
                        }
                        else
                        {
                            sphere.Render(sphereShader, hit.Size, hit.Pos, bone, camera.MvpMatrix, color);
                        }
                    }
                }
                GL.Enable(EnableCap.DepthTest);
                GL.Disable(EnableCap.Blend);
            }

            Matrix4 transN      = Skel.GetAnimationSingleBindsTransform(0).ClearRotation().ClearScale();
            int     cliffHangID = RenderSettings.Instance.CliffHangID;

            if (cliffHangID >= 0 && cliffHangID < CliffHangData.Length)
            {
                GL.Disable(EnableCap.DepthTest);

                CliffHangShape shape = CliffHangData[cliffHangID];
                Vector3        v1;
                Vector3        v2;
                Vector3        v3;
                Vector3        v4;
                //this makes sure the rectangle is always front facing
                //I had trouble using OpenGL's culling mode, I don't know why
                if ((shape.p1.X - shape.p2.X) * (shape.p1.Y - shape.p2.Y) > 0)
                {
                    v1 = new Vector3(0, shape.p1.Y, shape.p1.X);
                    v2 = new Vector3(0, shape.p1.Y, shape.p2.X);
                    v3 = new Vector3(0, shape.p2.Y, shape.p2.X);
                    v4 = new Vector3(0, shape.p2.Y, shape.p1.X);
                }
                else
                {
                    v1 = new Vector3(0, shape.p1.Y, shape.p1.X);
                    v2 = new Vector3(0, shape.p2.Y, shape.p1.X);
                    v3 = new Vector3(0, shape.p2.Y, shape.p2.X);
                    v4 = new Vector3(0, shape.p1.Y, shape.p2.X);
                }
                quad = new Polygon(new List <Vector3>()
                {
                    v1, v2, v3, v4
                });
                quad.Render(polygonShader, transN, camera.MvpMatrix, new Vector4(Collision.IDColors[cliffHangID % 9], 1f));

                GL.Enable(EnableCap.DepthTest);
            }
        }
    public override void OnImportAsset(AssetImportContext ctx)
    {
        //Load file contents
        BoneLib.Bone file = new BoneLib.Bone();
        file.LoadFile(ctx.assetPath);
        //Load skel file for reference
        M2 model = new M2();

        model.LoadFile(ctx.assetPath.Substring(0, ctx.assetPath.Length - 8) + ".m2");
        Skel skeleton = model.Skeleton;
        //Create empty animation clip
        AnimationClip  clip = new AnimationClip();
        AnimationCurve curve;
        Matrix4x4      matrix;

        Vector4[] columns = new Vector4[4];
        float     value;

        //Generate temporary bones
        Transform[] bones = new Transform[skeleton.Bones.Length];
        for (int i = 0; i < bones.Length; i++)
        {
            bones[i]          = new GameObject("Bone" + i).transform;
            bones[i].position = new Vector3(-skeleton.Bones[i].Pivot.X / 2, skeleton.Bones[i].Pivot.Z / 2, -skeleton.Bones[i].Pivot.Y / 2);
        }
        GameObject rig = new GameObject("Skeleton");

        for (int i = 0; i < bones.Length; i++)
        {
            if (skeleton.Bones[i].Parent == -1)
            {
                bones[i].parent = rig.transform;
            }
            else
            {
                bones[i].parent = bones[skeleton.Bones[i].Parent];
            }
        }
        //Fill animation data for each bone
        for (int i = 0; i < file.Bones.Length; i++)
        {
            string path = GetBonePath(skeleton.Bones[file.Bones[i]].Parent, skeleton.Bones) + "Bone" + file.Bones[i];
            for (int j = 0; j < 4; j++)
            {
                columns[j] = new Vector4(file.Transformations[i][j][0], file.Transformations[i][j][1], file.Transformations[i][j][2], file.Transformations[i][j][3]);
            }
            matrix = new Matrix4x4(columns[0], columns[1], columns[2], columns[3]);
            value  = -matrix.m03 / 2 + bones[file.Bones[i]].localPosition.x;
            curve  = AnimationCurve.Linear(0f, value, 0.1f, value);
            clip.SetCurve(path, typeof(Transform), "localPosition.x", curve);
            value = matrix.m23 / 2 + bones[file.Bones[i]].localPosition.y;
            curve = AnimationCurve.Linear(0f, value, 0.1f, value);
            clip.SetCurve(path, typeof(Transform), "localPosition.y", curve);
            value = -matrix.m13 / 2 + bones[file.Bones[i]].localPosition.z;
            curve = AnimationCurve.Linear(0f, value, 0.1f, value);
            clip.SetCurve(path, typeof(Transform), "localPosition.z", curve);
            UnityEngine.Quaternion rotation = matrix.rotation;
            curve = AnimationCurve.Linear(0f, -rotation.x, 1f, rotation.x);
            clip.SetCurve(path, typeof(Transform), "localRotation.x", curve);
            curve = AnimationCurve.Linear(0f, -rotation.z, 0.1f, rotation.z);
            clip.SetCurve(path, typeof(Transform), "localRotation.y", curve);
            curve = AnimationCurve.Linear(0f, rotation.y, 0.1f, rotation.y);
            clip.SetCurve(path, typeof(Transform), "localRotation.z", curve);
            curve = AnimationCurve.Linear(0f, rotation.w, 0.1f, rotation.w);
            clip.SetCurve(path, typeof(Transform), "localRotation.w", curve);
            Vector3 scale = matrix.lossyScale;
            curve = AnimationCurve.Linear(0f, scale.x, 0.1f, scale.x);
            clip.SetCurve(path, typeof(Transform), "localScale.x", curve);
            curve = AnimationCurve.Linear(0f, scale.z, 0.1f, scale.z);
            clip.SetCurve(path, typeof(Transform), "localScale.y", curve);
            curve = AnimationCurve.Linear(0f, scale.y, 0.1f, scale.y);
            clip.SetCurve(path, typeof(Transform), "localScale.z", curve);
        }
        //Clear temporary bones and add animation clip to the asset
        DestroyImmediate(rig);
        ctx.AddObjectToAsset(Path.GetFileNameWithoutExtension(ctx.assetPath.Replace("/", "\\")), clip);
    }
Example #7
0
        public void Render(Camera camera)
        {
            if (Sphere == null)
            {
                Sphere = new Sphere();
            }

            if (Capsule == null)
            {
                Capsule = new Capsule();
            }

            if (Line == null)
            {
                Line = new Line();
            }

            var sphereShader  = ShaderContainer.GetShader("Sphere");
            var capsuleShader = ShaderContainer.GetShader("Capsule");
            var lineShader    = ShaderContainer.GetShader("Line");

            Matrix4 mvp = camera.MvpMatrix;

            List <Collision> collisions = new List <Collision>();

            collisions.AddRange(Attacks);
            collisions.AddRange(Grabs);

            GL.Disable(EnableCap.DepthTest);

            for (int i = 0; i < collisions.Count; i++)
            {
                Collision coll = collisions[i];
                if (!coll.Enabled)
                {
                    continue;
                }

                Vector4 collColor = new Vector4(Collision.IDColors[i % Collision.IDColors.Length], 0.5f);

                Matrix4 boneTransform = Skel.GetAnimationSingleBindsTransform(BoneIDs[coll.Bone]);
                Matrix4 boneNoScale   =
                    Matrix4.CreateFromQuaternion(boneTransform.ExtractRotation())
                    * Matrix4.CreateTranslation(boneTransform.ExtractTranslation());

                if (IsSphere(coll))
                {
                    Sphere.Render(sphereShader, coll.Size, coll.Pos, boneNoScale, mvp, collColor);
                }
                else if (coll.ShapeType == Collision.Shape.capsule)
                {
                    Capsule.Render(capsuleShader, coll.Size, coll.Pos, coll.Pos2, boneNoScale, mvp, collColor);
                }
                //angle marker
                if (coll is Attack attack)
                {
                    int     angle      = attack.Angle;
                    Vector4 angleColor = new Vector4(1, 1, 1, 1);
                    GL.LineWidth(2f);

                    if (angle < 361)
                    {
                        float radian = angle * (float)Math.PI / 180f;
                        Line.Render(lineShader, radian, coll.Size, coll.Pos, boneNoScale, mvp, angleColor);
                    }
                    else if (angle == 361)
                    {
                        float radian = (float)Math.PI / 2f;
                        for (int j = 0; j < 4; j++)
                        {
                            Line.Render(lineShader, radian * j, coll.Size / 2, coll.Pos, boneNoScale, mvp, angleColor);
                        }
                    }
                    else if (angle == 368)
                    {
                        //set_vec_target_pos uses a second position to pull opponents toward
                        //this is represented by a line drawn between hitbox center and that point
                        if (attack.VecTargetPos_node != 0)
                        {
                            var attackVecBone        = Skel.GetAnimationSingleBindsTransform(BoneIDs[attack.VecTargetPos_node]);
                            var attackVecBoneNoScale =
                                Matrix4.CreateFromQuaternion(attackVecBone.ExtractRotation())
                                * Matrix4.CreateTranslation(attackVecBone.ExtractTranslation());
                            Line.Render(lineShader,
                                        boneNoScale, attackVecBoneNoScale,
                                        coll.Pos, Vector3.Zero,
                                        Vector3.Zero, new Vector3(attack.VecTargetPos_pos.Z, attack.VecTargetPos_pos.Y, 0),
                                        mvp, angleColor
                                        );
                        }
                    }
                    else
                    {
                        float radian = (float)Math.PI / 2f;
                        float add    = (float)Math.PI / 4f;
                        for (int j = 0; j < 4; j++)
                        {
                            Line.Render(lineShader, radian * j + add, coll.Size / 2, coll.Pos, boneNoScale, mvp, angleColor);
                        }
                    }
                }
            }

            GL.Enable(EnableCap.DepthTest);
        }