From 2f0940dfc2e7263860cc7d99bed91964af0b3175 Mon Sep 17 00:00:00 2001 From: jimCheng Date: Thu, 27 Apr 2017 16:01:38 +0800 Subject: [PATCH] New API of Individual Difference Animation --- .../Editor/GPUSkinningPlayerMonoEditor.cs | 7 +++ .../Scripts/GPUSkinningExecuteOncePerFrame.cs | 28 ++++++++++ ...=> GPUSkinningExecuteOncePerFrame.cs.meta} | 4 +- .../GPUSkinning/Scripts/GPUSkinningPlayer.cs | 47 +++++++++++++---- .../Scripts/GPUSkinningPlayerMaterial.cs | 51 ------------------- .../Scripts/GPUSkinningPlayerMono.cs | 9 +++- .../Scripts/GPUSkinningPlayerMonoManager.cs | 2 +- .../Scripts/GPUSkinningPlayerResources.cs | 28 +++++++--- 8 files changed, 103 insertions(+), 73 deletions(-) create mode 100644 Assets/GPUSkinning/Scripts/GPUSkinningExecuteOncePerFrame.cs rename Assets/GPUSkinning/Scripts/{GPUSkinningPlayerMaterial.cs.meta => GPUSkinningExecuteOncePerFrame.cs.meta} (75%) delete mode 100644 Assets/GPUSkinning/Scripts/GPUSkinningPlayerMaterial.cs diff --git a/Assets/GPUSkinning/Editor/GPUSkinningPlayerMonoEditor.cs b/Assets/GPUSkinning/Editor/GPUSkinningPlayerMonoEditor.cs index a0b8482..b4834f4 100644 --- a/Assets/GPUSkinning/Editor/GPUSkinningPlayerMonoEditor.cs +++ b/Assets/GPUSkinning/Editor/GPUSkinningPlayerMonoEditor.cs @@ -56,6 +56,13 @@ public override void OnInspectorGUI() } } + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(serializedObject.FindProperty("individualDifferenceEnabled"), new GUIContent("Individual Difference")); + if(EditorGUI.EndChangeCheck()) + { + player.Player.IndividualDifferenceEnabled = serializedObject.FindProperty("individualDifferenceEnabled").boolValue; + } + GPUSkinningAnimation anim = serializedObject.FindProperty("anim").objectReferenceValue as GPUSkinningAnimation; SerializedProperty defaultPlayingClipIndex = serializedObject.FindProperty("defaultPlayingClipIndex"); if (clipsName == null && anim != null) diff --git a/Assets/GPUSkinning/Scripts/GPUSkinningExecuteOncePerFrame.cs b/Assets/GPUSkinning/Scripts/GPUSkinningExecuteOncePerFrame.cs new file mode 100644 index 0000000..89e77c7 --- /dev/null +++ b/Assets/GPUSkinning/Scripts/GPUSkinningExecuteOncePerFrame.cs @@ -0,0 +1,28 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class GPUSkinningExecuteOncePerFrame +{ + private int frameCount = -1; + + public bool CanBeExecute() + { + if (Application.isPlaying) + { + return frameCount != Time.frameCount; + } + else + { + return true; + } + } + + public void MarkAsExecuted() + { + if (Application.isPlaying) + { + frameCount = Time.frameCount; + } + } +} diff --git a/Assets/GPUSkinning/Scripts/GPUSkinningPlayerMaterial.cs.meta b/Assets/GPUSkinning/Scripts/GPUSkinningExecuteOncePerFrame.cs.meta similarity index 75% rename from Assets/GPUSkinning/Scripts/GPUSkinningPlayerMaterial.cs.meta rename to Assets/GPUSkinning/Scripts/GPUSkinningExecuteOncePerFrame.cs.meta index 5ea9766..7640366 100644 --- a/Assets/GPUSkinning/Scripts/GPUSkinningPlayerMaterial.cs.meta +++ b/Assets/GPUSkinning/Scripts/GPUSkinningExecuteOncePerFrame.cs.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 19cefb4d0988bed4988b10a71d89dcfe -timeCreated: 1492493614 +guid: de7725a4952ca724eb82d06accbc336b +timeCreated: 1493278053 licenseType: Pro MonoImporter: serializedVersion: 2 diff --git a/Assets/GPUSkinning/Scripts/GPUSkinningPlayer.cs b/Assets/GPUSkinning/Scripts/GPUSkinningPlayer.cs index c271657..4a89970 100644 --- a/Assets/GPUSkinning/Scripts/GPUSkinningPlayer.cs +++ b/Assets/GPUSkinning/Scripts/GPUSkinningPlayer.cs @@ -21,6 +21,8 @@ public MeshRenderer MeshRenderer private float time = 0; + private float timeDiff = 0; + private GPUSkinningClip playingClip = null; private GPUSkinningPlayerResources res = null; @@ -52,6 +54,19 @@ public bool IsPlaying } } + private bool individualDifferenceEnabled = true; + public bool IndividualDifferenceEnabled + { + get + { + return individualDifferenceEnabled; + } + set + { + individualDifferenceEnabled = value; + } + } + private List joints = null; public List Joints { @@ -109,7 +124,7 @@ public GPUSkinningPlayer(GameObject attachToThisGo, GPUSkinningPlayerResources r mf = go.AddComponent(); } - mr.sharedMaterial = res.mtrl.Material; + mr.sharedMaterial = res.mtrl; mf.sharedMesh = res.mesh; mpb = new MaterialPropertyBlock(); @@ -138,7 +153,8 @@ public void Play(string clipName) } else if(playingClip.wrapMode == GPUSkinningWrapMode.Loop) { - time = Random.Range(0, playingClip.length); + time = 0; + timeDiff = Random.Range(0, playingClip.length); } else { @@ -182,26 +198,25 @@ private void Update_Internal(float timeDelta) return; } - if(res == null || res.mtrl == null || res.mtrl.Material == null) + if(res == null || res.mtrl == null || res.mtrl == null) { return; } if (playingClip.wrapMode == GPUSkinningWrapMode.Loop) { - UpdateMaterial(); - time += timeDelta; + UpdateMaterial(timeDelta); } else if(playingClip.wrapMode == GPUSkinningWrapMode.Once) { if (time >= playingClip.length) { time = playingClip.length; - UpdateMaterial(); + UpdateMaterial(timeDelta); } else { - UpdateMaterial(); + UpdateMaterial(timeDelta); time += timeDelta; if(time > playingClip.length) { @@ -215,11 +230,11 @@ private void Update_Internal(float timeDelta) } } - private void UpdateMaterial() + private void UpdateMaterial(float deltaTime) { int frameIndex = GetFrameIndex(); GPUSkinningFrame frame = playingClip.frames[frameIndex]; - res.UpdateMaterial(); + res.Update(deltaTime); res.UpdatePlayingData(mpb, playingClip, frameIndex, frame, playingClip.rootMotionEnabled && rootMotionEnabled); mr.SetPropertyBlock(mpb); UpdateJoints(frame); @@ -240,6 +255,20 @@ private void UpdateMaterial() private int GetFrameIndex() { + float time = 0; + if(WrapMode == GPUSkinningWrapMode.Once) + { + time = this.time; + } + else if(WrapMode == GPUSkinningWrapMode.Loop) + { + time = res.Time + (individualDifferenceEnabled ? this.timeDiff : 0); + } + else + { + throw new System.NotImplementedException(); + } + if (Mathf.Approximately(playingClip.length, time)) { return (int)(playingClip.length * playingClip.fps) - 1; diff --git a/Assets/GPUSkinning/Scripts/GPUSkinningPlayerMaterial.cs b/Assets/GPUSkinning/Scripts/GPUSkinningPlayerMaterial.cs deleted file mode 100644 index 5498d3e..0000000 --- a/Assets/GPUSkinning/Scripts/GPUSkinningPlayerMaterial.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -public class GPUSkinningPlayerMaterial -{ - private int frameCount = -1; - - private Material mtrl = null; - public Material Material - { - get - { - return mtrl; - } - } - - public GPUSkinningPlayerMaterial(Material mtrl) - { - this.mtrl = mtrl; - } - - public bool MaterialCanBeSetData() - { - if (Application.isPlaying) - { - return frameCount != Time.frameCount; - } - else - { - return true; - } - } - - public void MarkMaterialAsSet() - { - if (Application.isPlaying) - { - frameCount = Time.frameCount; - } - } - - public void Destroy() - { - if(mtrl != null) - { - Object.DestroyImmediate(mtrl); - mtrl = null; - } - } -} diff --git a/Assets/GPUSkinning/Scripts/GPUSkinningPlayerMono.cs b/Assets/GPUSkinning/Scripts/GPUSkinningPlayerMono.cs index 79bd44c..fe68386 100644 --- a/Assets/GPUSkinning/Scripts/GPUSkinningPlayerMono.cs +++ b/Assets/GPUSkinning/Scripts/GPUSkinningPlayerMono.cs @@ -29,6 +29,10 @@ public class GPUSkinningPlayerMono : MonoBehaviour [SerializeField] private bool rootMotionEnabled = false; + [HideInInspector] + [SerializeField] + private bool individualDifferenceEnabled = true; + private static GPUSkinningPlayerMonoManager playerManager = new GPUSkinningPlayerMonoManager(); private GPUSkinningPlayer player = null; @@ -74,14 +78,15 @@ public void Init() res = new GPUSkinningPlayerResources(); res.anim = anim; res.mesh = mesh; - res.mtrl = new GPUSkinningPlayerMaterial(new Material(mtrl)); + res.mtrl = new Material(mtrl); res.texture = GPUSkinningUtil.CreateTexture2D(textureRawData, anim); - res.mtrl.Material.hideFlags = HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor; + res.mtrl.hideFlags = HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor; res.texture.hideFlags = HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor; } player = new GPUSkinningPlayer(gameObject, res); player.RootMotionEnabled = Application.isPlaying ? rootMotionEnabled : false; + player.IndividualDifferenceEnabled = individualDifferenceEnabled; if (anim != null && anim.clips != null && anim.clips.Length > 0) { diff --git a/Assets/GPUSkinning/Scripts/GPUSkinningPlayerMonoManager.cs b/Assets/GPUSkinning/Scripts/GPUSkinningPlayerMonoManager.cs index 63ab785..b06d82e 100644 --- a/Assets/GPUSkinning/Scripts/GPUSkinningPlayerMonoManager.cs +++ b/Assets/GPUSkinning/Scripts/GPUSkinningPlayerMonoManager.cs @@ -45,7 +45,7 @@ public void Register(GPUSkinningAnimation anim, Mesh mesh, Material originalMtrl if(item.mtrl == null) { - item.mtrl = new GPUSkinningPlayerMaterial(new Material(originalMtrl)); + item.mtrl = new Material(originalMtrl); } if(item.texture == null) diff --git a/Assets/GPUSkinning/Scripts/GPUSkinningPlayerResources.cs b/Assets/GPUSkinning/Scripts/GPUSkinningPlayerResources.cs index 418942e..11c0b58 100644 --- a/Assets/GPUSkinning/Scripts/GPUSkinningPlayerResources.cs +++ b/Assets/GPUSkinning/Scripts/GPUSkinningPlayerResources.cs @@ -8,12 +8,23 @@ public class GPUSkinningPlayerResources public Mesh mesh = null; - public GPUSkinningPlayerMaterial mtrl = null; + public Material mtrl = null; public Texture2D texture = null; public List players = new List(); + private GPUSkinningExecuteOncePerFrame executeOncePerFrame = new GPUSkinningExecuteOncePerFrame(); + + private float time = 0; + public float Time + { + get + { + return time; + } + } + private static int shaderPropID_GPUSkinning_TextureMatrix = -1; private static int shaderPropID_GPUSkinning_NumPixelsPerFrame = 0; @@ -49,7 +60,7 @@ public void Destroy() if (mtrl != null) { - mtrl.Destroy(); + Object.Destroy(mtrl); mtrl = null; } @@ -66,14 +77,15 @@ public void Destroy() } } - public void UpdateMaterial() + public void Update(float deltaTime) { - if(mtrl.MaterialCanBeSetData()) + if(executeOncePerFrame.CanBeExecute()) { - mtrl.MarkMaterialAsSet(); - mtrl.Material.SetTexture(shaderPropID_GPUSkinning_TextureMatrix, texture); - mtrl.Material.SetFloat(shaderPropID_GPUSkinning_NumPixelsPerFrame, anim.bones.Length * 3/*treat 3 pixels as a float3x4*/); - mtrl.Material.SetVector(shaderPropID_GPUSkinning_TextureSize, new Vector4(anim.textureWidth, anim.textureHeight, 0, 0)); + executeOncePerFrame.MarkAsExecuted(); + mtrl.SetTexture(shaderPropID_GPUSkinning_TextureMatrix, texture); + mtrl.SetFloat(shaderPropID_GPUSkinning_NumPixelsPerFrame, anim.bones.Length * 3/*treat 3 pixels as a float3x4*/); + mtrl.SetVector(shaderPropID_GPUSkinning_TextureSize, new Vector4(anim.textureWidth, anim.textureHeight, 0, 0)); + time += deltaTime; } }