public void Destroy()
    {
        anim = null;
        mesh = null;

        if (cullingBounds != null)
        {
            cullingBounds.Release();
            cullingBounds = null;
        }

        DestroyCullingGroup();

        if (mtrls != null)
        {
            for (int i = 0; i < mtrls.Length; ++i)
            {
                mtrls[i].Destroy();
                mtrls[i] = null;
            }
            mtrls = null;
        }

        if (texture != null)
        {
            //Object.DestroyImmediate(texture);
            texture = null;
        }

        if (players != null)
        {
            players.Clear();
            players = null;
        }
    }
Esempio n. 2
0
    private void CreateTextureMatrix(string dir, GPUSkinningAnimation gpuSkinningAnim)
    {
        Texture2D texture = new Texture2D(gpuSkinningAnim.textureWidth, gpuSkinningAnim.textureHeight, TextureFormat.RGBAHalf, false, true);

        Color[] pixels     = texture.GetPixels();
        int     pixelIndex = 0;

        for (int clipIndex = 0; clipIndex < gpuSkinningAnim.clips.Length; ++clipIndex)
        {
            GPUSkinningClip    clip   = gpuSkinningAnim.clips[clipIndex];
            GPUSkinningFrame[] frames = clip.frames;
            int numFrames             = frames.Length;
            for (int frameIndex = 0; frameIndex < numFrames; ++frameIndex)
            {
                GPUSkinningFrame frame    = frames[frameIndex];
                Matrix4x4[]      matrices = frame.matrices;
                int numMatrices           = matrices.Length;
                for (int matrixIndex = 0; matrixIndex < numMatrices; ++matrixIndex)
                {
                    Matrix4x4 matrix = matrices[matrixIndex];
                    pixels[pixelIndex++] = new Color(matrix.m00, matrix.m01, matrix.m02, matrix.m03);
                    pixels[pixelIndex++] = new Color(matrix.m10, matrix.m11, matrix.m12, matrix.m13);
                    pixels[pixelIndex++] = new Color(matrix.m20, matrix.m21, matrix.m22, matrix.m23);
                }
            }
        }
        texture.SetPixels(pixels);
        texture.Apply();

        string savedPath = dir + "/GPUSKinning_Texture_" + animName + ".bytes";

        File.WriteAllBytes(savedPath, texture.GetRawTextureData());
        WriteTempData(TEMP_SAVED_TEXTURE_PATH, savedPath);
    }
Esempio n. 3
0
    public static string BoneHierarchyPath(GPUSkinningAnimation gpuSkinningAnimation, int boneIndex)
    {
        if (gpuSkinningAnimation == null)
        {
            return(null);
        }

        return(BoneHierarchyPath(gpuSkinningAnimation.bones, boneIndex));
    }
Esempio n. 4
0
    public void Register(GPUSkinningAnimation anim, Mesh mesh, Material originalMtrl, TextAsset textureRawData, GPUSkinningPlayerMono player, out GPUSkinningPlayerResources resources)
    {
        resources = null;

        if (anim == null || originalMtrl == null || textureRawData == null || player == null)
        {
            return;
        }

        GPUSkinningPlayerResources item = null;

        int numItems = items.Count;

        for (int i = 0; i < numItems; ++i)
        {
            if (items[i].anim.guid == anim.guid)
            {
                item = items[i];
                break;
            }
        }

        if (item == null)
        {
            item = new GPUSkinningPlayerResources();
            items.Add(item);
        }

        if (item.anim == null)
        {
            item.anim = anim;
        }

        if (item.mesh == null)
        {
            item.mesh = mesh;
        }

        if (item.mtrl == null)
        {
            item.mtrl = new Material(originalMtrl);
        }

        if (item.texture == null)
        {
            item.texture = GPUSkinningUtil.CreateTexture2D(textureRawData, anim);
        }

        if (!item.players.Contains(player))
        {
            item.players.Add(player);
        }

        resources = item;
    }
Esempio n. 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);
        }
    }
Esempio n. 6
0
    public static string BonesHierarchyTree(GPUSkinningAnimation gpuSkinningAnimation)
    {
        if (gpuSkinningAnimation == null || gpuSkinningAnimation.bones == null)
        {
            return(null);
        }

        string str = string.Empty;

        BonesHierarchy_Internal(gpuSkinningAnimation, gpuSkinningAnimation.bones[gpuSkinningAnimation.rootBoneIndex], string.Empty, ref str);
        return(str);
    }
Esempio n. 7
0
    public void Init(GPUSkinningAnimation anim, Mesh mesh, Material mtrl, TextAsset textureRawData)
    {
        if (player != null)
        {
            return;
        }

        this.anim           = anim;
        this.mesh           = mesh;
        this.mtrl           = mtrl;
        this.textureRawData = textureRawData;
        Init();
    }
    public void Init(GPUSkinningAnimation anim, Mesh mesh, Material mtrl, Texture2D boneTexture)
    {
        if (player != null)
        {
            return;
        }

        this.anim        = anim;
        this.mesh        = mesh;
        this.mtrl        = mtrl;
        this.boneTexture = boneTexture;
        Init();
    }
Esempio n. 9
0
    public static Texture2D CreateTexture2D(TextAsset textureRawData, GPUSkinningAnimation anim)
    {
        if (textureRawData == null || anim == null)
        {
            return(null);
        }

        Texture2D texture = new Texture2D(anim.textureWidth, anim.textureHeight, TextureFormat.RGBAHalf, false, true);

        texture.name       = "GPUSkinningTextureMatrix";
        texture.filterMode = FilterMode.Point;
        texture.LoadRawTextureData(textureRawData.bytes);
        texture.Apply(false, true);

        return(texture);
    }
Esempio n. 10
0
    private void CreateTextureMatrix(string dir, GPUSkinningAnimation gpuSkinningAnim)
    {
        Texture2D texture = new Texture2D(gpuSkinningAnim.textureWidth, gpuSkinningAnim.textureHeight, TextureFormat.RGBAHalf, false, true);

        texture.filterMode = FilterMode.Point;
        texture.wrapMode   = TextureWrapMode.Clamp;
        texture.anisoLevel = 0;
        Color[] pixels     = texture.GetPixels();
        int     pixelIndex = 0;

        for (int clipIndex = 0; clipIndex < gpuSkinningAnim.clips.Length; ++clipIndex)
        {
            GPUSkinningClip    clip   = gpuSkinningAnim.clips[clipIndex];
            GPUSkinningFrame[] frames = clip.frames;
            int numFrames             = frames.Length;
            for (int frameIndex = 0; frameIndex < numFrames; ++frameIndex)
            {
                GPUSkinningFrame frame    = frames[frameIndex];
                Matrix4x4[]      matrices = frame.matrices;
                int numMatrices           = matrices.Length;
                for (int matrixIndex = 0; matrixIndex < numMatrices; ++matrixIndex)
                {
                    Matrix4x4 matrix = matrices[matrixIndex];
                    pixels[pixelIndex++] = new Color(matrix.m00, matrix.m01, matrix.m02, matrix.m03);
                    pixels[pixelIndex++] = new Color(matrix.m10, matrix.m11, matrix.m12, matrix.m13);
                    pixels[pixelIndex++] = new Color(matrix.m20, matrix.m21, matrix.m22, matrix.m23);
                }
            }
        }
        texture.SetPixels(pixels);
        texture.Apply();

        string savedPath = dir + "/GPUSKinning_Texture_" + animName + ".asset";

        AssetDatabase.CreateAsset(texture, savedPath);
        WriteTempData(TEMP_SAVED_TEXTURE_PATH, savedPath);
        //string savedPath = dir + "/GPUSKinning_Texture_" + animName + ".bytes";
        //using (FileStream fileStream = new FileStream(savedPath, FileMode.Create))
        //{
        //    byte[] bytes = texture.GetRawTextureData();
        //    fileStream.Write(bytes, 0, bytes.Length);
        //    fileStream.Flush();
        //    fileStream.Close();
        //    fileStream.Dispose();
        //}
        //WriteTempData(TEMP_SAVED_TEXTURE_PATH, savedPath);
    }
Esempio n. 11
0
    private void OnDestroy()
    {
        player         = null;
        anim           = null;
        mesh           = null;
        mtrl           = null;
        textureRawData = null;
        m_PlayerMonoManager.Unregister(this);

#if UNITY_EDITOR
        if (!Application.isPlaying)
        {
            Resources.UnloadUnusedAssets();
            UnityEditor.EditorUtility.UnloadUnusedAssetsImmediate();
        }
#endif
    }
    private void SetSthAboutTexture(GPUSkinningAnimation gpuSkinningAnim)
    {
        int numPixels = 0;

        GPUSkinningClip[] clips = gpuSkinningAnim.clips;
        int numClips            = clips.Length;

        for (int clipIndex = 0; clipIndex < numClips; ++clipIndex)
        {
            GPUSkinningClip clip = clips[clipIndex];
            clip.pixelSegmentation = numPixels;

            GPUSkinningFrame[] frames = clip.frames;
            int numFrames             = frames.Length;
            numPixels += gpuSkinningAnim.bones.Length * 3 /*treat 3 pixels as a float3x4*/ * numFrames;
        }

        CalculateTextureSize(numPixels, out gpuSkinningAnim.textureWidth, out gpuSkinningAnim.textureHeight);
    }
Esempio n. 13
0
    public override void OnInspectorGUI()
    {
        GPUSkinningController controller = target as GPUSkinningController;

        if (controller == null)
        {
            return;
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("anim"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
        }
        GPUSkinningAnimation anim = serializedObject.FindProperty("anim").objectReferenceValue as GPUSkinningAnimation;

        serializedObject.ApplyModifiedProperties();
    }
Esempio n. 14
0
    public void Destroy()
    {
        anim = null;
        mesh = null;

        if (mtrl != null)
        {
            Object.Destroy(mtrl);
            mtrl = null;
        }

        if (texture != null)
        {
            Object.DestroyImmediate(texture);
            texture = null;
        }

        if (players != null)
        {
            players.Clear();
            players = null;
        }
    }
    public void StartSample()
    {
        if (isSampling)
        {
            return;
        }

        if (string.IsNullOrEmpty(animName.Trim()))
        {
            ShowDialog("Animation name is empty.");
            return;
        }

        if (rootBoneTransform == null)
        {
            ShowDialog("Please set Root Bone.");
            return;
        }

        if (animClips == null || animClips.Length == 0)
        {
            ShowDialog("Please set Anim Clips.");
            return;
        }

        animClip = animClips[samplingClipIndex];
        if (animClip == null)
        {
            isSampling = false;
            return;
        }

        int numFrames = (int)(GetClipFPS(animClip, samplingClipIndex) * animClip.length);

        if (numFrames == 0)
        {
            isSampling = false;
            return;
        }

        smr = GetComponentInChildren <SkinnedMeshRenderer>();
        if (smr == null)
        {
            ShowDialog("Cannot find SkinnedMeshRenderer.");
            return;
        }
        if (smr.sharedMesh == null)
        {
            ShowDialog("Cannot find SkinnedMeshRenderer.mesh.");
            return;
        }

        Mesh mesh = smr.sharedMesh;

        if (mesh == null)
        {
            ShowDialog("Missing Mesh");
            return;
        }

        samplingFrameIndex = 0;

        gpuSkinningAnimation = anim == null?ScriptableObject.CreateInstance <GPUSkinningAnimation>() : anim;

        gpuSkinningAnimation.name = animName;

        if (anim == null)
        {
            gpuSkinningAnimation.guid = System.Guid.NewGuid().ToString();
        }

        List <GPUSkinningBone> bones_result = new List <GPUSkinningBone>();

        CollectBones(bones_result, smr.bones, mesh.bindposes, null, rootBoneTransform, 0);
        GPUSkinningBone[] newBones = bones_result.ToArray();
        GenerateBonesGUID(newBones);
        if (anim != null)
        {
            RestoreCustomBoneData(anim.bones, newBones);
        }
        gpuSkinningAnimation.bones         = newBones;
        gpuSkinningAnimation.rootBoneIndex = 0;

        int numClips          = gpuSkinningAnimation.clips == null ? 0 : gpuSkinningAnimation.clips.Length;
        int overrideClipIndex = -1;

        for (int i = 0; i < numClips; ++i)
        {
            if (gpuSkinningAnimation.clips[i].name == animClip.name)
            {
                overrideClipIndex = i;
                break;
            }
        }

        gpuSkinningClip                             = new GPUSkinningClip();
        gpuSkinningClip.name                        = animClip.name;
        gpuSkinningClip.fps                         = GetClipFPS(animClip, samplingClipIndex);
        gpuSkinningClip.length                      = animClip.length;
        gpuSkinningClip.wrapMode                    = wrapModes[samplingClipIndex];
        gpuSkinningClip.frames                      = new GPUSkinningFrame[numFrames];
        gpuSkinningClip.rootMotionEnabled           = rootMotionEnabled[samplingClipIndex];
        gpuSkinningClip.individualDifferenceEnabled = individualDifferenceEnabled[samplingClipIndex];

        if (gpuSkinningAnimation.clips == null)
        {
            gpuSkinningAnimation.clips = new GPUSkinningClip[] { gpuSkinningClip };
        }
        else
        {
            if (overrideClipIndex == -1)
            {
                List <GPUSkinningClip> clips = new List <GPUSkinningClip>(gpuSkinningAnimation.clips);
                clips.Add(gpuSkinningClip);
                gpuSkinningAnimation.clips = clips.ToArray();
            }
            else
            {
                GPUSkinningClip overridedClip = gpuSkinningAnimation.clips[overrideClipIndex];
                RestoreCustomClipData(overridedClip, gpuSkinningClip);
                gpuSkinningAnimation.clips[overrideClipIndex] = gpuSkinningClip;
            }
        }

        SetCurrentAnimationClip();
        PrepareRecordAnimator();

        isSampling = true;
    }
Esempio n. 16
0
    public override void OnInspectorGUI()
    {
        GPUSkinningPlayerMono player = target as GPUSkinningPlayerMono;

        if (player == null)
        {
            return;
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("anim"));
        if (EditorGUI.EndChangeCheck())
        {
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("mesh"));
        if (EditorGUI.EndChangeCheck())
        {
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("mtrl"));
        if (EditorGUI.EndChangeCheck())
        {
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("textureRawData"));
        if (EditorGUI.EndChangeCheck())
        {
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("rootMotionEnabled"), new GUIContent("Apply Root Motion"));
        if (EditorGUI.EndChangeCheck())
        {
            if (Application.isPlaying)
            {
                player.Player.RootMotionEnabled = serializedObject.FindProperty("rootMotionEnabled").boolValue;
            }
        }

        GPUSkinningAnimation anim = serializedObject.FindProperty("anim").objectReferenceValue as GPUSkinningAnimation;
        SerializedProperty   defaultPlayingClipIndex = serializedObject.FindProperty("defaultPlayingClipIndex");

        if (clipsName == null && anim != null)
        {
            List <string> list = new List <string>();
            for (int i = 0; i < anim.clips.Length; ++i)
            {
                list.Add(anim.clips[i].name);
            }
            clipsName = list.ToArray();

            defaultPlayingClipIndex.intValue = Mathf.Clamp(defaultPlayingClipIndex.intValue, 0, anim.clips.Length);
        }
        if (clipsName != null)
        {
            EditorGUI.BeginChangeCheck();
            defaultPlayingClipIndex.intValue = EditorGUILayout.Popup("Default Playing", defaultPlayingClipIndex.intValue, clipsName);
            if (EditorGUI.EndChangeCheck())
            {
                player.Player.Play(clipsName[defaultPlayingClipIndex.intValue]);
            }
        }

        serializedObject.ApplyModifiedProperties();
    }
Esempio n. 17
0
    private void OnGUI_Preview(GPUSkinningSampler sampler)
    {
        BeginBox();
        {
            if (GUILayout.Button("Preview/Edit"))
            {
                anim    = sampler.anim;
                mesh    = sampler.savedMesh;
                mtrl    = sampler.savedMtrl;
                texture = sampler.texture;
                if (mesh != null)
                {
                    bounds = mesh.bounds;
                }
                if (anim == null || mesh == null || mtrl == null || texture == null)
                {
                    EditorUtility.DisplayDialog("GPUSkinning", "Missing Sampling Resources", "OK");
                }
                else
                {
                    if (rt == null)
                    {
                        linearToGammeMtrl           = new Material(Shader.Find("GPUSkinning/GPUSkinningSamplerEditor_LinearToGamma"));
                        linearToGammeMtrl.hideFlags = HideFlags.HideAndDontSave;

                        rt           = new RenderTexture(1024, 1024, 32, RenderTextureFormat.Default, RenderTextureReadWrite.Default);
                        rt.hideFlags = HideFlags.HideAndDontSave;

                        if (PlayerSettings.colorSpace == ColorSpace.Linear)
                        {
                            rtGamma           = new RenderTexture(512, 512, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Linear);
                            rtGamma.hideFlags = HideFlags.HideAndDontSave;
                        }

                        GameObject camGo = new GameObject("GPUSkinningSamplerEditor_CameraGo");
                        camGo.hideFlags          = HideFlags.HideAndDontSave;
                        cam                      = camGo.AddComponent <Camera>();
                        cam.hideFlags            = HideFlags.HideAndDontSave;
                        cam.farClipPlane         = 100;
                        cam.targetTexture        = rt;
                        cam.enabled              = false;
                        cam.clearFlags           = CameraClearFlags.SolidColor;
                        cam.backgroundColor      = new Color(0.2f, 0.2f, 0.2f, 1);
                        camGo.transform.position = new Vector3(999, 1002, 999);

                        previewClipIndex = 0;

                        GameObject previewGo = new GameObject("GPUSkinningPreview_Go");
                        previewGo.hideFlags          = HideFlags.HideAndDontSave;
                        previewGo.transform.position = new Vector3(999, 999, 1002);
                        preview           = previewGo.AddComponent <GPUSkinningPlayerMono>();
                        preview.hideFlags = HideFlags.HideAndDontSave;
                        preview.Init(anim, mesh, mtrl, texture);
                        preview.Player.RootMotionEnabled = rootMotionEnabled;
                    }
                }
            }
            GetLastGUIRect(ref previewEditBtnRect);

            if (rt != null)
            {
                int previewRectSize = Mathf.Min((int)(previewEditBtnRect.width * 0.9f), 512);
                EditorGUILayout.BeginHorizontal();
                {
                    GUILayout.FlexibleSpace();
                    EditorGUILayout.BeginVertical();
                    {
                        if (PlayerSettings.colorSpace == ColorSpace.Linear)
                        {
                            RenderTexture tempRT = RenderTexture.active;
                            Graphics.Blit(rt, rtGamma, linearToGammeMtrl);
                            RenderTexture.active = tempRT;
                            GUILayout.Box(rtGamma, GUILayout.Width(previewRectSize), GUILayout.Height(previewRectSize));
                        }
                        else
                        {
                            GUILayout.Box(rt, GUILayout.Width(previewRectSize), GUILayout.Height(previewRectSize));
                        }
                        GetLastGUIRect(ref interactionRect);
                        PreviewInteraction(interactionRect);

                        EditorGUILayout.HelpBox("Drag to Orbit\nCtrl + Drag to Pitch\nAlt+ Drag to Zoom\nPress P Key to Pause", MessageType.None);
                    }
                    EditorGUILayout.EndVertical();

                    EditorGUI.ProgressBar(new Rect(interactionRect.x, interactionRect.y + interactionRect.height, interactionRect.width, 5), preview.Player.NormalizedTime, string.Empty);

                    GUILayout.FlexibleSpace();
                }
                EditorGUILayout.EndHorizontal();

                OnGUI_PreviewClipsOptions();

                OnGUI_RootMotion();

                EditorGUILayout.Space();

                OnGUI_EditBounds();

                EditorGUILayout.Space();

                OnGUI_Joints();
            }
        }
        EndBox();

        serializedObject.ApplyModifiedProperties();
    }
    private void Update()
    {
        if (!isSampling)
        {
            return;
        }

        int totalFrams = (int)(gpuSkinningClip.length * gpuSkinningClip.fps);

        samplingTotalFrams = totalFrams;

        if (samplingFrameIndex >= totalFrams)
        {
            if (animator != null)
            {
                animator.StopPlayback();
            }

            string savePath = null;
            if (anim == null)
            {
                savePath = EditorUtility.SaveFolderPanel("GPUSkinning Sampler Save", GetUserPreferDir(), animName);
            }
            else
            {
                string animPath = AssetDatabase.GetAssetPath(anim);
                savePath = new FileInfo(animPath).Directory.FullName.Replace('\\', '/');
            }

            if (!string.IsNullOrEmpty(savePath))
            {
                if (!savePath.Contains(Application.dataPath.Replace('\\', '/')))
                {
                    ShowDialog("Must select a directory in the project's Asset folder.");
                }
                else
                {
                    SaveUserPreferDir(savePath);

                    string dir = "Assets" + savePath.Substring(Application.dataPath.Length);

                    string savedAnimPath = dir + "/GPUSKinning_Anim_" + animName + ".asset";
                    SetSthAboutTexture(gpuSkinningAnimation);
                    EditorUtility.SetDirty(gpuSkinningAnimation);
                    if (anim != gpuSkinningAnimation)
                    {
                        AssetDatabase.CreateAsset(gpuSkinningAnimation, savedAnimPath);
                    }
                    WriteTempData(TEMP_SAVED_ANIM_PATH, savedAnimPath);
                    anim = gpuSkinningAnimation;

                    CreateTextureMatrix(dir, anim);

                    if (samplingClipIndex == 0)
                    {
                        Mesh newMesh = CreateNewMesh(smr.sharedMesh, "GPUSkinning_Mesh");
                        if (savedMesh != null)
                        {
                            newMesh.bounds = savedMesh.bounds;
                        }
                        string savedMeshPath = dir + "/GPUSKinning_Mesh_" + animName + ".asset";
                        AssetDatabase.CreateAsset(newMesh, savedMeshPath);
                        WriteTempData(TEMP_SAVED_MESH_PATH, savedMeshPath);
                        savedMesh = newMesh;

                        CreateShaderAndMaterial(dir);

                        CreateLODMeshes(newMesh.bounds, dir);
                    }

                    AssetDatabase.Refresh();
                    AssetDatabase.SaveAssets();
                }
            }
            isSampling = false;
            return;
        }

        float            time  = gpuSkinningClip.length * ((float)samplingFrameIndex / totalFrams);
        GPUSkinningFrame frame = new GPUSkinningFrame();

        gpuSkinningClip.frames[samplingFrameIndex] = frame;
        frame.matrices = new Matrix4x4[gpuSkinningAnimation.bones.Length];
        if (animation == null)
        {
            animator.playbackTime = time;
            animator.Update(0);
        }
        else
        {
            animation.Stop();
            AnimationState animState = animation[animClip.name];
            if (animState != null)
            {
                animState.time = time;
                animation.Sample();
                animation.Play();
            }
        }
        StartCoroutine(SamplingCoroutine(frame, totalFrams));
    }
Esempio n. 19
0
    public override void OnInspectorGUI()
    {
        GPUSkinningPlayerMono player = target as GPUSkinningPlayerMono;
        if (player == null)
        {
            return;
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("anim"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
            player.DeletePlayer();
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("mesh"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
            player.DeletePlayer();
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("mtrl"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
            player.DeletePlayer();
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("textureRawData"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
            player.DeletePlayer();
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("rootMotionEnabled"), new GUIContent("Apply Root Motion"));
        if(EditorGUI.EndChangeCheck())
        {
            if(Application.isPlaying)
            {
                player.Player.RootMotionEnabled = serializedObject.FindProperty("rootMotionEnabled").boolValue;
            }
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("lodEnabled"), new GUIContent("LOD Enabled"));
        if (EditorGUI.EndChangeCheck())
        {
            if (Application.isPlaying)
            {
                player.Player.LODEnabled = serializedObject.FindProperty("lodEnabled").boolValue;
            }
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("cullingMode"), new GUIContent("Culling Mode"));
        if (EditorGUI.EndChangeCheck())
        {
            if (Application.isPlaying)
            {
                player.Player.CullingMode = 
                    serializedObject.FindProperty("cullingMode").enumValueIndex == 0 ? GPUSKinningCullingMode.AlwaysAnimate :
                    serializedObject.FindProperty("cullingMode").enumValueIndex == 1 ? GPUSKinningCullingMode.CullUpdateTransforms : GPUSKinningCullingMode.CullCompletely;
            }
        }

        GPUSkinningAnimation anim = serializedObject.FindProperty("anim").objectReferenceValue as GPUSkinningAnimation;
        SerializedProperty defaultPlayingClipIndex = serializedObject.FindProperty("defaultPlayingClipIndex");
        if (clipsName == null && anim != null)
        {
            List<string> list = new List<string>();
            for(int i = 0; i < anim.clips.Length; ++i)
            {
                list.Add(anim.clips[i].name);
            }
            clipsName = list.ToArray();

            defaultPlayingClipIndex.intValue = Mathf.Clamp(defaultPlayingClipIndex.intValue, 0, anim.clips.Length);
        }
        if (clipsName != null)
        {
            EditorGUI.BeginChangeCheck();
            defaultPlayingClipIndex.intValue = EditorGUILayout.Popup("Default Playing", defaultPlayingClipIndex.intValue, clipsName);
            if (EditorGUI.EndChangeCheck())
            {
                player.Player.Play(clipsName[defaultPlayingClipIndex.intValue]);
            }
        }

        serializedObject.ApplyModifiedProperties();

		if(GUILayout.Button("提交"))
		{
			//if(source == null) return;
			//
			MeshRenderer r = player.GetComponent<MeshRenderer> ();
			if (!player.mat.shader.isSupported) {
				player.mat.shader = r.sharedMaterial.shader;
			}
			player.mat.CopyPropertiesFromMaterial (r.sharedMaterial);
			 
			GameObject prefabGo = GetPrefabInstanceParent(player.gameObject);
			UnityEngine.Object prefabAsset = null;
			if(prefabGo != null){
			 	prefabAsset = PrefabUtility.GetPrefabParent(prefabGo);
			 	if(prefabAsset != null){
			    	PrefabUtility.ReplacePrefab(prefabGo, prefabAsset, ReplacePrefabOptions.ConnectToPrefab);
					string path = AssetDatabase.GetAssetPath (player.mat);
					Debug.Log (path);
					//System.IO.File.Delete (path);
					//AssetDatabase.CreateAsset(player.mat,path);
					EditorUtility.SetDirty(prefabGo);
					EditorUtility.SetDirty(player.mat);
					AssetDatabase.SaveAssets();
					EditorUtility.DisplayDialog ("", "替换", "确定");
			 	}
			}
			AssetDatabase.SaveAssets();
		}
    }
    public override void OnInspectorGUI()
    {
        if (SceneManager.GetActiveScene().name != "Adam_Sampler")
        {
            return;
        }

        GPUSkinningPlayerMono player = target as GPUSkinningPlayerMono;

        if (player == null)
        {
            return;
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("anim"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
            player.DeletePlayer();
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("mesh"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
            player.DeletePlayer();
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("mtrl"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
            player.DeletePlayer();
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("textureRawData"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
            player.DeletePlayer();
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("rootMotionEnabled"), new GUIContent("Apply Root Motion"));
        if (EditorGUI.EndChangeCheck())
        {
            if (Application.isPlaying)
            {
                player.Player.RootMotionEnabled = serializedObject.FindProperty("rootMotionEnabled").boolValue;
            }
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("lodEnabled"), new GUIContent("LOD Enabled"));
        if (EditorGUI.EndChangeCheck())
        {
            if (Application.isPlaying)
            {
                player.Player.LODEnabled = serializedObject.FindProperty("lodEnabled").boolValue;
            }
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("cullingMode"), new GUIContent("Culling Mode"));
        if (EditorGUI.EndChangeCheck())
        {
            if (Application.isPlaying)
            {
                player.Player.CullingMode =
                    serializedObject.FindProperty("cullingMode").enumValueIndex == 0 ? GPUSKinningCullingMode.AlwaysAnimate :
                    serializedObject.FindProperty("cullingMode").enumValueIndex == 1 ? GPUSKinningCullingMode.CullUpdateTransforms : GPUSKinningCullingMode.CullCompletely;
            }
        }

        GPUSkinningAnimation anim = serializedObject.FindProperty("anim").objectReferenceValue as GPUSkinningAnimation;
        SerializedProperty   defaultPlayingClipIndex = serializedObject.FindProperty("defaultPlayingClipIndex");

        if (clipsName == null && anim != null)
        {
            List <string> list = new List <string>();
            for (int i = 0; i < anim.clips.Length; ++i)
            {
                list.Add(anim.clips[i].name);
            }
            clipsName = list.ToArray();

            defaultPlayingClipIndex.intValue = Mathf.Clamp(defaultPlayingClipIndex.intValue, 0, anim.clips.Length);
        }
        if (clipsName != null)
        {
            EditorGUI.BeginChangeCheck();
            defaultPlayingClipIndex.intValue = EditorGUILayout.Popup("Default Playing", defaultPlayingClipIndex.intValue, clipsName);
            if (EditorGUI.EndChangeCheck())
            {
                player.Player.Play(clipsName[defaultPlayingClipIndex.intValue]);
            }
        }

        serializedObject.ApplyModifiedProperties();
    }
    public override void OnInspectorGUI()
    {
        GPUSkinningPlayerMono player = target as GPUSkinningPlayerMono;

        if (player == null)
        {
            return;
        }

        #region 属性设置后更新
        //设置属性后,调用Init函数初始化
        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("anim"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
            player.DeletePlayer();
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("mtrl"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
            player.DeletePlayer();
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("mesh"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
            player.DeletePlayer();
            player.Init();
        }

        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("textureRawData"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
            player.DeletePlayer();
            player.Init();
        }
        #endregion

        //运行时修改RootMotion属性
        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("rootMotionEnabled"), new GUIContent("Apply Root Motion"));
        if (EditorGUI.EndChangeCheck())
        {
            if (Application.isPlaying)
            {
                player.Player.RootMotionEnabled = serializedObject.FindProperty("rootMotionEnabled").boolValue;
            }
        }

        //运行时修改LOD属性
        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("lodEnabled"), new GUIContent("LOD Enabled"));
        if (EditorGUI.EndChangeCheck())
        {
            if (Application.isPlaying)
            {
                player.Player.LODEnabled = serializedObject.FindProperty("lodEnabled").boolValue;
            }
        }

        //运行时修改Animator的CullingMode属性
        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("cullingMode"), new GUIContent("Culling Mode"));
        if (EditorGUI.EndChangeCheck())
        {
            if (Application.isPlaying)
            {
                player.Player.CullingMode =
                    serializedObject.FindProperty("cullingMode").enumValueIndex == 0 ? GPUSKinningCullingMode.AlwaysAnimate :
                    serializedObject.FindProperty("cullingMode").enumValueIndex == 1 ? GPUSKinningCullingMode.CullUpdateTransforms : GPUSKinningCullingMode.CullCompletely;
            }
        }

        #region 根据defaultPlayingClipIndex(索引)获取默认播放的动画
        GPUSkinningAnimation anim = serializedObject.FindProperty("anim").objectReferenceValue as GPUSkinningAnimation;
        SerializedProperty   defaultPlayingClipIndex = serializedObject.FindProperty("defaultPlayingClipIndex");
        //生成anim.clips.name数组
        if (clipsName == null && anim != null)
        {
            List <string> list = new List <string>();
            for (int i = 0; i < anim.clips.Length; ++i)
            {
                list.Add(anim.clips[i].name);
            }
            clipsName = list.ToArray();
            //限定范围
            defaultPlayingClipIndex.intValue = Mathf.Clamp(defaultPlayingClipIndex.intValue, 0, anim.clips.Length);
        }
        if (clipsName != null)
        {
            EditorGUI.BeginChangeCheck();
            //绘制下拉框(属性名称、索引号、下拉框选项名称)
            defaultPlayingClipIndex.intValue = EditorGUILayout.Popup("Default Playing", defaultPlayingClipIndex.intValue, clipsName);
            if (EditorGUI.EndChangeCheck())
            {
                player.Player.Play(clipsName[defaultPlayingClipIndex.intValue]);
            }
        }
        #endregion
        //应用属性修改(一定要调用)
        serializedObject.ApplyModifiedProperties();
    }
    //注册需要渲染的模型种类
    public void Register(GPUSkinningAnimation anim, Mesh mesh, Material originalMtrl, TextAsset textureRawData, GPUSkinningPlayerMono player, out GPUSkinningPlayerResources resources)
    {
        resources = null;

        if (anim == null || originalMtrl == null || textureRawData == null || player == null)
        {
            return;
        }

        // item完成初始化后赋值给resources
        GPUSkinningPlayerResources item = null;

        int numItems = items.Count;

        //查询该anim是否已注册,根据guid(唯一标识符)判断
        for (int i = 0; i < numItems; ++i)
        {
            if (items[i].anim.guid == anim.guid)
            {
                //找到已注册的Resources,赋值给item
                item = items[i];
                break;
            }
        }

        #region 未找到,初始化赋值
        if (item == null)
        {
            item = new GPUSkinningPlayerResources();
            //Debug.Log("new");
            items.Add(item);
        }

        if (item.anim == null)
        {
            item.anim = anim;
        }

        if (item.mesh == null)
        {
            item.mesh = mesh;
        }

        if (item.texture == null)
        {
            item.texture = GPUSkinningUtil.CreateTexture2D(textureRawData, anim);
        }

        item.InitMaterial(originalMtrl, HideFlags.None);

        #endregion

        //为player设置CullingBounds(在CullingGroup中)
        if (!item.players.Contains(player))
        {
            item.players.Add(player);
            // fzy delete:culling
            //item.AddCullingBounds();
        }

        resources = item;
    }