private void CollectBones(List <GPUSkinningBone> bones_result, Transform[] bones_smr, Matrix4x4[] bindposes, GPUSkinningBone parentBone, Transform currentBoneTransform, int currentBoneIndex)
    {
        GPUSkinningBone currentBone = new GPUSkinningBone();

        bones_result.Add(currentBone);

        int indexOfSmrBones = System.Array.IndexOf(bones_smr, currentBoneTransform);

        currentBone.transform       = currentBoneTransform;
        currentBone.name            = currentBone.transform.gameObject.name;
        currentBone.bindpose        = indexOfSmrBones == -1 ? Matrix4x4.identity : bindposes[indexOfSmrBones];
        currentBone.parentBoneIndex = parentBone == null ? -1 : bones_result.IndexOf(parentBone);

        if (parentBone != null)
        {
            parentBone.childrenBonesIndices[currentBoneIndex] = bones_result.IndexOf(currentBone);
        }

        int numChildren = currentBone.transform.childCount;

        if (numChildren > 0)
        {
            currentBone.childrenBonesIndices = new int[numChildren];
            for (int i = 0; i < numChildren; ++i)
            {
                CollectBones(bones_result, bones_smr, bindposes, currentBone, currentBone.transform.GetChild(i), i);
            }
        }
    }
Example #2
0
    private void OnGUI_Bone(GPUSkinningBone bone, int indentLevel)
    {
        GUILayout.BeginHorizontal();
        {
            for (int i = 0; i < indentLevel; ++i)
            {
                GUILayout.Space(20);
            }

            EditorGUI.BeginChangeCheck();
            bool isExposed = GUILayout.Toggle(bone.isExposed, bone.name);
            if (EditorGUI.EndChangeCheck())
            {
                bone.isExposed = isExposed;
                ApplyAnimModification();
            }
        }
        GUILayout.EndHorizontal();

        int numChildren = bone.childrenBonesIndices == null ? 0 : bone.childrenBonesIndices.Length;

        for (int i = 0; i < numChildren; ++i)
        {
            OnGUI_Bone(anim.bones[bone.childrenBonesIndices[i]], indentLevel + 1);
        }
    }
    private IEnumerator SamplingCoroutine(GPUSkinningFrame frame, int totalFrames)
    {
        yield return(new WaitForEndOfFrame());

        GPUSkinningBone[] bones = gpuSkinningAnimation.bones;
        int numBones            = bones.Length;

        for (int i = 0; i < numBones; ++i)
        {
            Transform       boneTransform = bones[i].transform;
            GPUSkinningBone currentBone   = GetBoneByTransform(boneTransform);
            frame.matrices[i] = currentBone.bindpose;
            do
            {
                Matrix4x4 mat = Matrix4x4.TRS(currentBone.transform.localPosition, currentBone.transform.localRotation, currentBone.transform.localScale);
                frame.matrices[i] = mat * frame.matrices[i];
                if (currentBone.parentBoneIndex == -1)
                {
                    break;
                }
                else
                {
                    currentBone = bones[currentBone.parentBoneIndex];
                }
            }while (true);
        }

        if (samplingFrameIndex == 0)
        {
            rootMotionPosition = bones[gpuSkinningAnimation.rootBoneIndex].transform.localPosition;
            rootMotionRotation = bones[gpuSkinningAnimation.rootBoneIndex].transform.localRotation;
        }
        else
        {
            Vector3    newPosition   = bones[gpuSkinningAnimation.rootBoneIndex].transform.localPosition;
            Quaternion newRotation   = bones[gpuSkinningAnimation.rootBoneIndex].transform.localRotation;
            Vector3    deltaPosition = newPosition - rootMotionPosition;
            frame.rootMotionDeltaPositionQ = Quaternion.Inverse(Quaternion.Euler(transform.forward.normalized)) * Quaternion.Euler(deltaPosition.normalized);
            frame.rootMotionDeltaPositionL = deltaPosition.magnitude;
            frame.rootMotionDeltaRotation  = Quaternion.Inverse(rootMotionRotation) * newRotation;
            rootMotionPosition             = newPosition;
            rootMotionRotation             = newRotation;

            if (samplingFrameIndex == 1)
            {
                gpuSkinningClip.frames[0].rootMotionDeltaPositionQ = gpuSkinningClip.frames[1].rootMotionDeltaPositionQ;
                gpuSkinningClip.frames[0].rootMotionDeltaPositionL = gpuSkinningClip.frames[1].rootMotionDeltaPositionL;
                gpuSkinningClip.frames[0].rootMotionDeltaRotation  = gpuSkinningClip.frames[1].rootMotionDeltaRotation;
            }
        }

        ++samplingFrameIndex;
    }
Example #4
0
    public static string BoneHierarchyPath(GPUSkinningBone[] bones, int boneIndex)
    {
        if (bones == null || boneIndex < 0 || boneIndex >= bones.Length)
        {
            return(null);
        }

        GPUSkinningBone bone = bones[boneIndex];
        string          path = bone.name;

        while (bone.parentBoneIndex != -1)
        {
            bone = bones[bone.parentBoneIndex];
            path = bone.name + "/" + path;
        }
        return(path);
    }
Example #5
0
    public static void BonesHierarchy_Internal(GPUSkinningAnimation gpuSkinningAnimation, GPUSkinningBone bone, string tabs, ref string str)
    {
        str += tabs + bone.name + "\n";

        int numChildren = bone.childrenBonesIndices == null ? 0 : bone.childrenBonesIndices.Length;

        for (int i = 0; i < numChildren; ++i)
        {
            BonesHierarchy_Internal(gpuSkinningAnimation, gpuSkinningAnimation.bones[bone.childrenBonesIndices[i]], tabs + "    ", ref str);
        }
    }
 private int GetBoneIndex(GPUSkinningBone bone)
 {
     return(System.Array.IndexOf(gpuSkinningAnimation.bones, bone));
 }
    private Mesh CreateNewMesh(Mesh mesh, string meshName)
    {
        Vector3[] normals  = mesh.normals;
        Vector4[] tangents = mesh.tangents;
        Color[]   colors   = mesh.colors;
        Vector2[] uv       = mesh.uv;

        Mesh newMesh = new Mesh();

        newMesh.name     = meshName;
        newMesh.vertices = mesh.vertices;
        if (normals != null && normals.Length > 0)
        {
            newMesh.normals = normals;
        }
        if (tangents != null && tangents.Length > 0)
        {
            newMesh.tangents = tangents;
        }
        if (colors != null && colors.Length > 0)
        {
            newMesh.colors = colors;
        }
        if (uv != null && uv.Length > 0)
        {
            newMesh.uv = uv;
        }

        int numVertices = mesh.vertexCount;

        BoneWeight[] boneWeights = mesh.boneWeights;
        Vector4[]    uv2         = new Vector4[numVertices];
        Vector4[]    uv3         = new Vector4[numVertices];
        Transform[]  smrBones    = smr.bones;
        for (int i = 0; i < numVertices; ++i)
        {
            BoneWeight boneWeight = boneWeights[i];

            BoneWeightSortData[] weights = new BoneWeightSortData[4];
            weights[0] = new BoneWeightSortData()
            {
                index = boneWeight.boneIndex0, weight = boneWeight.weight0
            };
            weights[1] = new BoneWeightSortData()
            {
                index = boneWeight.boneIndex1, weight = boneWeight.weight1
            };
            weights[2] = new BoneWeightSortData()
            {
                index = boneWeight.boneIndex2, weight = boneWeight.weight2
            };
            weights[3] = new BoneWeightSortData()
            {
                index = boneWeight.boneIndex3, weight = boneWeight.weight3
            };
            System.Array.Sort(weights);

            GPUSkinningBone bone0 = GetBoneByTransform(smrBones[weights[0].index]);
            GPUSkinningBone bone1 = GetBoneByTransform(smrBones[weights[1].index]);
            GPUSkinningBone bone2 = GetBoneByTransform(smrBones[weights[2].index]);
            GPUSkinningBone bone3 = GetBoneByTransform(smrBones[weights[3].index]);

            Vector4 skinData_01 = new Vector4();
            skinData_01.x = GetBoneIndex(bone0);
            skinData_01.y = weights[0].weight;
            skinData_01.z = GetBoneIndex(bone1);
            skinData_01.w = weights[1].weight;
            uv2[i]        = skinData_01;

            Vector4 skinData_23 = new Vector4();
            skinData_23.x = GetBoneIndex(bone2);
            skinData_23.y = weights[2].weight;
            skinData_23.z = GetBoneIndex(bone3);
            skinData_23.w = weights[3].weight;
            uv3[i]        = skinData_23;
        }
        newMesh.SetUVs(1, new List <Vector4>(uv2));
        newMesh.SetUVs(2, new List <Vector4>(uv3));

        newMesh.triangles = mesh.triangles;
        return(newMesh);
    }
Example #8
0
    private void ConstructJoints()
    {
        if (joints == null)
        {
            GPUSkinningPlayerJoint[] existingJoints = go.GetComponentsInChildren <GPUSkinningPlayerJoint>();

            GPUSkinningBone[] bones = res.anim.bones;
            int numBones            = bones == null ? 0 : bones.Length;
            for (int i = 0; i < numBones; ++i)
            {
                GPUSkinningBone bone = bones[i];
                if (bone.isExposed)
                {
                    if (joints == null)
                    {
                        joints = new List <GPUSkinningPlayerJoint>();
                    }

                    bool inTheExistingJoints = false;
                    if (existingJoints != null)
                    {
                        for (int j = 0; j < existingJoints.Length; ++j)
                        {
                            if (existingJoints[j] != null && existingJoints[j].BoneGUID == bone.guid)
                            {
                                if (existingJoints[j].BoneIndex != i)
                                {
                                    existingJoints[j].Init(i, bone.guid);
                                    GPUSkinningUtil.MarkAllScenesDirty();
                                }
                                joints.Add(existingJoints[j]);
                                existingJoints[j]   = null;
                                inTheExistingJoints = true;
                                break;
                            }
                        }
                    }

                    if (!inTheExistingJoints)
                    {
                        GameObject jointGo = new GameObject(bone.name);
                        jointGo.transform.parent        = go.transform;
                        jointGo.transform.localPosition = Vector3.zero;
                        jointGo.transform.localScale    = Vector3.one;

                        GPUSkinningPlayerJoint joint = jointGo.AddComponent <GPUSkinningPlayerJoint>();
                        joints.Add(joint);
                        joint.Init(i, bone.guid);
                        GPUSkinningUtil.MarkAllScenesDirty();
                    }
                }
            }

            if (!Application.isPlaying)
            {
#if UNITY_EDITOR
                UnityEditor.EditorApplication.CallbackFunction DelayCall = null;
                DelayCall = () =>
                {
                    UnityEditor.EditorApplication.delayCall -= DelayCall;
                    DeleteInvalidJoints(existingJoints);
                };
                UnityEditor.EditorApplication.delayCall += DelayCall;
#endif
            }
            else
            {
                DeleteInvalidJoints(existingJoints);
            }
        }
    }
Example #9
0
    private void BakeAllAnimClip(List <AnimationState> curAnims, string path, GameObject go, float frameRate, GameObject rootBone, GPUSkinningBone[] bones)
    {
        int   curClipFrame = 0;
        float sampleTime   = 0;
        float perFrameTime = 0;
        float len          = 0;
        float s            = 1;

        for (int i = 0; i < this.animData.animClips.Count; i++)
        {
            if (!this.animData.animClips[i].clip.legacy)
            {
                Debug.LogError(string.Format("{0} is not legacy!!", this.animData.animClips[i].clip.name));
                continue;
            }
            if (this.animData.animClips[i].name.IndexOf("_all") >= 0)
            {
                continue;
            }

            //前后各加一帧
            curClipFrame += Mathf.CeilToInt(curAnims[i].clip.frameRate * curAnims[i].length * s) + 2;
        }

        len = curClipFrame / frameRate;
        int       pow1    = Mathf.NextPowerOfTwo(curClipFrame);
        int       width   = Mathf.NextPowerOfTwo(bones.Length * 3);
        Texture2D animMap = new Texture2D(width, pow1, format, false);

        animMap.wrapMode   = TextureWrapMode.Clamp;
        animMap.filterMode = FilterMode.Point;

        animMap.name = this.animData.name;
        int startFrame = 0;

        for (int i = 0; i < this.animData.animClips.Count; i++)
        {
            if (!this.animData.animClips[i].clip.legacy)
            {
                Debug.LogError(string.Format("{0} is not legacy!!", this.animData.animClips[i].clip.name));
                continue;
            }
            if (this.animData.animClips[i].name.IndexOf("_all") >= 0)
            {
                continue;
            }

            animData.AnimationPlay(curAnims[i].name);
            sampleTime = 0;
            int curClipFrame1 = Mathf.CeilToInt(curAnims[i].clip.frameRate * curAnims[i].length * s) + 2;
            perFrameTime = curAnims[i].length / (curClipFrame1 - 2);
            for (int k = startFrame; k < curClipFrame1 + startFrame - 2; k++)
            {
                if (sampleTime > curAnims[i].length)
                {
                    sampleTime = curAnims[i].length;
                }
                curAnims[i].time = sampleTime;

                this.animData.animation.Sample();
                for (int j = 0; j < bones.Length; j++)
                {
                    GPUSkinningBone currentBone = bones[j];
                    Matrix4x4       lastMat     = currentBone.bindpose;
                    while (true)
                    {
                        if (currentBone.parentBoneIndex == -1)
                        {
                            Matrix4x4 mat = Matrix4x4.TRS(currentBone.transform.localPosition, currentBone.transform.localRotation, currentBone.transform.localScale);
                            if (rootBone.transform != go.transform)
                            {
                                mat = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, go.transform.localScale) * mat;
                            }

                            lastMat = mat * lastMat;
                            break;
                        }
                        else
                        {
                            Matrix4x4 mat = Matrix4x4.TRS(currentBone.transform.localPosition, currentBone.transform.localRotation, currentBone.transform.localScale);
                            lastMat     = mat * lastMat;
                            currentBone = bones[currentBone.parentBoneIndex];
                        }
                    }

                    animMap.SetPixel(j * 3, k + 1, new Color(lastMat.m00, lastMat.m01, lastMat.m02, lastMat.m03));
                    animMap.SetPixel(j * 3 + 1, k + 1, new Color(lastMat.m10, lastMat.m11, lastMat.m12, lastMat.m13));
                    animMap.SetPixel(j * 3 + 2, k + 1, new Color(lastMat.m20, lastMat.m21, lastMat.m22, lastMat.m23));

                    if (k == startFrame)
                    {
                        animMap.SetPixel(j * 3, k, new Color(lastMat.m00, lastMat.m01, lastMat.m02, lastMat.m03));
                        animMap.SetPixel(j * 3 + 1, k, new Color(lastMat.m10, lastMat.m11, lastMat.m12, lastMat.m13));
                        animMap.SetPixel(j * 3 + 2, k, new Color(lastMat.m20, lastMat.m21, lastMat.m22, lastMat.m23));
                    }
                    else if (k == curClipFrame1 + startFrame - 3)
                    {
                        animMap.SetPixel(j * 3, k + 2, new Color(lastMat.m00, lastMat.m01, lastMat.m02, lastMat.m03));
                        animMap.SetPixel(j * 3 + 1, k + 2, new Color(lastMat.m10, lastMat.m11, lastMat.m12, lastMat.m13));
                        animMap.SetPixel(j * 3 + 2, k + 2, new Color(lastMat.m20, lastMat.m21, lastMat.m22, lastMat.m23));
                    }
                }
                sampleTime += perFrameTime;
            }

            startFrame += curClipFrame1;
        }

        animMap.Apply();
        this.bakedDataList.Add(new BakedData(animMap.name, pow1 / frameRate, animMap));
    }
Example #10
0
    public List <BakedData> Bake(GameObject go, GameObject fbx, GameObject rootBone, string path, Dictionary <string, string> dic, ref Mesh tarMesh)
    {
        if (this.animData == null)
        {
            Debug.LogError("bake data is null!!");
            return(this.bakedDataList);
        }


        List <GPUSkinningBone> bones_result = new List <GPUSkinningBone>();
        SkinnedMeshRenderer    skin         = animData.skin;

        CollectBones(bones_result, skin.bones, skin.sharedMesh.bindposes, null, rootBone.transform, 0);
        GPUSkinningBone[] bones = bones_result.ToArray();
        Mesh mesh = new Mesh();

        mesh.name     = skin.sharedMesh.name;
        mesh.vertices = skin.sharedMesh.vertices;
        mesh.normals  = skin.sharedMesh.normals;
        mesh.tangents = skin.sharedMesh.tangents;
        mesh.uv       = skin.sharedMesh.uv;
        BoneWeight[] boneWeights = skin.sharedMesh.boneWeights;
        int          numVertices = mesh.vertices.Length;

        Vector4[]   uv2      = new Vector4[numVertices];
        Vector4[]   uv3      = new Vector4[numVertices];
        Transform[] smrBones = skin.bones;

        for (int i = 0; i < mesh.vertices.Length; i++)
        {
            BoneWeight           weight  = boneWeights[i];
            BoneWeightSortData[] weights = new BoneWeightSortData[4];
            weights[0] = new BoneWeightSortData()
            {
                index = weight.boneIndex0, weight = weight.weight0
            };
            weights[1] = new BoneWeightSortData()
            {
                index = weight.boneIndex1, weight = weight.weight1
            };
            weights[2] = new BoneWeightSortData()
            {
                index = weight.boneIndex2, weight = weight.weight2
            };
            weights[3] = new BoneWeightSortData()
            {
                index = weight.boneIndex3, weight = weight.weight3
            };
            System.Array.Sort(weights);
            //Debug.Log(weights[0].index + ":" + weights[0].weight + ":" + weights[1].index + ":" + weights[1].weight + ":" + weights[2].index + ":" + weights[2].weight + ":" + weights[3].index + ":" + weights[3].weight);
            GPUSkinningBone bone0 = GetBoneByTransform(smrBones[weights[0].index], bones);
            GPUSkinningBone bone1 = GetBoneByTransform(smrBones[weights[1].index], bones);
            GPUSkinningBone bone2 = GetBoneByTransform(smrBones[weights[2].index], bones);
            GPUSkinningBone bone3 = GetBoneByTransform(smrBones[weights[3].index], bones);

            Vector4 skinData_01 = new Vector4();
            skinData_01.x = GetBoneIndex(bone0, bones);
            skinData_01.y = weights[0].weight;
            skinData_01.z = GetBoneIndex(bone1, bones);
            skinData_01.w = weights[1].weight;
            uv2[i]        = skinData_01;
        }

        mesh.SetUVs(1, new List <Vector4>(uv2));
        mesh.triangles = skin.sharedMesh.triangles;

        AssetDatabase.CreateAsset(mesh, "Assets/" + Path.Combine(path, mesh.name + "mesh.asset"));

        tarMesh = mesh;
        BakeAllAnimClip(this.animData.animClips, path, go, 30f, rootBone, bones);

        Object target  = PrefabUtility.GetPrefabParent(fbx);
        string fbxName = AssetDatabase.GetAssetPath(target);

        if (target == null)
        {
            fbxName = AssetDatabase.GetAssetPath(fbx);
        }
        else
        {
            fbxName = "Assets/" + path + "/" + fbx.name + ".fbx";
        }
        Debug.Log(fbxName);
        ModelImporter modelImporter = (ModelImporter)AssetImporter.GetAtPath(fbxName);

        GenAnimationDataFile(modelImporter.clipAnimations, this.animData.animClips, 30f, go, path, dic);

        return(this.bakedDataList);
    }
Example #11
0
 private int GetBoneIndex(GPUSkinningBone bone, GPUSkinningBone[] bones)
 {
     return(System.Array.IndexOf(bones, bone));
 }