public void Init(GPUSkinAnimationData animData, Mesh mesh, Material mtrl) { this.animData = animData; this.mesh = mesh; this.material = mtrl; StartInit(); }
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); }
private void OnPreview(GPUSkinGenerator gen) { BeginBox(); { if (GUILayout.Button("Preview And Edit")) { animData = gen.animData; mesh = gen.savedMesh; previewMaterial = gen.previewMaterial; if (animData == null || mesh == null || previewMaterial == null) { EditorUtility.DisplayDialog("GPUSkin", "Missing Preview Resources", "OK"); } else { if (previewRenderTexture == null && !EditorApplication.isPlaying) { previewRenderTexture = new RenderTexture(1024, 1024, 32, RenderTextureFormat.Default, RenderTextureReadWrite.Default); previewRenderTexture.hideFlags = HideFlags.HideAndDontSave; GameObject cameroGo = new GameObject("GPUSkinEditorCameraGo"); cameroGo.hideFlags = HideFlags.HideAndDontSave; previewCamera = cameroGo.AddComponent <Camera>(); previewCamera.hideFlags = HideFlags.HideAndDontSave; previewCamera.farClipPlane = 100; previewCamera.targetTexture = previewRenderTexture; previewCamera.enabled = false; previewCamera.clearFlags = CameraClearFlags.SolidColor; previewCamera.backgroundColor = new Color(0.2f, 0.2f, 0.2f, 1.0f); previewCamera.transform.position = new Vector3(999, 1002, 999); GameObject previewGo = new GameObject("GPUSkinEditorPreviewGo"); previewGo.hideFlags = HideFlags.HideAndDontSave; previewGo.transform.position = new Vector3(999, 999, 1002); previewAnimation = previewGo.AddComponent <GPUSkinAnimation>(); previewAnimation.hideFlags = HideFlags.HideAndDontSave; previewAnimation.Init(animData, mesh, previewMaterial); previewAnimation.CullingMode = GPUSkinCullingMode.AlwaysAnimate; } } } GetLastGUIRect(ref previewEditBtnRect); if (previewRenderTexture != null) { int previewRectSize = Mathf.Min((int)(previewEditBtnRect.width * 0.98f), 512); EditorGUILayout.BeginHorizontal(); { EditorGUILayout.BeginVertical(); { GUILayout.Box(previewRenderTexture, GUILayout.Width(previewRectSize), GUILayout.Height(previewRectSize)); GetLastGUIRect(ref previewInteractionRect); PreviewInteraction(previewInteractionRect); 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(previewInteractionRect.x, previewInteractionRect.y + previewInteractionRect.height, previewInteractionRect.width, 5), previewAnimation.NormalizedTime, string.Empty); } EditorGUILayout.EndHorizontal(); } } EndBox(); serializedObject.ApplyModifiedProperties(); }
private void Update() { if (!isSampling) { return; } int totalFrams = (int)(gpuSkinClip.length * gpuSkinClip.frameRate); samplingTotalFrams = totalFrams; if (samplingFrameIndex >= totalFrams) { if (animator != null) { animator.StopPlayback(); } string savePath = null; if (animData == null) { savePath = EditorUtility.SaveFolderPanel("GPUSkinning Animation Data Save", GetUserPreferDir(), string.Empty); } else { string animPath = AssetDatabase.GetAssetPath(animData); 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 + "/GPUSKinAnimData_" + animName + ".asset"; SetTextureInfo(gpuSkinAnimData); EditorUtility.SetDirty(gpuSkinAnimData); if (animData != gpuSkinAnimData) { AssetDatabase.CreateAsset(gpuSkinAnimData, savedAnimPath); } WriteTempData(TEMP_SAVED_ANIM_PATH, savedAnimPath); animData = gpuSkinAnimData; if (samplingClipIndex == 0) { Mesh newMesh = CreateNewMesh(smr.sharedMesh, "GPUSkinMesh"); if (savedMesh != null) { newMesh.bounds = savedMesh.bounds; } string savedMeshPath = dir + "/GPUSKinMesh_" + 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 = gpuSkinClip.length * ((float)samplingFrameIndex / totalFrams); GPUSkinFrame frame = new GPUSkinFrame(); gpuSkinClip.frames[samplingFrameIndex] = frame; frame.matrices = new Matrix4x4[gpuSkinAnimData.bones.Count]; 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)); }
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; }