示例#1
0
    void OnGUI()
    {
        targetGo = (GameObject)EditorGUILayout.ObjectField(targetGo, typeof(GameObject), true);
        subPath  = targetGo == null ? subPath : targetGo.name;
        EditorGUILayout.LabelField(string.Format("保存路径output path:{0}", Path.Combine(path, subPath)));
        path    = EditorGUILayout.TextField(path);
        subPath = EditorGUILayout.TextField(subPath);

        if (GUILayout.Button("Bake"))
        {
            if (targetGo == null)
            {
                EditorUtility.DisplayDialog("err", "targetGo is null!", "OK");
                return;
            }

            if (baker == null)
            {
                baker = new AnimMapBaker();
            }

            baker.SetAnimData(targetGo);

            List <BakedData> list = baker.Bake();

            if (list != null)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    BakedData data = list[i];
                    Save(ref data);
                }
            }
        }
    }
示例#2
0
    private Material SaveAsMat(ref BakedData data)
    {
        if (animMapShader == null)
        {
            EditorUtility.DisplayDialog("err", "shader is null!!", "OK");
            return(null);
        }

        if (targetGo == null || !targetGo.GetComponentInChildren <SkinnedMeshRenderer>())
        {
            EditorUtility.DisplayDialog("err", "SkinnedMeshRender is null!!", "OK");
            return(null);
        }

        SkinnedMeshRenderer smr     = targetGo.GetComponentInChildren <SkinnedMeshRenderer>();
        Material            mat     = new Material(smr.sharedMaterial);
        Texture2D           animMap = SaveAsAsset(ref data);

        //mat.SetTexture("_MainTex", smr.sharedMaterial.mainTexture);
        mat.SetTexture("_AnimMap", animMap);
        mat.SetFloat("_AnimLen", data.animLen);

        string folderPath = CreateFolder();

        AssetDatabase.CreateAsset(mat, Path.Combine(folderPath, data.name + ".mat"));

        return(mat);
    }
示例#3
0
    private void SaveAsAsset(ref BakedData data)
    {
        MemoryStream file   = new MemoryStream(1024);
        BinaryWriter writer = new BinaryWriter(file);

        writer.Write(data.animMapWidth);
        writer.Write(data.animMapHeight);
        writer.Write(data.animLen);
        for (int i = 0; i < data.animData.Length; ++i)
        {
            var point = data.animData[i];
            writer.Write((short)(point.x * 1000f));
            writer.Write((short)(point.y * 1000f));
            writer.Write((short)(point.z * 1000f));
        }
        StringBuilder pathBuilder = new StringBuilder(1024);

        pathBuilder.Append(Application.dataPath).Append('/');
        pathBuilder.Append(subPath).Append('/');
        pathBuilder.Append(data.name).Append(".bytes");
        var fullPath  = pathBuilder.ToString();
        var directory = Path.GetDirectoryName(fullPath);

        if (!Directory.Exists(directory))
        {
            Directory.CreateDirectory(directory);
        }
        File.WriteAllBytes(fullPath, file.GetBuffer());
    }
示例#4
0
    private Mesh SaveAsMesh(ref BakedData data)
    {
        if (targetGo == null || !targetGo.GetComponentInChildren <SkinnedMeshRenderer>())
        {
            EditorUtility.DisplayDialog("err", "SkinnedMeshRender is null!!", "OK");
            return(null);
        }

        SkinnedMeshRenderer smr = targetGo.GetComponentInChildren <SkinnedMeshRenderer>();
        var mesh = new Mesh();

        smr.BakeMesh(mesh);
        var uv2 = new Vector2[mesh.vertexCount];

        for (var i = mesh.vertexCount - 1; i >= 0; i--)
        {
            uv2[i] = new Vector2(i, i);
        }
        mesh.uv2 = uv2;
        string folderPath = CreateFolder();

        AssetDatabase.CreateAsset(mesh, Path.Combine(folderPath, data.name + ".mesh"));

        return(mesh);
    }
    private static Material SaveAsMat(ref BakedData data)
    {
        if (_animMapShader == null)
        {
            EditorUtility.DisplayDialog("err", "shader is null!!", "OK");
            return(null);
        }

        if (_targetGo == null || !_targetGo.GetComponentInChildren <SkinnedMeshRenderer>())
        {
            EditorUtility.DisplayDialog("err", "SkinnedMeshRender is null!!", "OK");
            return(null);
        }

        var smr     = _targetGo.GetComponentInChildren <SkinnedMeshRenderer>();
        var mat     = new Material(_animMapShader);
        var animMap = SaveAsAsset(ref data);

        mat.SetTexture(MainTex, smr.sharedMaterial.mainTexture);
        mat.SetTexture(AnimMap, animMap);
        mat.SetFloat(AnimLen, data.AnimLen);

        var folderPath = CreateFolder();

        AssetDatabase.CreateAsset(mat, Path.Combine(folderPath, $"{data.Name}.mat"));

        return(mat);
    }
示例#6
0
    private void SaveAsPrefab(ref BakedData data, int i, Mesh mesh)
    {
        Material mat = SaveAsMat(ref data, i);

        if (mat == null)
        {
            EditorUtility.DisplayDialog("err", "mat is null!!", "OK");
            return;
        }

        GameObject go = new GameObject();

        go.AddComponent <MeshRenderer>().sharedMaterial = mat;
        go.AddComponent <MeshFilter>().sharedMesh       = mesh;
        mat.enableInstancing = true;
        string folderPath = CreateFolder();
        string prefabName = data.name;

        //if (data.name.LastIndexOf("_") >= 0)
        //{
        //    prefabName = data.name.Substring(0, data.name.LastIndexOf("_"));
        //}

        prefabName += "prefab";
        PrefabUtility.CreatePrefab(Path.Combine(folderPath, prefabName + ".prefab").Replace("\\", "/"), go);
        GameObject.DestroyImmediate(go);
    }
示例#7
0
    private Material SaveAsMat(ref BakedData data, int i)
    {
        if (animMapShader == null)
        {
            animMapShader = Shader.Find("Custom/CharactorShader");
        }

        if (targetGo == null || !targetGo.GetComponentInChildren <SkinnedMeshRenderer>())
        {
            EditorUtility.DisplayDialog("err", "SkinnedMeshRender is null!!", "OK");
            return(null);
        }

        SkinnedMeshRenderer smr     = targetGo.GetComponentInChildren <SkinnedMeshRenderer>();
        Material            mat     = new Material(animMapShader);
        Texture2D           animMap = SaveAsAsset(ref data, i);

        mat.SetTexture("_MainTex", smr.sharedMaterial.mainTexture);
        mat.SetTexture("_AnimMap", animMap);
        mat.SetFloat("_AnimAll", data.animLen);
        string folderPath = CreateFolder();
        string matName    = data.name;

        //if (data.name.LastIndexOf("_") >= 0)
        //{
        //    matName = data.name.Substring(0, data.name.LastIndexOf("_"));
        //}
        matName += "matbaked";
        AssetDatabase.CreateAsset(mat, Path.Combine(folderPath, matName + ".mat"));

        return(mat);
    }
示例#8
0
    private Material SaveAsMat(ref BakedData data)
    {
        if (_animMapShader == null)
        {
            EditorUtility.DisplayDialog("err", "shader is null!!", "OK");
            return(null);
        }

        if (_targetGo == null || !_targetGo.GetComponentInChildren <SkinnedMeshRenderer>())
        {
            EditorUtility.DisplayDialog("err", "SkinnedMeshRender is null!!", "OK");
            return(null);
        }

        var smr     = _targetGo.GetComponentInChildren <SkinnedMeshRenderer>();
        var mat     = new Material(_animMapShader);
        var animMap = SaveAsAsset(ref data);

        mat.SetTexture("_MainTex", smr.sharedMaterial.mainTexture);
        mat.SetTexture("_AnimMap", animMap);
        mat.SetFloat("_AnimLen", data.AnimLen);
        mat.SetInt("_AnimOffsetYPixel", data.AnimOffsetYPixel);
        if (data.VATMultipleRows)
        {
            mat.EnableKeyword("VATMultipleRows_ON");
            mat.SetInt("_VATMultipleRows", 1);
        }
        mat.enableInstancing = true;

        var folderPath = CreateFolder();

        AssetDatabase.CreateAsset(mat, Path.Combine(folderPath, data.Name + ".mat"));

        return(mat);
    }
    private Material[] SaveAsMat(ref BakedData data)
    {
        if (animMapShader == null)
        {
            EditorUtility.DisplayDialog("err", "shader is null!!", "OK");
            return(null);
        }

        if (targetGo == null || !targetGo.GetComponentInChildren <SkinnedMeshRenderer>())
        {
            EditorUtility.DisplayDialog("err", "SkinnedMeshRender is null!!", "OK");
            return(null);
        }

        SkinnedMeshRenderer smr = targetGo.GetComponentInChildren <SkinnedMeshRenderer>();

        Material[] mats = new Material[smr.sharedMaterials.Length];
        for (int i = 0; i < smr.sharedMaterials.Length; i++)
        {
            Material  mat     = new Material(animMapShader);
            Texture2D animMap = SaveAsAsset(ref data);
            mat.SetTexture("_MainTex", smr.sharedMaterials[i].mainTexture);
            mat.SetTexture("_AnimMap", animMap);
            mat.SetFloat("_AnimLen", data.animLen);
            mat.enableInstancing = true;
            string folderPath = CreateFolder();
            AssetDatabase.CreateAsset(mat, Path.Combine(folderPath, data.name + i + ".mat"));

            mats[i] = mat;
        }
        return(mats);
    }
示例#10
0
    void OnGUI()
    {
        GUILayout.Label("Target Prefab");
        GameObject oldObj = targetGo;

        targetGo = (GameObject)EditorGUILayout.ObjectField(targetGo, typeof(GameObject), true);
        GUILayout.Label("Target Animation FBX");
        animationFBX = (GameObject)EditorGUILayout.ObjectField(animationFBX, typeof(GameObject), true);
        if (targetGo != oldGameObject)
        {
            oldGameObject = targetGo;
        }

        GUILayout.Label("RootBone GameObject");
        rootBone = (GameObject)EditorGUILayout.ObjectField(rootBone, typeof(GameObject), true);

        Object target = PrefabUtility.GetPrefabParent(targetGo);

        path = AssetDatabase.GetAssetPath(target);
        if (path == "")
        {
            path = AssetDatabase.GetAssetPath(targetGo);
        }
        int index = path.LastIndexOf("/");

        if (index >= 0)
        {
            path = path.Substring(7, index - 7);
        }

        EditorGUILayout.LabelField(string.Format("output path:{0}", path));
        path = EditorGUILayout.TextField(path);

        if (GUILayout.Button("Bake"))
        {
            if (targetGo == null)
            {
                EditorUtility.DisplayDialog("err", "targetGo is null!", "OK");
                return;
            }

            baker = new AnimMapBaker();

            baker.SetAnimData(targetGo, animationFBX, path);
            Dictionary <string, string> dic = new Dictionary <string, string>();
            Mesh             tarMesh        = null;
            List <BakedData> list           = baker.Bake(targetGo, animationFBX, rootBone, path, dic, ref tarMesh);

            if (list != null)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    BakedData data = list[i];
                    Save(ref data, i, tarMesh);
                }
            }
        }
    }
    private static Texture2D SaveAsAsset(ref BakedData data)
    {
        var folderPath = CreateFolder();
        var animMap    = new Texture2D(data.AnimMapWidth, data.AnimMapHeight, TextureFormat.RGBAHalf, false);

        animMap.LoadRawTextureData(data.RawAnimMap);
        AssetDatabase.CreateAsset(animMap, Path.Combine(folderPath, data.Name + ".asset"));
        return(animMap);
    }
示例#12
0
    private Texture2D SaveAsAsset(ref BakedData data)
    {
        string    folderPath = CreateFolder();
        Texture2D animMap    = new Texture2D(data.animMapWidth, data.animMapHeight, TextureFormat.RGBAHalf, false);

        animMap.LoadRawTextureData(data.rawAnimMap);
        AssetDatabase.CreateAsset(animMap, Path.Combine(folderPath, data.name + ".asset"));
        return(animMap);
    }
示例#13
0
    private Texture2D SaveAsAsset(ref BakedData data, int i)
    {
        string    folderPath = CreateFolder();
        Texture2D animMap    = new Texture2D(data.animMapWidth, data.animMapHeight, AnimMapBaker.format, false);

        animMap.filterMode = FilterMode.Point;
        animMap.LoadRawTextureData(data.rawAnimMap);
        AssetDatabase.CreateAsset(animMap, Path.Combine(folderPath, data.name + ".asset"));
        return(animMap);
    }
示例#14
0
    private TextAsset SaveAsTextAsset(ref BakedData data)
    {
        var folderPath = CreateFolder();

        Debug.LogError(data.JsonInfo);
        var text = new TextAsset(data.JsonInfo);

        AssetDatabase.CreateAsset(text, Path.Combine(folderPath, data.Name + "Info.asset"));
        return(text);
    }
示例#15
0
    private Texture2D SaveAsAsset(ref BakedData data)
    {
        var folderPath = CreateFolder();
        var animMap    = new Texture2D(data.AnimMapWidth, data.AnimMapHeight, TextureFormat.RGBAHalf, false);

        animMap.wrapMode   = TextureWrapMode.Clamp;
        animMap.filterMode = FilterMode.Point;
        animMap.LoadRawTextureData(data.RawAnimMap);
        AssetDatabase.CreateAsset(animMap, Path.Combine(folderPath, data.Name + ".asset"));
        SaveAsTextAsset(ref data);
        return(animMap);
    }
示例#16
0
 private void Save(ref BakedData data, int i, Mesh mesh)
 {
     if (i == 0)
     {
         SaveAsPrefab(ref data, i, mesh);
     }
     else
     {
         SaveAsAsset(ref data, i);
     }
     AssetDatabase.SaveAssets();
     AssetDatabase.Refresh();
 }
        public static BakedData Bake(this GameObject model, AnimationClip[] animationClips, bool applyRootMotion, int fps, int textureWidth)
        {
            BakedData bakedData = new BakedData()
            {
                mesh         = null,
                positionMaps = new List <Texture2D>(),
                minBounds    = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue),
                maxBounds    = new Vector3(float.MinValue, float.MinValue, float.MinValue)
            };

            // Calculate what our max frames/time is going to be.
            int maxFrames = 0;

            foreach (AnimationClip ac in animationClips)
            {
                int frames = Mathf.FloorToInt(fps * ac.length);

                if (maxFrames < frames)
                {
                    maxFrames = frames;
                }
            }

            // Get the target mesh to calculate the animation info.
            Mesh mesh = model.GetComponent <SkinnedMeshRenderer>().sharedMesh;

            // Get the info for the biggest animation.
            AnimationInfo animationInfo = new AnimationInfo(mesh, applyRootMotion, maxFrames, textureWidth, fps);

            foreach (AnimationClip ac in animationClips)
            {
                // Set the frames for this animation.
                animationInfo.frames = Mathf.FloorToInt(fps * ac.length);

                BakedData bd = Bake(model, ac, animationInfo);
                bakedData.mesh = bd.mesh;
                bakedData.positionMaps.AddRange(bd.positionMaps);
                bakedData.maxFrames = maxFrames;
                bakedData.minBounds = Vector3.Min(bakedData.minBounds, bd.minBounds);
                bakedData.maxBounds = Vector3.Max(bakedData.maxBounds, bd.maxBounds);
            }

            bakedData.mesh.bounds = new Bounds()
            {
                max = bakedData.maxBounds,
                min = bakedData.minBounds
            };

            return(bakedData);
        }
    private void SaveAsPrefab(ref BakedData data)
    {
        Material mat = SaveAsMat(ref data);

        if (mat == null)
        {
            EditorUtility.DisplayDialog("err", "mat is null!!", "OK");
            return;
        }
        GameObject go = new GameObject();

        go.AddComponent <MeshRenderer>().sharedMaterial = mat;
        go.AddComponent <MeshFilter>().sharedMesh       = targetGo.GetComponentInChildren <SkinnedMeshRenderer>().sharedMesh;
        string folderPath = CreateFolder();

        PrefabUtility.CreatePrefab(Path.Combine(folderPath, data.name + ".prefab").Replace("\\", "/"), go);
    }
示例#19
0
    private void Save(ref BakedData data)
    {
        switch (_stratege)
        {
        case SaveStrategy.AnimMap:
            SaveAsAsset(ref data);
            break;

        case SaveStrategy.Mat:
            SaveAsMat(ref data);
            break;
            // case SaveStrategy.Prefab:
            //     SaveAsPrefab(ref data);
            //     break;
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
        public static BakedData Bake(this GameObject model, AnimationClip animationClip, AnimationInfo animationInfo)
        {
            Mesh mesh = new Mesh
            {
                name = string.Format("{0}", model.name)
            };

            // Set root motion options.
            if (model.TryGetComponent(out Animator animator))
            {
                animator.applyRootMotion = animationInfo.applyRootMotion;
            }

            // Bake mesh for a copy and to apply the new UV's to.
            SkinnedMeshRenderer skinnedMeshRenderer = model.GetComponent <SkinnedMeshRenderer>();

            skinnedMeshRenderer.BakeMesh(mesh);
            mesh.RecalculateBounds();

            mesh.uv3 = mesh.BakePositionUVs(animationInfo);

            BakedAnimation bakedAnimation = BakeAnimation(model, animationClip, animationInfo);

            BakedData bakedData = new BakedData()
            {
                mesh         = mesh,
                positionMaps = new List <Texture2D>()
                {
                    bakedAnimation.positionMap
                },
                maxFrames = animationInfo.maxFrames,
                minBounds = bakedAnimation.minBounds,
                maxBounds = bakedAnimation.maxBounds
            };

            mesh.bounds = new Bounds()
            {
                max = bakedAnimation.maxBounds,
                min = bakedAnimation.minBounds
            };

            return(bakedData);
        }
    private static void SaveAsPrefab(ref BakedData data)
    {
        var mat = SaveAsMat(ref data);

        if (mat == null)
        {
            EditorUtility.DisplayDialog("err", "mat is null!!", "OK");
            return;
        }

        var go = new GameObject();

        go.AddComponent <MeshRenderer>().sharedMaterial = mat;
        go.AddComponent <MeshFilter>().sharedMesh       = _targetGo.GetComponentInChildren <SkinnedMeshRenderer>().sharedMesh;

        var folderPath = CreateFolder();

        PrefabUtility.SaveAsPrefabAsset(go, Path.Combine(folderPath, $"{data.Name}.prefab")
                                        .Replace("\\", "/"));
    }
        public static BakedData BakeClips(GameObject animationRoot, AnimationClip[] animationClips, float framerate, LodData lods)
        {
            var skinRenderers = animationRoot.GetComponentsInChildren <SkinnedMeshRenderer>();

            if (skinRenderers.Length != 1)
            {
                throw new System.ArgumentException("There must be exactly one SkinnedMeshRenderer");
            }

            // @TODO: warning about more than one materials

            // Before messing about with some arbitrary game object hierarchy.
            // Instantiate the character, but make sure it's inactive so it doesn't trigger any unexpected systems.
            var wasActive = animationRoot.activeSelf;

            animationRoot.SetActive(false);
            var instance = GameObject.Instantiate(animationRoot, Vector3.zero, Quaternion.identity);

            animationRoot.SetActive(wasActive);

            instance.transform.localScale = Vector3.one;
            var skinRenderer = instance.GetComponentInChildren <SkinnedMeshRenderer>();

            BakedData bakedData = new BakedData();

            bakedData.NewMesh = CreateMesh(skinRenderer);
            var lod1Mesh = CreateMesh(skinRenderer, lods.Lod1Mesh);
            var lod2Mesh = CreateMesh(skinRenderer, lods.Lod2Mesh);
            var lod3Mesh = CreateMesh(skinRenderer, lods.Lod3Mesh);

            bakedData.lods = new LodData(lod1Mesh, lod2Mesh, lod3Mesh, lods.Lod1Distance, lods.Lod2Distance, lods.Lod3Distance);

            bakedData.Framerate = framerate;

            var sampledBoneMatrices = new List <Matrix4x4[, ]>();

            int numberOfKeyFrames = 0;

            for (int i = 0; i < animationClips.Length; i++)
            {
                var sampledMatrix = SampleAnimationClip(instance, animationClips[i], skinRenderer, bakedData.Framerate);
                sampledBoneMatrices.Add(sampledMatrix);

                numberOfKeyFrames += sampledMatrix.GetLength(0);
            }

            int numberOfBones = sampledBoneMatrices[0].GetLength(1);

            var tex0 = bakedData.AnimationTextures.Animation0 = new Texture2D(numberOfKeyFrames, numberOfBones, TextureFormat.RGBAFloat, false);

            tex0.wrapMode   = TextureWrapMode.Clamp;
            tex0.filterMode = FilterMode.Point;
            tex0.anisoLevel = 0;

            var tex1 = bakedData.AnimationTextures.Animation1 = new Texture2D(numberOfKeyFrames, numberOfBones, TextureFormat.RGBAFloat, false);

            tex1.wrapMode   = TextureWrapMode.Clamp;
            tex1.filterMode = FilterMode.Point;
            tex1.anisoLevel = 0;

            var tex2 = bakedData.AnimationTextures.Animation2 = new Texture2D(numberOfKeyFrames, numberOfBones, TextureFormat.RGBAFloat, false);

            tex2.wrapMode   = TextureWrapMode.Clamp;
            tex2.filterMode = FilterMode.Point;
            tex2.anisoLevel = 0;

            Color[] texture0Color = new Color[tex0.width * tex0.height];
            Color[] texture1Color = new Color[tex0.width * tex0.height];
            Color[] texture2Color = new Color[tex0.width * tex0.height];

            int runningTotalNumberOfKeyframes = 0;

            for (int i = 0; i < sampledBoneMatrices.Count; i++)
            {
                for (int boneIndex = 0; boneIndex < sampledBoneMatrices[i].GetLength(1); boneIndex++)
                {
                    //Color previousRotation = new Color();

                    for (int keyframeIndex = 0; keyframeIndex < sampledBoneMatrices[i].GetLength(0); keyframeIndex++)
                    {
                        //var rotation = GetRotation(Quaternion.LookRotation(sampledBoneMatrices[i][keyframeIndex, boneIndex].GetColumn(2),
                        //													sampledBoneMatrices[i][keyframeIndex, boneIndex].GetColumn(1)));

                        //if (keyframeIndex != 0)
                        //{
                        //	if (Distance(previousRotation, rotation) > Distance(Negate(rotation), previousRotation))
                        //	{
                        //		rotation = new Color(-rotation.r, -rotation.g, -rotation.b, -rotation.a);
                        //	}
                        //}

                        //var translation = GetTranslation(sampledBoneMatrices[i][keyframeIndex, boneIndex].GetColumn(3), rotation);

                        //previousRotation = rotation;
                        //int index = Get1DCoord(runningTotalNumberOfKeyframes + keyframeIndex, boneIndex, bakedData.TranslationTexture.width);
                        //translations[index] = translation;
                        //rotations[index] = rotation;

                        int index = Get1DCoord(runningTotalNumberOfKeyframes + keyframeIndex, boneIndex, tex0.width);

                        texture0Color[index] = sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(0);
                        texture1Color[index] = sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(1);
                        texture2Color[index] = sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(2);
                    }
                }

                AnimationClipData clipData = new AnimationClipData
                {
                    Clip       = animationClips[i],
                    PixelStart = runningTotalNumberOfKeyframes + 1,
                    PixelEnd   = runningTotalNumberOfKeyframes + sampledBoneMatrices[i].GetLength(0) - 1
                };

                if (clipData.Clip.wrapMode == WrapMode.Default)
                {
                    clipData.PixelEnd -= 1;
                }

                bakedData.Animations.Add(clipData);

                runningTotalNumberOfKeyframes += sampledBoneMatrices[i].GetLength(0);
            }

            tex0.SetPixels(texture0Color);
            tex1.SetPixels(texture1Color);
            tex2.SetPixels(texture2Color);

            runningTotalNumberOfKeyframes = 0;
            for (int i = 0; i < sampledBoneMatrices.Count; i++)
            {
                for (int boneIndex = 0; boneIndex < sampledBoneMatrices[i].GetLength(1); boneIndex++)
                {
                    for (int keyframeIndex = 0; keyframeIndex < sampledBoneMatrices[i].GetLength(0); keyframeIndex++)
                    {
                        //int d1_index = Get1DCoord(runningTotalNumberOfKeyframes + keyframeIndex, boneIndex, bakedData.Texture0.width);

                        Color pixel0 = tex0.GetPixel(runningTotalNumberOfKeyframes + keyframeIndex, boneIndex);
                        Color pixel1 = tex1.GetPixel(runningTotalNumberOfKeyframes + keyframeIndex, boneIndex);
                        Color pixel2 = tex2.GetPixel(runningTotalNumberOfKeyframes + keyframeIndex, boneIndex);

                        if ((Vector4)pixel0 != sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(0))
                        {
                            Debug.LogError("Error at (" + (runningTotalNumberOfKeyframes + keyframeIndex) + ", " + boneIndex + ") expected " + Format(sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(0)) + " but got " + Format(pixel0));
                        }
                        if ((Vector4)pixel1 != sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(1))
                        {
                            Debug.LogError("Error at (" + (runningTotalNumberOfKeyframes + keyframeIndex) + ", " + boneIndex + ") expected " + Format(sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(1)) + " but got " + Format(pixel1));
                        }
                        if ((Vector4)pixel2 != sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(2))
                        {
                            Debug.LogError("Error at (" + (runningTotalNumberOfKeyframes + keyframeIndex) + ", " + boneIndex + ") expected " + Format(sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(2)) + " but got " + Format(pixel2));
                        }
                    }
                }
                runningTotalNumberOfKeyframes += sampledBoneMatrices[i].GetLength(0);
            }

            tex0.Apply(false, true);
            tex1.Apply(false, true);
            tex2.Apply(false, true);

            bakedData.AnimationsDictionary = new Dictionary <string, AnimationClipData>();
            foreach (var clipData in bakedData.Animations)
            {
                bakedData.AnimationsDictionary[clipData.Clip.name] = clipData;
            }

            GameObject.DestroyImmediate(instance);

            return(bakedData);
        }
示例#23
0
    public static BakedData BakeClips(SkinnedMeshRenderer originalRenderer, AnimationClip[] animationClips, LodData lods)
    {
        BakedData bakedData = new BakedData();

        bakedData.NewMesh = CreateMesh(originalRenderer, lods.Scale);
        var lod1Mesh = CreateMesh(originalRenderer, lods.Scale, lods.Lod1Mesh);
        var lod2Mesh = CreateMesh(originalRenderer, lods.Scale, lods.Lod2Mesh);
        var lod3Mesh = CreateMesh(originalRenderer, lods.Scale, lods.Lod3Mesh);

        bakedData.lods = new LodData(lod1Mesh, lod2Mesh, lod3Mesh, lods.Lod1Distance, lods.Lod2Distance, lods.Lod3Distance);

        bakedData.Framerate = 60f;

        List <Matrix4x4[, ]> sampledBoneMatrices = new List <Matrix4x4[, ]>();

        int numberOfKeyFrames  = 0;
        var animationComponent = originalRenderer.GetComponentInParent <Animation>();

        for (int i = 0; i < animationClips.Length; i++)
        {
            animationComponent[animationClips[i].name].enabled = false;
            animationComponent[animationClips[i].name].weight  = 0f;
        }

        for (int i = 0; i < animationClips.Length; i++)
        {
            Debug.Log("x " + i + " " + animationClips[i].name);
            var sampledMatrix = SampleAnimationClip(animationClips[i], originalRenderer, bakedData.Framerate);
            sampledBoneMatrices.Add(sampledMatrix);

            numberOfKeyFrames += sampledMatrix.GetLength(0);
        }

        int numberOfBones = sampledBoneMatrices[0].GetLength(1);

        bakedData.Texture0            = new Texture2D(numberOfKeyFrames, numberOfBones, TextureFormat.RGBAFloat, false);
        bakedData.Texture0.wrapMode   = TextureWrapMode.Clamp;
        bakedData.Texture0.filterMode = FilterMode.Point;
        bakedData.Texture0.anisoLevel = 0;

        bakedData.Texture1            = new Texture2D(numberOfKeyFrames, numberOfBones, TextureFormat.RGBAFloat, false);
        bakedData.Texture1.wrapMode   = TextureWrapMode.Clamp;
        bakedData.Texture1.filterMode = FilterMode.Point;
        bakedData.Texture1.anisoLevel = 0;

        bakedData.Texture2            = new Texture2D(numberOfKeyFrames, numberOfBones, TextureFormat.RGBAFloat, false);
        bakedData.Texture2.wrapMode   = TextureWrapMode.Clamp;
        bakedData.Texture2.filterMode = FilterMode.Point;
        bakedData.Texture2.anisoLevel = 0;

        Color[] texture0Color = new Color[bakedData.Texture0.width * bakedData.Texture0.height];
        Color[] texture1Color = new Color[bakedData.Texture0.width * bakedData.Texture0.height];
        Color[] texture2Color = new Color[bakedData.Texture0.width * bakedData.Texture0.height];

        int runningTotalNumberOfKeyframes = 0;

        for (int i = 0; i < sampledBoneMatrices.Count; i++)
        {
            for (int boneIndex = 0; boneIndex < sampledBoneMatrices[i].GetLength(1); boneIndex++)
            {
                //Color previousRotation = new Color();

                for (int keyframeIndex = 0; keyframeIndex < sampledBoneMatrices[i].GetLength(0); keyframeIndex++)
                {
                    //var rotation = GetRotation(Quaternion.LookRotation(sampledBoneMatrices[i][keyframeIndex, boneIndex].GetColumn(2),
                    //													sampledBoneMatrices[i][keyframeIndex, boneIndex].GetColumn(1)));

                    //if (keyframeIndex != 0)
                    //{
                    //	if (Distance(previousRotation, rotation) > Distance(Negate(rotation), previousRotation))
                    //	{
                    //		rotation = new Color(-rotation.r, -rotation.g, -rotation.b, -rotation.a);
                    //	}
                    //}

                    //var translation = GetTranslation(sampledBoneMatrices[i][keyframeIndex, boneIndex].GetColumn(3), rotation);

                    //previousRotation = rotation;
                    //int index = Get1DCoord(runningTotalNumberOfKeyframes + keyframeIndex, boneIndex, bakedData.TranslationTexture.width);
                    //translations[index] = translation;
                    //rotations[index] = rotation;

                    int index = Get1DCoord(runningTotalNumberOfKeyframes + keyframeIndex, boneIndex, bakedData.Texture0.width);

                    texture0Color[index] = sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(0);
                    texture1Color[index] = sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(1);
                    texture2Color[index] = sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(2);
                }
            }

            AnimationClipData clipData = new AnimationClipData
            {
                Clip       = animationClips[i],
                PixelStart = runningTotalNumberOfKeyframes + 1,
                PixelEnd   = runningTotalNumberOfKeyframes + sampledBoneMatrices[i].GetLength(0) - 1
            };

            if (clipData.Clip.wrapMode == WrapMode.Default)
            {
                clipData.PixelEnd -= 1;
            }

            bakedData.Animations.Add(clipData);

            runningTotalNumberOfKeyframes += sampledBoneMatrices[i].GetLength(0);
        }

        bakedData.Texture0.SetPixels(texture0Color);
        bakedData.Texture0.Apply(false, false);

        bakedData.Texture1.SetPixels(texture1Color);
        bakedData.Texture1.Apply(false, false);

        bakedData.Texture2.SetPixels(texture2Color);
        bakedData.Texture2.Apply(false, false);


        runningTotalNumberOfKeyframes = 0;
        for (int i = 0; i < sampledBoneMatrices.Count; i++)
        {
            for (int boneIndex = 0; boneIndex < sampledBoneMatrices[i].GetLength(1); boneIndex++)
            {
                for (int keyframeIndex = 0; keyframeIndex < sampledBoneMatrices[i].GetLength(0); keyframeIndex++)
                {
                    //int d1_index = Get1DCoord(runningTotalNumberOfKeyframes + keyframeIndex, boneIndex, bakedData.Texture0.width);

                    Color pixel0 = bakedData.Texture0.GetPixel(runningTotalNumberOfKeyframes + keyframeIndex, boneIndex);
                    Color pixel1 = bakedData.Texture1.GetPixel(runningTotalNumberOfKeyframes + keyframeIndex, boneIndex);
                    Color pixel2 = bakedData.Texture2.GetPixel(runningTotalNumberOfKeyframes + keyframeIndex, boneIndex);

                    if ((Vector4)pixel0 != sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(0))
                    {
                        Debug.LogError("Error at (" + (runningTotalNumberOfKeyframes + keyframeIndex) + ", " + boneIndex + ") expected " + Format(sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(0)) + " but got " + Format(pixel0));
                    }
                    if ((Vector4)pixel1 != sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(1))
                    {
                        Debug.LogError("Error at (" + (runningTotalNumberOfKeyframes + keyframeIndex) + ", " + boneIndex + ") expected " + Format(sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(1)) + " but got " + Format(pixel1));
                    }
                    if ((Vector4)pixel2 != sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(2))
                    {
                        Debug.LogError("Error at (" + (runningTotalNumberOfKeyframes + keyframeIndex) + ", " + boneIndex + ") expected " + Format(sampledBoneMatrices[i][keyframeIndex, boneIndex].GetRow(2)) + " but got " + Format(pixel2));
                    }
                }
            }
            runningTotalNumberOfKeyframes += sampledBoneMatrices[i].GetLength(0);
        }

        bakedData.AnimationsDictionary = new Dictionary <string, AnimationClipData>();
        foreach (var clipData in bakedData.Animations)
        {
            bakedData.AnimationsDictionary[clipData.Clip.name] = clipData;
        }

        return(bakedData);
    }
示例#24
0
 public GPUAnimDrawer(IBakery bakery, IConfig config)
 {
     this.data   = bakery.BakeClips(config.FrameRate);
     this.config = config;
 }
示例#25
0
        /// <summary>
        /// Bake all animation clips to texture in format:
        /// [clip0[frame0[bone0[row0, row1, row0]..boneN[row0, row1, row0]]..frameM[bone0[row0, row1, row0]..boneN[row0, row1, row0]]]..clipK[..
        /// </summary>
        /// <returns>BakedData - baked animation matrix to texture</returns>
        public BakedData BakeClips(float frameRate = 30f)
        {
            OnBeginBakeClips();

            var bakedDataBuilder = BakedData.Bulder(1)
                                   .SetMaterial(CreateMaterial())
                                   .SetMesh(CreateMesh())
                                   .SetFrameRate(frameRate);

            var sampledBoneMatrices = SampleAnimationClips(frameRate,
                                                           out var animationClips,
                                                           out var numberOfKeyFrames,
                                                           out var numberOfBones);

            // find minimum square texture size, size should be power of 2
            var size = BakeryUtils.NextPowerOfTwo(
                (int)Math.Sqrt(numberOfBones * numberOfKeyFrames * MATRIX_ROWS_COUNT));
            var texture = new Texture2D(size, size, TextureFormat.RGBAFloat, false)
            {
                wrapMode   = TextureWrapMode.Clamp,
                filterMode = FilterMode.Point,
                anisoLevel = 0
            };
            var textureColor = new Color[texture.width * texture.height];

            bakedDataBuilder.SetTexture(0, texture);
            bakedDataBuilder.SetBonesCount(numberOfBones);

            var clipOffset = 0;

            for (var clipIndex = 0; clipIndex < sampledBoneMatrices.Count; clipIndex++)
            {
                var framesCount = sampledBoneMatrices[clipIndex].GetLength(0);
                for (var keyframeIndex = 0; keyframeIndex < framesCount; keyframeIndex++)
                {
                    var frameOffset = keyframeIndex * numberOfBones * MATRIX_ROWS_COUNT;
                    for (var boneIndex = 0; boneIndex < numberOfBones; boneIndex++)
                    {
                        var index  = clipOffset + frameOffset + boneIndex * MATRIX_ROWS_COUNT;
                        var matrix = sampledBoneMatrices[clipIndex][keyframeIndex, boneIndex];

                        if ((Vector4)textureColor[index + 0] != Vector4.zero)
                        {
                            Debug.LogError($"Index {index + 0} not empty");
                        }
                        if ((Vector4)textureColor[index + 1] != Vector4.zero)
                        {
                            Debug.LogError($"Index {index + 1} not empty");
                        }
                        if ((Vector4)textureColor[index + 2] != Vector4.zero)
                        {
                            Debug.LogError($"Index {index + 2} not empty");
                        }

                        textureColor[index + 0] = matrix.GetRow(0);
                        textureColor[index + 1] = matrix.GetRow(1);
                        textureColor[index + 2] = matrix.GetRow(2);
                    }
                }

                var clip  = animationClips[clipIndex];
                var start = clipOffset;
                var end   = clipOffset + (framesCount - 1) * MATRIX_ROWS_COUNT;

                var clipData = AnimationClipData.Create(clip,
                                                        start,
                                                        end,
                                                        framesCount);

                bakedDataBuilder.AddClip(clipData);

                clipOffset += framesCount * numberOfBones * MATRIX_ROWS_COUNT;
            }

            texture.SetPixels(textureColor);
            texture.Apply(false, false);

            clipOffset = 0;
            for (var clipIndex = 0; clipIndex < sampledBoneMatrices.Count; clipIndex++)
            {
                var framesCount = sampledBoneMatrices[clipIndex].GetLength(0);
                for (var keyframeIndex = 0; keyframeIndex < framesCount; keyframeIndex++)
                {
                    var frameOffset = keyframeIndex * numberOfBones * MATRIX_ROWS_COUNT;
                    for (var boneIndex = 0; boneIndex < numberOfBones; boneIndex++)
                    {
                        var index  = clipOffset + frameOffset + boneIndex * MATRIX_ROWS_COUNT;
                        var matrix = sampledBoneMatrices[clipIndex][keyframeIndex, boneIndex];

                        var color0   = textureColor[index];
                        var index2D0 = BakeryUtils.To2D(index, texture.width);
                        var pixel0   = texture.GetPixel(index2D0.x, index2D0.y);
                        var row0     = (Color)matrix.GetRow(0);
                        index++;

                        var color1   = textureColor[index];
                        var index2D1 = BakeryUtils.To2D(index, texture.width);
                        var pixel1   = texture.GetPixel(index2D1.x, index2D1.y);
                        var row1     = (Color)matrix.GetRow(1);
                        index++;

                        var color2   = textureColor[index];
                        var index2D2 = BakeryUtils.To2D(index, texture.width);
                        var pixel2   = texture.GetPixel(index2D2.x, index2D2.y);
                        var row2     = (Color)matrix.GetRow(2);

                        if (!Verify(pixel0, row0, color0, index2D0, clipIndex, keyframeIndex, boneIndex))
                        {
                            break;
                        }
                        if (!Verify(pixel1, row1, color1, index2D1, clipIndex, keyframeIndex, boneIndex))
                        {
                            break;
                        }
                        if (!Verify(pixel2, row2, color2, index2D2, clipIndex, keyframeIndex, boneIndex))
                        {
                            break;
                        }
                    }
                }

                clipOffset += numberOfBones * framesCount * MATRIX_ROWS_COUNT;
            }

            var data = bakedDataBuilder.Build();

            OnEndBakeClips();
            return(data);
        }
示例#26
0
 private void Save(ref BakedData data)
 {
     SaveAsAsset(ref data);
     AssetDatabase.SaveAssets();
     AssetDatabase.Refresh();
 }
    void OnGUI()
    {
        if (animMapShader == null)
        {
            animMapShader = Shader.Find("chenjd/AnimMapShader");
        }

        if (obj != null && objIndex < obj.Length)
        {
            targetGo = obj[objIndex] as GameObject;
        }
        targetGo = (GameObject)EditorGUILayout.ObjectField(targetGo, typeof(GameObject), true);
        subPath  = targetGo == null ? subPath : targetGo.name;
        EditorGUILayout.LabelField(string.Format("保存路径output path:{0}", Path.Combine(path, subPath)));
        path    = EditorGUILayout.TextField(path);
        subPath = EditorGUILayout.TextField(subPath);

        stratege = (SaveStrategy)EditorGUILayout.EnumPopup("保存策略output type:", stratege);

        if (baking || GUILayout.Button("Bake"))
        {
            if (!AssetDatabase.IsValidFolder("Assets/" + path))
            {
                AssetDatabase.CreateFolder("Assets", path);
            }

            if (obj != null)
            {
                baking = (objIndex < obj.Length);
                if (!baking)
                {
                    obj      = null;
                    targetGo = null;
                    editorWindow.Close();
                    EditorUtility.DisplayDialog("", "批量处理结束", "OK");
                    return;
                }
            }
            if (targetGo == null)
            {
                editorWindow.Close();
                EditorUtility.DisplayDialog("err", "targetGo is null!", "OK");
                return;
            }

            if (baker == null)
            {
                baker = new AnimMapBaker();
            }

            baker.SetAnimData(targetGo);

            List <BakedData> list = baker.Bake();

            if (list != null)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    BakedData data = list[i];
                    Save(ref data);
                }
            }

            objIndex += 1;
        }
    }
示例#28
0
        /// <summary>
        /// Bake all animation clips to texture in format:
        /// [clip0[frame0[bone0[row0, row1, row0]..boneN[row0, row1, row0]]..frameM[bone0[row0, row1, row0]..boneN[row0, row1, row0]]]..clipK[..
        /// </summary>
        /// <returns>BakedData - baked animation matrix to texture</returns>
        public static BakedData BakeClips(GameObject prototype, float frameRate = 30f)
        {
            var go = Object.Instantiate(prototype);

            go.transform.localPosition = Vector3.zero;
            go.transform.localRotation = Quaternion.identity;
            go.SetActive(true);

            var skinnedMeshRenderer = go.GetComponentInChildren <SkinnedMeshRenderer>();

            var sampledBoneMatrices = SampleAnimationClips(go,
                                                           skinnedMeshRenderer,
                                                           frameRate,
                                                           out var animationClips,
                                                           out var numberOfKeyFrames,
                                                           out var numberOfBones);
            var buffer = new Vector4[numberOfBones * numberOfKeyFrames * MATRIX_ROWS_COUNT];

            var bakedDataBuilder = BakedData.Create()
                                   .SetFrameRate(frameRate)
                                   .SetBonesCount(numberOfBones);

            var clipOffset = 0;

            for (var clipIndex = 0; clipIndex < sampledBoneMatrices.Count; clipIndex++)
            {
                var framesCount = sampledBoneMatrices[clipIndex].GetLength(0);
                for (var keyframeIndex = 0; keyframeIndex < framesCount; keyframeIndex++)
                {
                    var frameOffset = keyframeIndex * numberOfBones * MATRIX_ROWS_COUNT;
                    for (var boneIndex = 0; boneIndex < numberOfBones; boneIndex++)
                    {
                        var index  = clipOffset + frameOffset + boneIndex * MATRIX_ROWS_COUNT;
                        var matrix = sampledBoneMatrices[clipIndex][keyframeIndex, boneIndex];

                        if (buffer[index + 0] != Vector4.zero)
                        {
                            Debug.LogError($"Index {index + 0} not empty");
                        }
                        if (buffer[index + 1] != Vector4.zero)
                        {
                            Debug.LogError($"Index {index + 1} not empty");
                        }
                        if (buffer[index + 2] != Vector4.zero)
                        {
                            Debug.LogError($"Index {index + 2} not empty");
                        }

                        buffer[index + 0] = matrix.GetRow(0);
                        buffer[index + 1] = matrix.GetRow(1);
                        buffer[index + 2] = matrix.GetRow(2);
                    }
                }

                var clip  = animationClips[clipIndex];
                var start = clipOffset;

                var clipData = ClipData.Create(clip.name,
                                               clip.length,
                                               clip.wrapMode,
                                               start,
                                               framesCount);

                bakedDataBuilder.AddClip(clipData);

                clipOffset += framesCount * numberOfBones * MATRIX_ROWS_COUNT;
            }
            bakedDataBuilder.SetBuffer(buffer);

            clipOffset = 0;
            for (var clipIndex = 0; clipIndex < sampledBoneMatrices.Count; clipIndex++)
            {
                var framesCount = sampledBoneMatrices[clipIndex].GetLength(0);
                for (var keyframeIndex = 0; keyframeIndex < framesCount; keyframeIndex++)
                {
                    var frameOffset = keyframeIndex * numberOfBones * MATRIX_ROWS_COUNT;
                    for (var boneIndex = 0; boneIndex < numberOfBones; boneIndex++)
                    {
                        var index  = clipOffset + frameOffset + boneIndex * MATRIX_ROWS_COUNT;
                        var matrix = sampledBoneMatrices[clipIndex][keyframeIndex, boneIndex];

                        var data0 = buffer[index];
                        var row0  = (Color)matrix.GetRow(0);
                        index++;

                        var data1 = buffer[index];
                        var row1  = (Color)matrix.GetRow(1);
                        index++;

                        var data2 = buffer[index];
                        var row2  = (Color)matrix.GetRow(2);

                        if (!Verify(row0, data0, clipIndex, keyframeIndex, boneIndex))
                        {
                            break;
                        }
                        if (!Verify(row1, data1, clipIndex, keyframeIndex, boneIndex))
                        {
                            break;
                        }
                        if (!Verify(row2, data2, clipIndex, keyframeIndex, boneIndex))
                        {
                            break;
                        }
                    }
                }

                clipOffset += numberOfBones * framesCount * MATRIX_ROWS_COUNT;
            }

            var data = bakedDataBuilder.Build();

            go.SetActive(false);
            Object.Destroy(go);
            return(data);
        }