Ejemplo n.º 1
0
        private void AppendSpriteBoneDataRecursively(List <SpriteBone> spriteBones, BoneCache bone, int parentIndex)
        {
            int currentParentIndex = spriteBones.Count;

            var spriteBone = new SpriteBone();

            spriteBone.name     = bone.name;
            spriteBone.parentId = parentIndex;
            if (parentIndex == -1 && bone.parentBone != null)
            {
                spriteBone.position = bone.position;
                spriteBone.rotation = bone.rotation;
            }
            else
            {
                spriteBone.position = bone.localPosition;
                spriteBone.rotation = bone.localRotation;
            }
            spriteBone.position = new Vector3(spriteBone.position.x, spriteBone.position.y, bone.depth);

            spriteBone.length = bone.localLength;
            spriteBones.Add(spriteBone);

            foreach (var child in bone)
            {
                var childBone = child as BoneCache;
                if (childBone != null)
                {
                    AppendSpriteBoneDataRecursively(spriteBones, childBone, currentParentIndex);
                }
            }
        }
Ejemplo n.º 2
0
        private static List <SpriteBone> Load(SerializedObject importer, SpriteImportMode mode, int index)
        {
            var sp = mode == SpriteImportMode.Multiple ?
                     importer.FindProperty("m_SpriteSheet.m_Sprites").GetArrayElementAtIndex(index).FindPropertyRelative("m_Bones") :
                     importer.FindProperty("m_SpriteSheet.m_Bones");

            var spriteBone = new List <SpriteBone>(sp.arraySize);

            if (sp.arraySize > 0)
            {
                var boneSO = sp.GetArrayElementAtIndex(0);
                for (int i = 0; i < sp.arraySize; ++i, boneSO.Next(false))
                {
                    var sb = new SpriteBone();
                    sb.length   = boneSO.FindPropertyRelative("length").floatValue;
                    sb.position = boneSO.FindPropertyRelative("position").vector3Value;
                    sb.rotation = boneSO.FindPropertyRelative("rotation").quaternionValue;
                    sb.parentId = boneSO.FindPropertyRelative("parentId").intValue;
                    sb.name     = boneSO.FindPropertyRelative("name").stringValue;
                    sb.guid     = boneSO.FindPropertyRelative("guid").stringValue;
                    sb.color    = boneSO.FindPropertyRelative("color").colorValue;
                    spriteBone.Add(sb);
                }
            }
            return(spriteBone);
        }
 public UniqueSpriteBone(SpriteBone spriteBone)
 {
     this.length   = spriteBone.length;
     this.name     = spriteBone.name;
     this.parentId = spriteBone.parentId;
     this.position = spriteBone.position;
     this.rotation = spriteBone.rotation;
     this.id       = new GUID();
 }
        public static void Apply(SerializedProperty rectSP, List <SpriteBone> spriteBone)
        {
            SerializedProperty serializedProperty = rectSP.FindPropertyRelative("m_Bones");

            serializedProperty.arraySize = spriteBone.Count;
            for (int i = 0; i < serializedProperty.arraySize; i++)
            {
                SerializedProperty arrayElementAtIndex = serializedProperty.GetArrayElementAtIndex(i);
                SpriteBone         spriteBone2         = spriteBone[i];
                arrayElementAtIndex.FindPropertyRelative("length").floatValue        = spriteBone2.length;
                arrayElementAtIndex.FindPropertyRelative("position").vector3Value    = spriteBone2.position;
                arrayElementAtIndex.FindPropertyRelative("rotation").quaternionValue = spriteBone2.rotation;
                arrayElementAtIndex.FindPropertyRelative("parentId").intValue        = spriteBone2.parentId;
                arrayElementAtIndex.FindPropertyRelative("name").stringValue         = spriteBone2.name;
            }
        }
Ejemplo n.º 5
0
        static void CalculateLocaltoWorldMatrix(int i, SpriteRect spriteRect, float definitionScale, float pixelsPerUnit, List <SpriteBone> spriteBone, ref SpriteBone?[] outpriteBone, ref NativeArray <Matrix4x4> bindPose)
        {
            if (outpriteBone[i] != null)
            {
                return;
            }
            SpriteBone sp       = spriteBone[i];
            var        isRoot   = sp.parentId == -1;
            var        position = isRoot ? (spriteBone[i].position - Vector3.Scale(spriteRect.rect.size, spriteRect.pivot)) : spriteBone[i].position;

            position.z      = 0f;
            sp.position     = position * definitionScale / pixelsPerUnit;
            sp.length       = spriteBone[i].length * definitionScale / pixelsPerUnit;
            outpriteBone[i] = sp;

            // Calculate bind poses
            var worldPosition = Vector3.zero;
            var worldRotation = Quaternion.identity;

            if (sp.parentId == -1)
            {
                worldPosition = sp.position;
                worldRotation = sp.rotation;
            }
            else
            {
                if (outpriteBone[sp.parentId] == null)
                {
                    CalculateLocaltoWorldMatrix(sp.parentId, spriteRect, definitionScale, pixelsPerUnit, spriteBone, ref outpriteBone, ref bindPose);
                }
                var parentBindPose    = bindPose[sp.parentId];
                var invParentBindPose = Matrix4x4.Inverse(parentBindPose);

                worldPosition = invParentBindPose.MultiplyPoint(sp.position);
                worldRotation = sp.rotation * invParentBindPose.rotation;
            }

            // Practically Matrix4x4.SetTRInverse
            var       rot = Quaternion.Inverse(worldRotation);
            Matrix4x4 mat = Matrix4x4.identity;

            mat = Matrix4x4.Rotate(rot);
            mat = mat * Matrix4x4.Translate(-worldPosition);


            bindPose[i] = mat;
        }
        public override bool ApplyRevert(bool apply)
        {
            if (apply)
            {
                var meshDataProvider = spriteEditor.GetDataProvider <ISpriteMeshDataProvider>();
                var boneDataProvider = spriteEditor.GetDataProvider <ISpriteBoneDataProvider>();

                foreach (var spriteMeshData in m_SpriteMeshCache)
                {
                    spriteMeshData.SortTrianglesByDepth();

                    List <Vertex2DMetaData> vmd = new List <Vertex2DMetaData>(spriteMeshData.vertices.Count);
                    foreach (var v in spriteMeshData.vertices)
                    {
                        vmd.Add(new Vertex2DMetaData()
                        {
                            position = v.position - spriteMeshData.frame.position, boneWeight = v.editableBoneWeight.ToBoneWeight(true)
                        });
                    }

                    List <Vector2Int> emd = new List <Vector2Int>(spriteMeshData.edges.Count);
                    foreach (var e in spriteMeshData.edges)
                    {
                        emd.Add(new Vector2Int(e.index1, e.index2));
                    }

                    meshDataProvider.SetVertices(spriteMeshData.spriteID, vmd.ToArray());
                    meshDataProvider.SetIndices(spriteMeshData.spriteID, spriteMeshData.indices.ToArray());
                    meshDataProvider.SetEdges(spriteMeshData.spriteID, emd.ToArray());

                    List <SpriteBone> bones = boneDataProvider.GetBones(spriteMeshData.spriteID);
                    for (int i = 0; i < bones.Count; ++i)
                    {
                        SpriteBone     original = bones[i];
                        SpriteBoneData bone     = spriteMeshData.bones[i];
                        Vector3        position = original.position;
                        position.z        = bone.depth;
                        original.position = position;
                        bones[i]          = original;
                    }

                    boneDataProvider.SetBones(spriteMeshData.spriteID, bones);
                }
            }

            return(true);
        }
Ejemplo n.º 7
0
        private List <SpriteBoneData> CreateBones()
        {
            SpriteBone[] spriteBones = new SpriteBone[]
            {
                new SpriteBone()
                {
                    name     = "root",
                    length   = 1f,
                    parentId = -1,
                    position = Vector2.zero,
                    rotation = Quaternion.identity
                },
                new SpriteBone()
                {
                    name     = "bone 0",
                    length   = 1f,
                    parentId = 0,
                    position = Vector2.right,
                    rotation = Quaternion.identity
                }
            };

            return(ModuleUtility.CreateSpriteBoneData(spriteBones, Matrix4x4.identity));
        }
        private List <SpriteBoneData> CreateSpriteBoneData()
        {
            var spriteBones = new SpriteBone[2]
            {
                new SpriteBone()
                {
                    name     = "root",
                    parentId = -1,
                    position = Vector2.one,
                    rotation = Quaternion.Euler(0.0f, 0.0f, 30.0f),
                    length   = 1.0f
                },
                new SpriteBone()
                {
                    name     = "child1",
                    parentId = 0,
                    position = Vector3.up,
                    rotation = Quaternion.Euler(0.0f, 0.0f, 60.0f),
                    length   = 1.5f
                }
            };

            return(MeshModuleUtility.CreateSpriteBoneData(spriteBones.ToList(), Matrix4x4.identity));
        }
        private static IEnumerable <TestCaseData> BoneMetadataCases()
        {
            var originalMetadata = new SpriteBone[5]
            {
                new SpriteBone()
                {
                    name     = "root",
                    parentId = -1,
                    position = Vector2.one,
                    rotation = Quaternion.Euler(0.0f, 0.0f, 30.0f),
                    length   = 1.0f
                },
                new SpriteBone()
                {
                    name     = "child1",
                    parentId = 0,
                    position = Vector3.up,
                    rotation = Quaternion.Euler(0.0f, 0.0f, 60.0f),
                    length   = 1.5f
                },
                new SpriteBone()
                {
                    name     = "child2",
                    parentId = 1,
                    position = Vector3.right,
                    rotation = Quaternion.identity,
                    length   = 1.5f
                },
                new SpriteBone()
                {
                    name     = "child3",
                    parentId = 1,
                    position = Vector3.left,
                    rotation = Quaternion.Euler(0.0f, 0.0f, 120.0f),
                    length   = 2.5f
                },
                new SpriteBone()
                {
                    name     = "child4",
                    parentId = 3,
                    position = Vector3.up,
                    rotation = Quaternion.identity,
                    length   = 1.0f
                }
            };

            var expectedPositions = new List <Vector2>();

            expectedPositions.Add(new Vector2(1f, 1f));
            expectedPositions.Add(new Vector2(0.5f, 1.8660f));
            expectedPositions.Add(new Vector2(0.5f, 2.8660f));
            expectedPositions.Add(new Vector2(0.5f, 0.8660f));
            expectedPositions.Add(new Vector2(1f, 0f));

            var expectedEndPositions = new List <Vector2>();

            expectedEndPositions.Add(new Vector2(1.8660f, 1.5f));
            expectedEndPositions.Add(new Vector2(0.5f, 3.3660f));
            expectedEndPositions.Add(new Vector2(0.5f, 4.3660f));
            expectedEndPositions.Add(new Vector2(-1.6650f, -0.383974f));
            expectedEndPositions.Add(new Vector2(0.133974f, -0.5f));

            var testcase = new TestCaseData(originalMetadata, expectedPositions, expectedEndPositions);

            testcase.SetName("Normal Hierarchical order");
            yield return(testcase);

            originalMetadata = new SpriteBone[5]
            {
                new SpriteBone()
                {
                    name     = "child4",
                    parentId = 1,
                    position = Vector3.up,
                    rotation = Quaternion.identity,
                    length   = 1.0f
                },
                new SpriteBone()
                {
                    name     = "child3",
                    parentId = 3,
                    position = Vector3.left,
                    rotation = Quaternion.Euler(0.0f, 0.0f, 120.0f),
                    length   = 2.5f
                },
                new SpriteBone()
                {
                    name     = "child2",
                    parentId = 3,
                    position = Vector3.right,
                    rotation = Quaternion.identity,
                    length   = 1.5f
                },
                new SpriteBone()
                {
                    name     = "child1",
                    parentId = 4,
                    position = Vector3.up,
                    rotation = Quaternion.Euler(0.0f, 0.0f, 60.0f),
                    length   = 1.5f
                },
                new SpriteBone()
                {
                    name     = "root",
                    parentId = -1,
                    position = Vector2.one,
                    rotation = Quaternion.Euler(0.0f, 0.0f, 30.0f),
                    length   = 1.0f
                }
            };

            expectedPositions = new List <Vector2>();
            expectedPositions.Add(new Vector2(1f, 0f));
            expectedPositions.Add(new Vector2(0.5f, 0.8660f));
            expectedPositions.Add(new Vector2(0.5f, 2.8660f));
            expectedPositions.Add(new Vector2(0.5f, 1.8660f));
            expectedPositions.Add(new Vector2(1f, 1f));

            expectedEndPositions = new List <Vector2>();
            expectedEndPositions.Add(new Vector2(0.133974f, -0.5f));
            expectedEndPositions.Add(new Vector2(-1.6650f, -0.383974f));
            expectedEndPositions.Add(new Vector2(0.5f, 4.3660f));
            expectedEndPositions.Add(new Vector2(0.5f, 3.3660f));
            expectedEndPositions.Add(new Vector2(1.8660f, 1.5f));

            testcase = new TestCaseData(originalMetadata, expectedPositions, expectedEndPositions);
            testcase.SetName("Reversed Hierarchical order");
            yield return(testcase);
        }
Ejemplo n.º 10
0
        public void OnPasteActivated(bool bone, bool mesh, bool flipX, bool flipY)
        {
            var copyBuffer = m_CopyToolStringStore.stringStore;

            if (!SkinningCopyUtility.CanDeserializeStringToSkinningCopyData(copyBuffer))
            {
                Debug.LogError(TextContent.copyError1);
                return;
            }

            var skinningCopyData = SkinningCopyUtility.DeserializeStringToSkinningCopyData(copyBuffer);

            if (skinningCopyData == null || skinningCopyData.copyData.Count == 0)
            {
                Debug.LogError(TextContent.copyError2);
                return;
            }

            var scale = 1f;

            if (skinningCopyData.pixelsPerUnit > 0f)
            {
                scale = pixelsPerUnit / skinningCopyData.pixelsPerUnit;
            }

            var sprites      = skinningCache.GetSprites();
            var copyMultiple = skinningCopyData.copyData.Count > 1;

            if (copyMultiple && skinningCopyData.copyData.Count != sprites.Length && mesh)
            {
                Debug.LogError(String.Format(TextContent.copyError3, sprites.Length, skinningCopyData.copyData.Count));
                return;
            }

            using (skinningCache.UndoScope(TextContent.pasteData))
            {
                NewBonesStore newBonesStore = null;
                if (bone && copyMultiple && skinningCache.hasCharacter)
                {
                    newBonesStore = new NewBonesStore();
                    var skinningSpriteData = skinningCopyData.copyData[0];
                    newBonesStore.newBones = skinningCache.CreateBoneCacheFromSpriteBones(skinningSpriteData.spriteBones.Select(y => y.spriteBone).ToArray(), scale);
                    if (flipX || flipY)
                    {
                        var characterRect = new Rect(Vector2.zero, skinningCache.character.dimension);
                        var newPositions  = new Vector3[newBonesStore.newBones.Length];
                        var newRotations  = new Quaternion[newBonesStore.newBones.Length];
                        for (var i = 0; i < newBonesStore.newBones.Length; ++i)
                        {
                            newPositions[i] = GetFlippedBonePosition(newBonesStore.newBones[i], Vector2.zero, characterRect, flipX, flipY);
                            newRotations[i] = GetFlippedBoneRotation(newBonesStore.newBones[i], flipX, flipY);
                        }
                        for (var i = 0; i < newBonesStore.newBones.Length; ++i)
                        {
                            newBonesStore.newBones[i].position = newPositions[i];
                            newBonesStore.newBones[i].rotation = newRotations[i];
                        }
                    }
                    newBonesStore.MapAllExistingBones();
                    var skeleton = skinningCache.character.skeleton;
                    skeleton.SetBones(newBonesStore.newBones);
                    skinningCache.events.skeletonTopologyChanged.Invoke(skeleton);
                }

                foreach (var skinningSpriteData in skinningCopyData.copyData)
                {
                    SpriteCache sprite = null;
                    if (!String.IsNullOrEmpty(skinningSpriteData.spriteName))
                    {
                        sprite = sprites.FirstOrDefault(x => x.name == skinningSpriteData.spriteName);
                    }
                    if (sprite == null && (skinningCopyData.copyData.Count == 1 || String.IsNullOrEmpty(skinningSpriteData.spriteName)))
                    {
                        sprite = skinningCache.selectedSprite;
                    }
                    if (sprite == null)
                    {
                        continue;
                    }

                    if (bone && (!skinningCache.hasCharacter || !copyMultiple))
                    {
                        var spriteBones = new SpriteBone[skinningSpriteData.spriteBones.Count];
                        for (int i = 0; i < skinningSpriteData.spriteBones.Count; ++i)
                        {
                            var order = skinningSpriteData.spriteBones[i].order;
                            spriteBones[order] = skinningSpriteData.spriteBones[i].spriteBone;
                            var parentId = spriteBones[order].parentId;
                            if (parentId >= 0)
                            {
                                spriteBones[order].parentId = skinningSpriteData.spriteBones[parentId].order;
                            }
                        }
                        newBonesStore = PasteSkeletonBones(sprite, spriteBones.ToList(), flipX, flipY, scale);
                    }

                    if (mesh && meshTool != null)
                    {
                        PasteMesh(sprite, skinningSpriteData, flipX, flipY, scale, newBonesStore);
                    }
                }

                if (newBonesStore != null && newBonesStore.newBones != null)
                {
                    skinningCache.skeletonSelection.elements = newBonesStore.newBones;
                    skinningCache.events.boneSelectionChanged.Invoke();
                }
            }
            skinningCache.events.paste.Invoke(bone, mesh, flipX, flipY);
        }
    public static void ProcessCharacter()
    {
        // Get the file paths of the data
        string plist_path = EditorUtility.OpenFilePanel("Open character's config data:", "Assets", "plist");
        string json_path  = EditorUtility.OpenFilePanel("Open character's skeletal/animation data:", "Assets", "ExportJson");

        Texture2D sprite;

        if (Selection.objects.Length != 1)
        {
            sprite = null;
        }
        else
        {
            sprite = Selection.activeObject as Texture2D;
        }

        if (sprite == null)
        {
            Debug.LogError("ERROR: Sprite sheet is not selected.");
            return;
        }

        if (plist_path == "" || json_path == "")
        {
            Debug.LogError("ERROR: Plist and/or JSON are null.");
            return;
        }


        // Read sprite data from the plist
        List <SpriteData> cutting_data = ReadPlist(plist_path);

        // Cut sprite data
        List <SpriteMetaData> sheet = CutSprite(sprite, cutting_data);

        // Prepare sprite atlas
        string atlas_source = AssetDatabase.GetAssetPath(sprite);

        atlas_source = atlas_source.Substring(atlas_source.LastIndexOf("/") + 1, (atlas_source.LastIndexOf(".") - atlas_source.LastIndexOf("/")) - 1);
        SpriteAtlas atlas = new SpriteAtlas(atlas_source);


        // Read data from Json file into Json string
        string json_content = File.ReadAllText(json_path);

        // Deserialize Json string into usable object data
        RootObject obj = JsonUtility.FromJson <RootObject>(json_content);


        // Create base object for armature
        GameObject root = new GameObject(obj.armature_data[0].name);

        root.tag = "Armature";

        // Prepare the skeleton
        //List<GameObject> bones = new List<GameObject>();
        List <SpriteBone> bones = new List <SpriteBone>();


        // For each bone in the skeleton
        foreach (BoneData node in obj.armature_data[0].bone_data)
        {
            // Create a new game object, tag is set to bone
            GameObject g = new GameObject(node.name);
            g.tag = "Bone";

            // If parent node is null, parent the object to the root
            if (node.parent == "")
            {
                g.transform.SetParent(root.transform);
            }
            else
            {
                // Get a reference to all child transforms
                Transform[] allChildren = root.GetComponentsInChildren <Transform>();

                // For each transform
                foreach (Transform child in allChildren)
                {
                    // Check if transform name matches parent. If so, parent the object to that transform
                    if (child.gameObject.name == node.parent)
                    {
                        g.transform.SetParent(child);
                    }
                }
            }

            // POSITION IS RELATIVE TO PARENT
            // Set the position and scale
            // Mathf.Rad2Deg
            g.transform.localPosition    = new Vector2((float)node.x / scale_factor, (float)node.y / scale_factor);
            g.transform.localScale       = new Vector3((float)node.cX, (float)node.cY, 1.0f);
            g.transform.localEulerAngles = new Vector3(0.0f, 0.0f, (float)(node.kY * Mathf.Rad2Deg));

            int index        = 0;
            int displayIndex = node.dI;

            /*if (displayIndex < 0)
             *  displayIndex = 0;*/

            // Initialize skeleton
            SpriteBone sb = new SpriteBone();
            sb.bone = g;


            // Sprites need to be their own gameobjects
            foreach (DisplayData d in node.display_data)
            {
                // Create object
                GameObject s = new GameObject(d.name);
                s.transform.SetParent(g.transform);
                s.tag = "Display Data";

                SkinData   d_data = d.skin_data[0];
                SpriteData sd     = FindSpriteData(cutting_data, d.name);

                // Set sprite transforms
                if (sd != null)
                {
                    s.transform.localPosition    = new Vector3(((float)d_data.x) / scale_factor, ((float)d_data.y) / scale_factor);
                    s.transform.localScale       = new Vector3((float)d_data.cX, (float)d_data.cY, 1.0f);
                    s.transform.localEulerAngles = new Vector3(0.0f, 0.0f, (float)(d_data.kY * Mathf.Rad2Deg));

                    // Set sprite offset
                    GameObject o = new GameObject(index.ToString());
                    o.transform.SetParent(s.transform);
                    o.tag = "Sprite";

                    // Set up sprite components
                    o.AddComponent <SpriteRenderer>();
                    //o.GetComponent<SpriteRenderer>().sortingOrder = node.z;
                    Sprite body_piece = atlas.getSprite(d.name);
                    o.GetComponent <SpriteRenderer>().sprite = body_piece;

                    // Apply sprite offset
                    o.transform.localPosition    = new Vector3(sd.offsetX / scale_factor, sd.offsetY / scale_factor, -node.z / scale_factor);
                    o.transform.localEulerAngles = Vector3.zero;

                    sb.displayData.Add(o);

                    // Determine visibility
                    if (displayIndex != index)
                    {
                        o.SetActive(false);
                    }
                }

                index++;
            }

            // Add bone to the list
            bones.Add(sb);
        }


        // Add an animator to the root
        root.AddComponent <Animator>();

        // Create an animator controller (ADDENDUM: MAY NOT BE NEEDED)

        // Loop through all animations in the JSON
        foreach (MovData md in obj.animation_data[0].mov_data)
        {
            // Create and name an animation clip
            AnimationClip anim = new AnimationClip();
            anim.name = md.name;

            // Name and frame index of inverted bones
            // Change to dictionary <string, Dictionary<int, bool>>
            Dictionary <string, Dictionary <int, bool> > toInvert = new Dictionary <string, Dictionary <int, bool> >();

            foreach (MovBoneData mbd in md.mov_bone_data)
            {
                Dictionary <int, bool> boneInv = new Dictionary <int, bool>();
                int numAdded = 0;

                foreach (FrameData fd in mbd.frame_data)
                {
                    if (fd.cX < 0 || fd.cY < 0)
                    {
                        boneInv.Add(fd.fi, true);
                        numAdded++;
                    }
                    else
                    {
                        if (!boneInv.ContainsKey(fd.fi))
                        {
                            boneInv.Add(fd.fi, false);
                        }
                    }
                }

                if (boneInv.Count > 0 && numAdded > 0)
                {
                    toInvert.Add(mbd.name, boneInv);
                }
            }


            // Loop through all bone data
            foreach (MovBoneData mbd in md.mov_bone_data)
            {
                // Name of bone that needs its transform inverted
                //List<string> toInvert = new List<string>();

                // Find the game object matching the bone
                SpriteBone bone = null;

                foreach (SpriteBone sb in bones)
                {
                    if (sb.bone.name.Equals(mbd.name))
                    {
                        bone = sb;
                    }
                }

                // Prepare animation curves for animated properties
                AnimationCurve curve_x  = new AnimationCurve();
                AnimationCurve curve_y  = new AnimationCurve();
                AnimationCurve curve_cx = new AnimationCurve();
                AnimationCurve curve_cy = new AnimationCurve();
                AnimationCurve curve_ky = new AnimationCurve();

                AnimationCurve[] curve_z  = new AnimationCurve[bone.displayData.Count];
                AnimationCurve[] curve_di = new AnimationCurve[bone.displayData.Count];

                AnimationCurve[] curve_fx = new AnimationCurve[bone.displayData.Count];
                AnimationCurve[] curve_fy = new AnimationCurve[bone.displayData.Count];

                // Required to retain offsets
                AnimationCurve[] curve_zx = new AnimationCurve[bone.displayData.Count];
                AnimationCurve[] curve_zy = new AnimationCurve[bone.displayData.Count];

                for (int i = 0; i < bone.displayData.Count; i++)
                {
                    curve_z[i]  = new AnimationCurve();
                    curve_zx[i] = new AnimationCurve();
                    curve_zy[i] = new AnimationCurve();
                    curve_di[i] = new AnimationCurve();
                    curve_fx[i] = new AnimationCurve();
                    curve_fy[i] = new AnimationCurve();
                }

                int previous_z = 0;

                // Loop through all keyframes for that bone
                foreach (FrameData fd in mbd.frame_data)
                {
                    // Set keyframe values for position, rotation, and scale. Note that all of these are relative
                    Keyframe px = new Keyframe((fd.fi / sample_rate), (bone.bone.transform.localPosition.x + ((float)fd.x / scale_factor)));
                    px.tangentMode = 0;
                    px.inTangent   = 0.0f;
                    px.outTangent  = 0.0f;

                    Keyframe py = new Keyframe((fd.fi / sample_rate), (bone.bone.transform.localPosition.y + ((float)fd.y / scale_factor)));
                    py.tangentMode = 0;
                    py.inTangent   = 0.0f;
                    py.outTangent  = 0.0f;

                    curve_x.AddKey(px);
                    curve_y.AddKey(py);

                    // Scale keyframes
                    Keyframe kx = new Keyframe((fd.fi / sample_rate), ((float)fd.cX));
                    kx.tangentMode = 0;
                    kx.inTangent   = 0.0f;
                    kx.outTangent  = 0.0f;

                    Keyframe ky = new Keyframe((fd.fi / sample_rate), ((float)fd.cY));
                    ky.tangentMode = 0;
                    ky.inTangent   = 0.0f;
                    ky.outTangent  = 0.0f;

                    curve_cx.AddKey(kx);
                    curve_cy.AddKey(ky);

                    // This is the ONLY bug remaining. When something's supposed to be inverted, the inversion is never reset.
                    // Inversion is also not 100%. For example, Suzy's right arm is not inverted in her idle animation


                    // Correct inversion error
                    Transform t         = bone.bone.transform;
                    float     direction = 1.0f;

                    while (t.transform.parent != null)
                    {
                        t = t.transform.parent;

                        if (toInvert.ContainsKey(t.gameObject.name))
                        {
                            // This needs to get the previous frame index if none exist
                            if (InvertAtIndex(toInvert, fd.fi, t.gameObject.name))
                            {
                                direction = -1.0f;
                                Debug.Log("Success! - " + md.name + ": " + t.gameObject.name + " " + mbd.name);
                            }
                        }
                    }
                    // Invert rotation
                    Keyframe ry = new Keyframe((fd.fi / sample_rate),
                                               direction * (bone.bone.transform.localEulerAngles.z + ((float)(fd.kY * Mathf.Rad2Deg))));
                    ry.tangentMode = 0;
                    ry.inTangent   = 0.0f;
                    ry.outTangent  = 0.0f;

                    curve_ky.AddKey(ry);

                    // Determine display index
                    int displayIndex = fd.dI;

                    for (int i = 0; i < bone.displayData.Count; i++)
                    {
                        // If the frame index is not one, a second keyframe will need to be set to disable "sliding"
                        if (fd.fi > 1)
                        {
                            Keyframe p_zx = new Keyframe(((fd.fi - 1) / sample_rate), bone.displayData[i].transform.localPosition.x);
                            p_zx.tangentMode = 0;
                            p_zx.inTangent   = 0.0f;
                            p_zx.outTangent  = 0.0f;

                            Keyframe p_zy = new Keyframe(((fd.fi - 1) / sample_rate), bone.displayData[i].transform.localPosition.y);
                            p_zy.tangentMode = 0;
                            p_zy.inTangent   = 0.0f;
                            p_zy.outTangent  = 0.0f;

                            Keyframe p_zz = new Keyframe(((fd.fi - 1) / sample_rate), bone.displayData[i].transform.localPosition.z + (-previous_z / scale_factor));
                            p_zz.tangentMode = 0;
                            p_zz.inTangent   = 0.0f;
                            p_zz.outTangent  = 0.0f;

                            curve_z[i].AddKey(p_zz);
                            curve_zx[i].AddKey(p_zx);
                            curve_zy[i].AddKey(p_zy);
                        }

                        Keyframe zx = new Keyframe((fd.fi / sample_rate), bone.displayData[i].transform.localPosition.x);
                        zx.tangentMode = 0;
                        zx.inTangent   = 0.0f;
                        zx.outTangent  = 0.0f;

                        Keyframe zy = new Keyframe((fd.fi / sample_rate), bone.displayData[i].transform.localPosition.y);
                        zy.tangentMode = 0;
                        zy.inTangent   = 0.0f;
                        zy.outTangent  = 0.0f;

                        Keyframe zz = new Keyframe((fd.fi / sample_rate), bone.displayData[i].transform.localPosition.z + (-fd.z / scale_factor));
                        zz.tangentMode = 0;
                        zz.inTangent   = 0.0f;
                        zz.outTangent  = 0.0f;

                        curve_z[i].AddKey(zz);
                        previous_z = fd.z;

                        curve_zx[i].AddKey(zx);
                        curve_zy[i].AddKey(zy);

                        // Check if the current index equals the display index

                        if (bone.displayData[i].name.Equals(displayIndex.ToString()))
                        {
                            Keyframe k = new Keyframe((fd.fi / sample_rate), 1.0f);
                            k.tangentMode = 103;
                            k.inTangent   = float.PositiveInfinity;
                            k.outTangent  = float.PositiveInfinity;
                            curve_di[i].AddKey(k);
                        }

                        else
                        {
                            Keyframe k = new Keyframe((fd.fi / sample_rate), 0.0f);
                            k.tangentMode = 103;
                            k.inTangent   = float.PositiveInfinity;
                            k.outTangent  = float.PositiveInfinity;
                            curve_di[i].AddKey(k);
                        }
                    }
                }

                // Get full name of bone
                string bone_name = GetCompletePath(bone.bone.transform);

                // Apply transform keyframes to animation clip
                anim.SetCurve(bone_name, typeof(Transform), "localPosition.x", curve_x);
                anim.SetCurve(bone_name, typeof(Transform), "localPosition.y", curve_y);
                anim.SetCurve(bone_name, typeof(Transform), "localScale.x", curve_cx);
                anim.SetCurve(bone_name, typeof(Transform), "localScale.y", curve_cy);
                anim.SetCurve(bone_name, typeof(Transform), "localEulerAngles.z", curve_ky);

                // Get full name of sprites
                string[] sprite_names = new string[bone.displayData.Count];

                for (int i = 0; i < sprite_names.Length; i++)
                {
                    sprite_names[i] = GetCompletePath(bone.displayData[i].transform);

                    // Apply sprite keyframes to animation clip
                    anim.SetCurve(sprite_names[i], typeof(Transform), "localPosition.x", curve_zx[i]);
                    anim.SetCurve(sprite_names[i], typeof(Transform), "localPosition.y", curve_zy[i]);
                    anim.SetCurve(sprite_names[i], typeof(Transform), "localPosition.z", curve_z[i]);

                    anim.SetCurve(sprite_names[i], typeof(GameObject), "m_IsActive", curve_di[i]);
                }
            }

            // Apply loop
            AnimationClipSettings animClipSett = new AnimationClipSettings();
            animClipSett.loopTime = md.lp;

            AnimationUtility.SetAnimationClipSettings(anim, animClipSett);

            string filePath = "assets/animations/" + sprite.name + "/";

            // Create the anim clip
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }

            AssetDatabase.CreateAsset(anim, filePath + anim.name + ".anim");
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }
    }
        public void Populate(bool character)
        {
            m_HasCharacter = character;

            m_SpriteRects              = new SpriteRect[2];
            m_SpriteRects[0]           = new SpriteRect();
            m_SpriteRects[0].rect      = new Rect(0, 0, 100, 100);
            m_SpriteRects[0].alignment = SpriteAlignment.Center;
            m_SpriteRects[0].border    = Vector4.zero;
            m_SpriteRects[0].name      = "Sprite1";
            m_SpriteRects[0].pivot     = Vector2.zero;
            m_SpriteRects[0].spriteID  = GUID.Generate();

            m_SpriteRects[1]           = new SpriteRect();
            m_SpriteRects[1].rect      = new Rect(100, 0, 100, 100);
            m_SpriteRects[1].alignment = SpriteAlignment.Center;
            m_SpriteRects[1].border    = Vector4.zero;
            m_SpriteRects[1].name      = "Sprite2";
            m_SpriteRects[1].pivot     = Vector2.zero;
            m_SpriteRects[1].spriteID  = GUID.Generate();

            pixelsPerUnit = 100f;

            m_SpriteData          = new SpriteData[2];
            m_SpriteData[0]       = new SpriteData();
            m_SpriteData[0].bones = new List <SpriteBone>();

            var bone = new SpriteBone()
            {
                name     = "Bone-1-1",
                length   = 20f,
                position = Vector3.zero,
                rotation = Quaternion.identity,
                parentId = -1
            };

            m_SpriteData[0].bones.Add(bone);

            bone = new SpriteBone()
            {
                name     = "Bone-1-2",
                length   = 50f,
                position = new Vector3(20, 0, 0),
                rotation = Quaternion.Euler(0, 0, 270),
                parentId = 0
            };
            m_SpriteData[0].bones.Add(bone);

            m_SpriteData[0].vertices    = new Vertex2DMetaData[4];
            m_SpriteData[0].vertices[0] = new Vertex2DMetaData()
            {
                position   = new Vector2(0, 0),
                boneWeight = new BoneWeight()
            };
            m_SpriteData[0].vertices[1] = new Vertex2DMetaData()
            {
                position   = new Vector2(0, 100),
                boneWeight = new BoneWeight()
            };
            m_SpriteData[0].vertices[2] = new Vertex2DMetaData()
            {
                position   = new Vector2(100, 100),
                boneWeight = new BoneWeight()
            };
            m_SpriteData[0].vertices[3] = new Vertex2DMetaData()
            {
                position   = new Vector2(100, 0),
                boneWeight = new BoneWeight()
            };
            m_SpriteData[0].indices = new int[6] {
                0, 1, 2, 0, 2, 3
            };
            m_SpriteData[0].edges = new Vector2Int[4]
            {
                new Vector2Int(0, 1),
                new Vector2Int(1, 2),
                new Vector2Int(2, 3),
                new Vector2Int(3, 0)
            };

            m_SpriteData[1]       = new SpriteData();
            m_SpriteData[1].bones = new List <SpriteBone>();

            bone = new SpriteBone()
            {
                name     = "Bone-2-1",
                length   = 20f,
                position = new Vector3(100, 0, 0),
                rotation = Quaternion.identity,
                parentId = -1
            };
            m_SpriteData[1].bones.Add(bone);

            bone = new SpriteBone()
            {
                name     = "Bone-2-2",
                length   = 50f,
                position = new Vector3(120, 0, 0),
                rotation = Quaternion.Euler(0, 0, 270),
                parentId = 0
            };
            m_SpriteData[1].bones.Add(bone);

            m_SpriteData[1].vertices    = new Vertex2DMetaData[3];
            m_SpriteData[1].vertices[0] = new Vertex2DMetaData()
            {
                position   = new Vector2(100, 0),
                boneWeight = new BoneWeight()
                {
                    boneIndex0 = 0,
                    weight0    = 1.5f
                }
            };
            m_SpriteData[1].vertices[1] = new Vertex2DMetaData()
            {
                position   = new Vector2(100, 100),
                boneWeight = new BoneWeight()
                {
                    boneIndex0 = 1,
                    weight0    = 0.5f
                }
            };
            m_SpriteData[1].vertices[2] = new Vertex2DMetaData()
            {
                position   = new Vector2(190, 50),
                boneWeight = new BoneWeight()
                {
                    boneIndex0 = 0,
                    weight0    = 0.5f,
                    boneIndex1 = 1,
                    weight1    = 0.5f
                }
            };
            m_SpriteData[1].indices = new int[3] {
                0, 1, 2
            };
            m_SpriteData[1].edges = new Vector2Int[3]
            {
                new Vector2Int(0, 1),
                new Vector2Int(1, 2),
                new Vector2Int(2, 0)
            };

            m_Character.bones             = new SpriteBone[3];
            m_Character.bones[0]          = new SpriteBone();
            m_Character.bones[0].name     = "Bone 1";
            m_Character.bones[0].length   = 10f;
            m_Character.bones[0].position = new Vector3(55, 0, 0);
            m_Character.bones[0].rotation = Quaternion.identity;
            m_Character.bones[0].parentId = -1;

            m_Character.bones[1]          = new SpriteBone();
            m_Character.bones[1].name     = "Bone 2";
            m_Character.bones[1].length   = 30f;
            m_Character.bones[1].position = Vector3.zero;
            m_Character.bones[1].rotation = Quaternion.Euler(0, 0, 315);
            m_Character.bones[1].parentId = 0;

            m_Character.bones[2]          = new SpriteBone();
            m_Character.bones[2].name     = "Bone 3";
            m_Character.bones[2].length   = 20f;
            m_Character.bones[2].position = Vector3.zero;
            m_Character.bones[2].rotation = Quaternion.Euler(0, 0, 45);
            m_Character.bones[2].parentId = 1;

            m_Character.parts    = new CharacterPart[2];
            m_Character.parts[0] = new CharacterPart();
            m_Character.parts[0].spritePosition = new RectInt(50, 0, 100, 100);
            m_Character.parts[0].spriteId       = m_SpriteRects[0].spriteID.ToString();
            m_Character.parts[0].bones          = new int[0];

            m_Character.parts[1] = new CharacterPart();
            m_Character.parts[1].spritePosition = new RectInt(75, 0, 100, 100);
            m_Character.parts[1].spriteId       = m_SpriteRects[1].spriteID.ToString();
            m_Character.parts[1].bones          = new int[0];
        }
Ejemplo n.º 13
0
        static bool PostProcessBoneData(ISpriteEditorDataProvider spriteDataProvider, Sprite[] sprites)
        {
            var boneDataProvider    = spriteDataProvider.GetDataProvider <ISpriteBoneDataProvider>();
            var textureDataProvider = spriteDataProvider.GetDataProvider <ITextureDataProvider>();

            if (sprites == null || sprites.Length == 0 || boneDataProvider == null || textureDataProvider == null)
            {
                return(false);
            }

            bool dataChanged = false;

            float definitionScale = CalculateDefinitionScale(textureDataProvider);

            foreach (var sprite in sprites)
            {
                var guid = sprite.GetSpriteID();
                {
                    SpriteRect spriteRect = spriteDataProvider.GetSpriteRects().First(s => { return(s.spriteID == guid); });
                    var        spriteBone = boneDataProvider.GetBones(guid);
                    if (spriteBone == null)
                    {
                        continue;
                    }

                    var spriteBoneCount    = spriteBone.Count;
                    var pivotPointInPixels = sprite.pivot;
                    var bindPose           = new NativeArray <Matrix4x4>(spriteBoneCount, Allocator.Temp);
                    var outputSpriteBones  = new SpriteBone[spriteBoneCount];// NativeArray<SpriteBone>(spriteBone.Count, Allocator.Temp);
                    for (int i = 0; i < spriteBoneCount; ++i)
                    {
                        // Convert position to world unit.
                        SpriteBone sp       = spriteBone[i];
                        var        isRoot   = sp.parentId == -1;
                        var        position = isRoot ? (spriteBone[i].position - Vector3.Scale(spriteRect.rect.size, spriteRect.pivot)) : spriteBone[i].position;
                        position.z           = 0f;
                        sp.position          = position * definitionScale / sprite.pixelsPerUnit;
                        sp.length            = spriteBone[i].length * definitionScale / sprite.pixelsPerUnit;
                        outputSpriteBones[i] = sp;

                        // Calculate bind poses
                        var worldPosition = Vector3.zero;
                        var worldRotation = Quaternion.identity;

                        if (sp.parentId == -1)
                        {
                            worldPosition = sp.position;
                            worldRotation = sp.rotation;
                        }
                        else
                        {
                            var parentBindPose    = bindPose[sp.parentId];
                            var invParentBindPose = Matrix4x4.Inverse(parentBindPose);

                            worldPosition = invParentBindPose.MultiplyPoint(sp.position);
                            worldRotation = sp.rotation * invParentBindPose.rotation;
                        }

                        // Practically Matrix4x4.SetTRInverse
                        var       rot = Quaternion.Inverse(worldRotation);
                        Matrix4x4 mat = Matrix4x4.identity;
                        mat = Matrix4x4.Rotate(rot);
                        mat = mat * Matrix4x4.Translate(-worldPosition);


                        bindPose[i] = mat;
                    }
                    sprite.SetBindPoses(bindPose);
                    sprite.SetBones(outputSpriteBones);
                    bindPose.Dispose();

                    dataChanged = true;
                }
            }

            return(dataChanged);
        }