Example #1
0
        public NewBonesStore PasteSkeletonBones(SpriteCache sprite, List <SpriteBone> spriteBones, bool flipX, bool flipY, float scale = 1.0f)
        {
            NewBonesStore newBonesStore = new NewBonesStore();

            newBonesStore.newBones = skinningCache.CreateBoneCacheFromSpriteBones(spriteBones.ToArray(), scale);
            if (newBonesStore.newBones.Length == 0)
            {
                return(null);
            }

            if (sprite == null || (skinningCache.mode == SkinningMode.SpriteSheet && skinningCache.hasCharacter))
            {
                return(null);
            }

            var spriteRect = sprite.textureRect;
            var skeleton   = skinningCache.GetEffectiveSkeleton(sprite);

            var rectPosition = spriteRect.position;

            if (skinningCache.mode == SkinningMode.Character)
            {
                var characterPart = sprite.GetCharacterPart();
                if (characterPart == null)
                {
                    return(null);
                }
                rectPosition = characterPart.position;
            }

            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], rectPosition, spriteRect, flipX, flipY);
                newRotations[i] = GetFlippedBoneRotation(newBonesStore.newBones[i], flipX, flipY);
            }
            for (var i = 0; i < newBonesStore.newBones.Length; ++i)
            {
                if (newBonesStore.newBones[i].parent == null)
                {
                    SetBonePositionAndRotation(newBonesStore.newBones, newBonesStore.newBones[i], newPositions, newRotations);
                }
            }

            if (skinningCache.mode == SkinningMode.SpriteSheet)
            {
                newBonesStore.MapAllExistingBones();
                skeleton.SetBones(newBonesStore.newBones);
            }
            else
            {
                var existingBoneNames = skeleton.bones.Select(x => x.name).ToList();

                skeleton.AddBones(newBonesStore.newBones);

                var bones = skeleton.bones;

                // Update names of all newly pasted bones
                foreach (var bone in newBonesStore.newBones)
                {
                    if (existingBoneNames.Contains(bone.name))
                    {
                        var oldBoneName = bone.name;
                        bone.name = SkeletonController.AutoBoneName(bone.parentBone, bones);
                        existingBoneNames.Add(bone.name);
                        newBonesStore.newBoneNameDict.Add(oldBoneName, bone.name);
                    }
                    else
                    {
                        newBonesStore.newBoneNameDict.Add(bone.name, bone.name);
                    }
                }

                skeleton.SetDefaultPose();
            }

            skinningCache.events.skeletonTopologyChanged.Invoke(skeleton);
            return(newBonesStore);
        }
Example #2
0
        public void PasteMesh(SpriteCache sprite, SkinningCopySpriteData skinningSpriteData, bool flipX, bool flipY, float scale, NewBonesStore newBonesStore)
        {
            if (sprite == null)
            {
                return;
            }

            meshTool.SetupSprite(sprite);
            meshTool.mesh.vertices = skinningSpriteData.vertices;
            if (!Mathf.Approximately(scale, 1f) || flipX || flipY)
            {
                var spriteRect = sprite.textureRect;
                foreach (var vertex in meshTool.mesh.vertices)
                {
                    var position = vertex.position;
                    if (!Mathf.Approximately(scale, 1f))
                    {
                        position = position * scale;
                    }
                    if (flipX)
                    {
                        position.x = spriteRect.width - vertex.position.x;
                    }
                    if (flipY)
                    {
                        position.y = spriteRect.height - vertex.position.y;
                    }
                    vertex.position = position;
                }
            }
            meshTool.mesh.indices = skinningSpriteData.indices;
            meshTool.mesh.edges   = skinningSpriteData.edges;

            int[]       copyBoneToNewBones = new int[skinningSpriteData.boneWeightNames.Count];
            BoneCache[] setBones           = null;

            if (newBonesStore != null && newBonesStore.newBones != null)
            {
                // Update bone weights with new bone indices
                var setBonesList = new List <BoneCache>();
                copyBoneToNewBones = new int[skinningSpriteData.boneWeightNames.Count];
                int index = 0;
                for (int i = 0; i < skinningSpriteData.boneWeightNames.Count; ++i)
                {
                    string oldBoneName = skinningSpriteData.boneWeightNames[i];
                    string newBoneName;
                    newBonesStore.newBoneNameDict.TryGetValue(oldBoneName, out newBoneName);
                    var newBone = newBonesStore.newBones.FirstOrDefault(bone => bone.name == newBoneName);
                    copyBoneToNewBones[i] = -1;
                    if (newBone == null)
                    {
                        continue;
                    }

                    for (int j = 0; j < skinningSpriteData.spriteBones.Count; ++j)
                    {
                        if (skinningSpriteData.spriteBones[j].spriteBone.name == oldBoneName)
                        {
                            copyBoneToNewBones[i] = index++;
                            setBonesList.Add(newBone);
                            break;
                        }
                    }
                }
                setBones = setBonesList.ToArray();
            }
            else
            {
                // Attempt to link weights based on existing bone names
                var skeleton       = skinningCache.GetEffectiveSkeleton(sprite);
                var characterBones = new List <BoneCache>();
                for (int i = 0; i < skinningSpriteData.boneWeightNames.Count; ++i)
                {
                    copyBoneToNewBones[i] = -1;
                    var boneName = skinningSpriteData.boneWeightNames[i];
                    for (int j = 0; j < skeleton.bones.Length; ++j)
                    {
                        if (skeleton.bones[j].name == boneName)
                        {
                            copyBoneToNewBones[i] = characterBones.Count;
                            characterBones.Add(skeleton.bones[j]);
                            break;
                        }
                    }
                }
                setBones = characterBones.ToArray();
            }

            // Remap new bone indexes from copied bone indexes
            foreach (var vertex in meshTool.mesh.vertices)
            {
                var editableBoneWeight = vertex.editableBoneWeight;

                for (var i = 0; i < editableBoneWeight.Count; ++i)
                {
                    if (!editableBoneWeight[i].enabled)
                    {
                        continue;
                    }

                    if (copyBoneToNewBones.Length > editableBoneWeight[i].boneIndex)
                    {
                        var boneIndex = copyBoneToNewBones[editableBoneWeight[i].boneIndex];
                        if (boneIndex != -1)
                        {
                            editableBoneWeight[i].boneIndex = boneIndex;
                        }
                    }
                }
            }

            // Update associated bones for mesh
            meshTool.mesh.SetCompatibleBoneSet(setBones);
            meshTool.mesh.bones = setBones; // Fixes weights for bones that do not exist

            // Update associated bones for character
            if (skinningCache.hasCharacter)
            {
                var characterPart = sprite.GetCharacterPart();
                if (characterPart != null)
                {
                    characterPart.bones = setBones;
                    skinningCache.events.characterPartChanged.Invoke(characterPart);
                }
            }

            meshTool.UpdateMesh();
        }
Example #3
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);
        }