public void CrossFade(string clipName, float fadeLength) { if (playingClip == null) { Play(clipName); } else { List <GPUSkinClip> clips = animData.clips; int numClips = clips == null ? 0 : clips.Count; for (int i = 0; i < numClips; ++i) { GPUSkinClip clip = clips[i]; if (clip.name == clipName) { if (playingClip != clip) { crossFadeProgress = 0; crossFadeTime = fadeLength; SetNewPlayingClip(clip); return; } if ((playingClip.wrapMode == GPUSkinWrapMode.Once && IsTimeAtTheEndOfLoop) || !isPlaying) { SetNewPlayingClip(clip); return; } } } } }
public void Play(string clipName) { if (animData == null) { return; } List <GPUSkinClip> clips = animData.clips; int numClips = clips == null ? 0 : clips.Count; for (int i = 0; i < numClips; ++i) { GPUSkinClip clip = clips[i]; if (clip.name == clipName) { if (playingClip != clip || (playingClip != null && playingClip.wrapMode == GPUSkinWrapMode.Once && IsTimeAtTheEndOfLoop) || (playingClip != null && !isPlaying)) { SetNewPlayingClip(clip); crossFadeTime = 0; } return; } } }
private void UpdateMaterial(float deltaTime) { int frameIndex = GetFrameIndex(); if (lastPlayingClip == playingClip && lastPlayingFrameIndex == frameIndex) { return; } lastPlayingClip = playingClip; lastPlayingFrameIndex = frameIndex; bool isCrossBlending = IsCrossFadeBlending(lastPlayedClip, crossFadeTime, crossFadeProgress); int frameIndexCrossFade = -1; GPUSkinFrame frameCrossFade = null; float crossFadeBlendFactor = 1; bool isRootMotion = playingClip.rootMotionEnabled && RootMotionEnabled; GPUSkinFrame frame = playingClip.frames[frameIndex]; if (isCrossBlending) { frameIndexCrossFade = GetCrossFadeFrameIndex(); frameCrossFade = lastPlayedClip.frames[frameIndexCrossFade]; crossFadeBlendFactor = Mathf.Clamp01(crossFadeProgress / crossFadeTime); } if (Visible || CullingMode == GPUSkinCullingMode.AlwaysAnimate) { mpb.SetVector(shaderPorpID_GPUSkin_FrameIndex_PixelSegmentation, new Vector4(frameIndex, playingClip.pixelSegmentation, 0, 0)); if (isRootMotion) { Matrix4x4 rootMotionInv = animData.rootTransformMatrix * frame.RootMotionInv(animData.rootBoneIndex); //Matrix4x4 rootMotionInv = frame.RootMotionInv(animData.rootBoneIndex); mpb.SetMatrix(shaderPorpID_GPUSkin_RootMotion, rootMotionInv); } else { mpb.SetMatrix(shaderPorpID_GPUSkin_RootMotion, Matrix4x4.identity); } if (isCrossBlending) { mpb.SetVector(shaderPorpID_GPUSkin_FrameIndex_PixelSegmentation_Blend_CrossFade, new Vector4(frameIndexCrossFade, lastPlayedClip.pixelSegmentation, crossFadeBlendFactor)); } else { mpb.SetVector(shaderPorpID_GPUSkin_FrameIndex_PixelSegmentation_Blend_CrossFade, new Vector4(0, 0, 1)); } meshRender.SetPropertyBlock(mpb); } if (isRootMotion && deltaTime > 0) { if (CullingMode != GPUSkinCullingMode.CullCompletely) { DoRootMotion(deltaTime); } } }
private void SetNewPlayingClip(GPUSkinClip clip) { lastPlayedClip = playingClip; lastPlayedTime = GetCurrentTime(); isPlaying = true; playingClip = clip; time = 0; rootMotionFrameIndex = -1; rootMotionDeltaPosition = Vector3.zero; rootMotionDeltaQuat = Quaternion.identity; }
private void SetTextureInfo(GPUSkinAnimationData data) { int numPixels = 0; var clips = data.clips; int numClips = clips.Count; for (int clipIndex = 0; clipIndex < numClips; ++clipIndex) { GPUSkinClip clip = clips[clipIndex]; clip.pixelSegmentation = numPixels; numPixels += data.bones.Count * 3 /*treat 3 pixels as a float3x4*/ * clip.frames.Length; } CalculateTextureSize(numPixels, out data.textureWidth, out data.textureHeight); }
public static Texture2D CreateTexture2D(GPUSkinAnimationData animData, out Color[] pixels) { pixels = null; if (animData == null) { return(null); } if (SystemInfo.SupportsTextureFormat(TextureFormat.RGBAHalf)) { if (!bSwitchGpuSkinFloatTexture) { Shader.EnableKeyword("GPUSKIN_SUPPORT_FLOAT_TEXTURE"); Shader.DisableKeyword("GPUSKIN_NOSUPPORT_FLOAT_TEXTURE"); bSwitchGpuSkinFloatTexture = true; } Texture2D texture = new Texture2D(animData.textureWidth, animData.textureHeight, TextureFormat.RGBAHalf, false, true); texture.name = "GPUSkinTextureMatrix"; texture.filterMode = FilterMode.Point; pixels = texture.GetPixels(); int pixelIndex = 0; int clipCount = animData.clips.Count; for (int clipIndex = 0; clipIndex < clipCount; ++clipIndex) { GPUSkinClip clip = animData.clips[clipIndex]; var frames = clip.frames; int numFrames = frames.Length; for (int frameIndex = 0; frameIndex < numFrames; ++frameIndex) { GPUSkinFrame 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, 0); texture.Apply(false); return(texture); } else if (SystemInfo.SupportsTextureFormat(TextureFormat.RGBA32)) { if (!bSwitchGpuSkinFloatTexture) { Shader.EnableKeyword("GPUSKIN_NOSUPPORT_FLOAT_TEXTURE"); Shader.DisableKeyword("GPUSKIN_SUPPORT_FLOAT_TEXTURE"); bSwitchGpuSkinFloatTexture = true; } Texture2D texture = new Texture2D(animData.textureWidth * 2, animData.textureHeight, TextureFormat.RGBA32, false, true); texture.name = "GPUSkinTextureMatrix"; texture.filterMode = FilterMode.Point; pixels = texture.GetPixels(); int pixelIndex = 0; int clipCount = animData.clips.Count; for (int clipIndex = 0; clipIndex < clipCount; ++clipIndex) { GPUSkinClip clip = animData.clips[clipIndex]; var frames = clip.frames; int numFrames = frames.Length; for (int frameIndex = 0; frameIndex < numFrames; ++frameIndex) { GPUSkinFrame frame = frames[frameIndex]; Matrix4x4[] matrices = frame.matrices; int numMatrices = matrices.Length; for (int matrixIndex = 0; matrixIndex < numMatrices; ++matrixIndex) { Matrix4x4 matrix = matrices[matrixIndex]; pixels[pixelIndex++] = Float2ToColor(matrix.m00, matrix.m01); pixels[pixelIndex++] = Float2ToColor(matrix.m02, matrix.m03); pixels[pixelIndex++] = Float2ToColor(matrix.m10, matrix.m11); pixels[pixelIndex++] = Float2ToColor(matrix.m12, matrix.m13); pixels[pixelIndex++] = Float2ToColor(matrix.m20, matrix.m21); pixels[pixelIndex++] = Float2ToColor(matrix.m22, matrix.m23); } } } texture.SetPixels(pixels, 0); texture.Apply(false); return(texture); } return(null); }
public bool IsCrossFadeBlending(GPUSkinClip lastPlayedClip, float crossFadeTime, float crossFadeProgress) { return(lastPlayedClip != null && crossFadeTime > 0 && crossFadeProgress <= crossFadeTime); }
private int GetFrameIndex(GPUSkinClip clip, float time) { return((int)(time * clip.frameRate) % (int)(clip.length * clip.frameRate)); }
private int GetTheLastFrameIndex(GPUSkinClip clip) { return((int)(clip.length * clip.frameRate) - 1); }
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.Count == 0) { ShowDialog("Please set Animation Clips."); return; } animClip = animClips[samplingClipIndex].clip; if (animClip == null) { isSampling = false; return; } int numFrames = (int)(GetClipFrameRate(animClip, samplingClipIndex) * animClip.length); if (numFrames == 0) { isSampling = false; return; } smr = GetComponentInChildren <SkinnedMeshRenderer>(); if (smr == null) { ShowDialog("Cannot find SkinnedMeshRenderer."); return; } Mesh mesh = smr.sharedMesh; if (mesh == null) { ShowDialog("Missing Mesh"); return; } samplingFrameIndex = 0; gpuSkinAnimData = animData == null?ScriptableObject.CreateInstance <GPUSkinAnimationData>() : animData; gpuSkinAnimData.name = animName; List <GPUSkinBone> bones_result = new List <GPUSkinBone>(); CollectBones(bones_result, smr.bones, mesh.bindposes, null, rootBoneTransform, 0); gpuSkinAnimData.bones = bones_result; gpuSkinAnimData.rootBoneIndex = 0; gpuSkinAnimData.rootTransformMatrix = rootTransformMatrix; int numClips = gpuSkinAnimData.clips == null ? 0 : gpuSkinAnimData.clips.Count; int overrideClipIndex = -1; for (int i = 0; i < numClips; ++i) { if (gpuSkinAnimData.clips[i].name == animClips[samplingClipIndex].name) { overrideClipIndex = i; break; } } gpuSkinClip = new GPUSkinClip(); gpuSkinClip.name = animClips[samplingClipIndex].name; gpuSkinClip.frameRate = GetClipFrameRate(animClip, samplingClipIndex); gpuSkinClip.length = animClip.length; gpuSkinClip.wrapMode = animClips[samplingClipIndex].wrapMode; gpuSkinClip.frames = new GPUSkinFrame[numFrames]; gpuSkinClip.rootMotionEnabled = animClips[samplingClipIndex].rootMotion; if (gpuSkinAnimData.clips == null) { gpuSkinAnimData.clips = new List <GPUSkinClip>(); gpuSkinAnimData.clips.Add(gpuSkinClip); } else { if (overrideClipIndex == -1) { gpuSkinAnimData.clips.Add(gpuSkinClip); } else { GPUSkinClip overridedClip = gpuSkinAnimData.clips[overrideClipIndex]; //RestoreCustomClipData(overridedClip, gpuSkinningClip); gpuSkinAnimData.clips[overrideClipIndex] = gpuSkinClip; } } SetCurrentAnimationClip(); PrepareRecordAnimator(); isSampling = true; }