public void setData(GpuSkinningAnimClip clip, bool l, float blendDura, float timeOffset) { setData(clip, l, blendDura); timer = timeOffset; while (timer >= loopDuration && loopDuration != 0) { timer -= loopDuration; } }
// 设置数据 public void setData(GpuSkinningAnimClip clip, bool l, float blendDura) { clear(); hasData = true; animClip = clip; loop = l; blendDuration = blendDura; duration = animClip.getDuration(); loopDuration = duration + animClip.getPerFrameDuration(); }
// 移动数据 public void moveData(PlayAnimationInfo info) { animClip = info.animClip; timer = info.timer; loop = info.loop; blendDuration = info.blendDuration; blendTimer = info.blendTimer; hasData = info.hasData; duration = info.duration; loopDuration = info.loopDuration; info.clear(); }
// 清空 public void clear() { animClip = null; timer = 0; loop = false; blendDuration = 0; blendTimer = 0; duration = 0; loopDuration = 0; recCurFrame = 0; recNextFrame = 0; recNextFrameProgress = 0; hasData = false; }
public void refreshGeneratorInfo() { animData = ScriptableObject.CreateInstance <GpuSkinningAnimData>(); int totalFrame = 0; int clipFrame = 0; clipsData.Clear(); boneIds = resortBone(curGameObject); animData.totalBoneNum = boneIds.Count; animClips = clipList.ToArray(); for (int i = 0; i < animClips.Length; ++i) { AnimationClip clip = animClips[i]; clipFrame = (int)(clip.frameRate * clip.length / compression); GpuSkinningAnimClip clipData = new GpuSkinningAnimClip(clip.name, totalFrame, totalFrame + clipFrame - 1, clip.frameRate / compression); clipsData.Add(clipData); totalFrame += clipFrame; } animData.totalFrame = totalFrame; animData.clips = clipsData.ToArray(); GenerateConfig config = generateConfigs[genType]; if (config.animationType == AnimationType.Vertices) { // 顶点动画 Mesh mesh = selectedSkinnedMeshRenderer.sharedMesh; animData.texWidth = mesh.vertices.Length; animData.texHeight = totalFrame * 2; // vec3需要两个像素表示(rgba32->float16) } else { // 骨骼动画 long totalPixels = boneIds.Count * DEFAULT_PER_FRAME_BONE_DATASPACE * totalFrame; calTextureSize(totalPixels, out animData.texWidth, out animData.texHeight); } }
public void generateTexAndMesh(string parentFolder, string savePath, string dataFileName) { int numBones = animData.totalBoneNum; // 重新生成mesh rebuildAllMeshes(savePath, parentFolder); // 将骨骼矩阵写入纹理 var tex2D = new Texture2D(animData.texWidth, animData.texHeight, TextureFormat.RGBA32, false); tex2D.filterMode = FilterMode.Point; int clipIdx = 0; int pixelIdx = 0; Vector2Int pixelUv; GpuSkinningAnimClip boneAnimation = null; AnimationClip clip = null; List <Matrix4x4> boneMatrices = null; for (clipIdx = 0; clipIdx < animClips.Length; ++clipIdx) { boneAnimation = animData.clips[clipIdx]; clip = animClips[clipIdx]; for (int frameIndex = 0; frameIndex < boneAnimation.Length(); frameIndex++) { boneMatrices = samplerAnimationClipBoneMatrices(curGameObject, clip, (float)frameIndex / clip.frameRate); for (int boneIndex = 0; boneIndex < numBones; boneIndex++) { Matrix4x4 matrix = boneMatrices[boneIndex]; Quaternion rotation = ToQuaternion(matrix); Vector3 scale = matrix.lossyScale; float sx = Mathf.Floor(scale.x * 100.0f); float sy = Mathf.Floor(scale.y * 100.0f); float sz = Mathf.Floor(scale.z * 100.0f); if ((sx - sy) > 5.0f || (sx - sz) > 5.0f || (sy - sz) > 5.0f) { Transform remapBone = null; foreach (var key in boneIds.Keys) { if (boneIds[key] == boneIndex) { remapBone = key; break; } } string strLog = string.Format("AnimClip scale X Y Z not equal: {0} -> {1} {2}", curGameObject.name, boneAnimation.name, remapBone.transform.name); Warning("AnimClip scale", strLog); } pixelUv = convertPixel2UV(pixelIdx++); Color color1 = convertFloat16Bytes2Color(convertFloat32toFloat16Bytes(rotation.x), convertFloat32toFloat16Bytes(rotation.y)); tex2D.SetPixel(pixelUv.x, pixelUv.y, color1); pixelUv = convertPixel2UV(pixelIdx++); Color color2 = convertFloat16Bytes2Color(convertFloat32toFloat16Bytes(rotation.z), convertFloat32toFloat16Bytes(rotation.w)); tex2D.SetPixel(pixelUv.x, pixelUv.y, color2); pixelUv = convertPixel2UV(pixelIdx++); Color color3 = convertFloat16Bytes2Color(convertFloat32toFloat16Bytes(matrix.GetColumn(3).x), convertFloat32toFloat16Bytes(matrix.GetColumn(3).y)); tex2D.SetPixel(pixelUv.x, pixelUv.y, color3); pixelUv = convertPixel2UV(pixelIdx++); Color color4 = convertFloat16Bytes2Color(convertFloat32toFloat16Bytes(matrix.GetColumn(3).z), convertFloat32toFloat16Bytes(Mathf.Clamp01(matrix.lossyScale.magnitude))); tex2D.SetPixel(pixelUv.x, pixelUv.y, color4); //Debug.Log("==============frameIndex========start========"+ frameIndex); //Debug.Log("=======rotation==========="+ rotation.x+", "+ rotation.y+", " + rotation.z +", "+rotation.w); //Vector4 rrrr = convertColors2Halfs(color1, color2); //Debug.Log("=======rotation===22======" + rrrr.x + ", " + rrrr.y + ", " + rrrr.z + ", " + rrrr.w); //Debug.Log("=======translation===========" + matrix.GetColumn(3).x + ", " + matrix.GetColumn(3).y + ", " + matrix.GetColumn(3).z + ", " + Mathf.Clamp01(matrix.lossyScale.magnitude)); //Vector4 ttttt = convertColors2Halfs(color3, color4); //Debug.Log("=======translation===22======" + ttttt.x + ", " + ttttt.y + ", " + ttttt.z + ", " + ttttt.w); //Debug.Log("==============frameIndex========end========" + frameIndex); } } } tex2D.Apply(); // 导出动画纹理 animTexturePath = savePath + dataFileName.Replace(".asset", "") + ".png"; exportTexture(tex2D, animTexturePath); setAnimationTextureProperties(animTexturePath); // 存储 string filePath = savePath + dataFileName; AssetDatabase.CreateAsset(animData, filePath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); }
public void generateTexAndMesh_verticesAnim(string parentFolder, string savePath, string dataFileName) { // 重新生成mesh(这一步生成的mesh还是带骨骼indices和骨骼权重的,但顶点动画是不需要这些数据的,后面会删掉) rebuildAllMeshes(savePath, parentFolder); // 将骨骼矩阵写入纹理 var tex2D = new Texture2D(animData.texWidth, animData.texHeight, TextureFormat.RGB24, false); tex2D.filterMode = FilterMode.Point; int clipIdx = 0; int pixelIdx = 0; int totalFrameIndex = 0; GpuSkinningAnimClip boneAnimation = null; AnimationClip clip = null; List <Matrix4x4> boneMatrices = null; Vector4 boneIndices, boneWeights; Matrix4x4 boneMatrix0, boneMatrix1, boneMatrix2, boneMatrix3; Vector3 src_vertex; Vector4 vertex, position; for (clipIdx = 0; clipIdx < animClips.Length; ++clipIdx) { boneAnimation = animData.clips[clipIdx]; clip = animClips[clipIdx]; for (int frameIndex = 0; frameIndex < boneAnimation.Length(); frameIndex++) { boneMatrices = samplerAnimationClipBoneMatrices(curGameObject, clip, (float)frameIndex / (clip.frameRate / compression)); for (int vertexIndex = 0; vertexIndex < instMesh.vertices.Length; ++vertexIndex) { src_vertex = instMesh.vertices[vertexIndex]; vertex = new Vector4(src_vertex.x, src_vertex.y, src_vertex.z, 1); boneIndices = boneIndicesList[vertexIndex]; boneWeights = boneWeightsList[vertexIndex]; boneMatrix0 = boneMatrices[Mathf.RoundToInt(boneIndices.x)]; boneMatrix1 = boneMatrices[Mathf.RoundToInt(boneIndices.y)]; boneMatrix2 = boneMatrices[Mathf.RoundToInt(boneIndices.z)]; boneMatrix3 = boneMatrices[Mathf.RoundToInt(boneIndices.w)]; matrixMulFloat(ref boneMatrix0, boneWeights.x); matrixMulFloat(ref boneMatrix1, boneWeights.y); matrixMulFloat(ref boneMatrix2, boneWeights.z); matrixMulFloat(ref boneMatrix3, boneWeights.w); position = (matrixAddMatrix(matrixAddMatrix(boneMatrix0, boneMatrix1), matrixAddMatrix(boneMatrix2, boneMatrix3))) * vertex; Color[] colors = convertThreeFloat16Bytes2TwoColor(convertFloat32toFloat16Bytes(position.x), convertFloat32toFloat16Bytes(position.y), convertFloat32toFloat16Bytes(position.z)); tex2D.SetPixel(vertexIndex, totalFrameIndex * 2, colors[0]); tex2D.SetPixel(vertexIndex, totalFrameIndex * 2 + 1, colors[1]); } ++totalFrameIndex; } } tex2D.Apply(); // 导出动画纹理 animTexturePath = savePath + dataFileName.Replace(".asset", "") + ".png"; exportTexture(tex2D, animTexturePath); setAnimationTextureProperties(animTexturePath); // 存储数据 string filePath = savePath + dataFileName; AssetDatabase.CreateAsset(animData, filePath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); // 删除mesh的骨骼信息 instMesh.uv2 = null; instMesh.uv3 = null; // 添加mesh的顶点索引 (TODO: unity shader中是否可以直接获取?) List <Vector4> indices = new List <Vector4>(); for (int vertexIndex = 0; vertexIndex < instMesh.vertices.Length; ++vertexIndex) { indices.Add(new Vector4(vertexIndex, vertexIndex, vertexIndex, vertexIndex)); } instMesh.SetUVs(1, indices); EditorUtility.SetDirty(instMesh); AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); }