public override void Init(GPUSkinning gpuSkinning) { base.Init(gpuSkinning); shaderPropID_Matrices = Shader.PropertyToID("_Matrices"); matricesUniformBlock = new Matrix4x4[gpuSkinning.GetComponentInChildren <SkinnedMeshRenderer>().bones.Length]; }
public override void Init(GPUSkinning gpuSkinning) { base.Init(gpuSkinning); shaderPropID_Time = Shader.PropertyToID("_GameTime"); smr = gpuSkinning.GetComponentInChildren <SkinnedMeshRenderer>(); mesh = smr.sharedMesh; // Init Bones int numBones = smr.bones.Length; bones = new GPUSkinning_Bone[numBones]; for (int i = 0; i < numBones; ++i) { GPUSkinning_Bone bone = new GPUSkinning_Bone(); bones[i] = bone; bone.transform = smr.bones[i]; bone.name = bone.transform.gameObject.name; bone.bindpose = mesh.bindposes[i] /*smr to bone*/; } // Construct Hierarchy for (int i = 0; i < numBones; ++i) { if (bones[i].transform == smr.rootBone) { rootBoneIndex = i; break; } } System.Action <GPUSkinning_Bone> CollectChildren = null; CollectChildren = (currentBone) => { List <GPUSkinning_Bone> children = new List <GPUSkinning_Bone>(); for (int j = 0; j < currentBone.transform.childCount; ++j) { Transform childTransform = currentBone.transform.GetChild(j); GPUSkinning_Bone childBone = GetBoneByTransform(childTransform); if (childBone != null) { childBone.parent = currentBone; children.Add(childBone); CollectChildren(childBone); } } currentBone.children = children.ToArray(); }; CollectChildren(bones[rootBoneIndex]); // New MeshFilter MeshRenderer mf = gpuSkinning.gameObject.AddComponent <MeshFilter>(); mr = gpuSkinning.gameObject.AddComponent <MeshRenderer>(); newMtrl = new Material(Shader.Find("Unlit/GPUSkinning")); newMtrl.CopyPropertiesFromMaterial(smr.sharedMaterial); mr.sharedMaterial = newMtrl; // New Mesh newMesh = new Mesh(); newMesh.vertices = mesh.vertices; newMesh.tangents = GPUSkinningUtil.ExtractBoneWeights(mesh); newMesh.uv = mesh.uv; newMesh.triangles = mesh.triangles; mf.sharedMesh = newMesh; #if UNITY_EDITOR // Extract bone animation data int boneAnimationsCount = 0; boneAnimations = new GPUSkinning_BoneAnimation[gpuSkinning.GetComponent <Animator>().runtimeAnimatorController.animationClips.Length]; foreach (AnimationClip animClip in gpuSkinning.GetComponent <Animator>().runtimeAnimatorController.animationClips) { GPUSkinning_BoneAnimation boneAnimation = ScriptableObject.CreateInstance <GPUSkinning_BoneAnimation>(); boneAnimation.fps = 60; boneAnimation.animName = animClip.name; boneAnimation.frames = new GPUSkinning_BoneAnimationFrame[(int)(animClip.length * boneAnimation.fps)]; boneAnimation.length = animClip.length; boneAnimations[boneAnimationsCount++] = boneAnimation; for (int frameIndex = 0; frameIndex < boneAnimation.frames.Length; ++frameIndex) { GPUSkinning_BoneAnimationFrame frame = new GPUSkinning_BoneAnimationFrame(); boneAnimation.frames[frameIndex] = frame; float second = (float)(frameIndex) / (float)boneAnimation.fps; List <GPUSkinning_Bone> bones2 = new List <GPUSkinning_Bone>(); List <Matrix4x4> matrices = new List <Matrix4x4>(); List <string> bonesHierarchyNames = null; if (boneAnimation.bonesHierarchyNames == null) { bonesHierarchyNames = new List <string>(); } EditorCurveBinding[] curvesBinding = AnimationUtility.GetCurveBindings(animClip); foreach (var curveBinding in curvesBinding) { GPUSkinning_Bone bone = GetBoneByHierarchyName(curveBinding.path); if (bones2.Contains(bone)) { continue; } bones2.Add(bone); if (bonesHierarchyNames != null) { bonesHierarchyNames.Add(GetBoneHierarchyName(bone)); } AnimationCurve curveRX = AnimationUtility.GetEditorCurve(animClip, curveBinding.path, curveBinding.type, "m_LocalRotation.x"); AnimationCurve curveRY = AnimationUtility.GetEditorCurve(animClip, curveBinding.path, curveBinding.type, "m_LocalRotation.y"); AnimationCurve curveRZ = AnimationUtility.GetEditorCurve(animClip, curveBinding.path, curveBinding.type, "m_LocalRotation.z"); AnimationCurve curveRW = AnimationUtility.GetEditorCurve(animClip, curveBinding.path, curveBinding.type, "m_LocalRotation.w"); AnimationCurve curvePX = AnimationUtility.GetEditorCurve(animClip, curveBinding.path, curveBinding.type, "m_LocalPosition.x"); AnimationCurve curvePY = AnimationUtility.GetEditorCurve(animClip, curveBinding.path, curveBinding.type, "m_LocalPosition.y"); AnimationCurve curvePZ = AnimationUtility.GetEditorCurve(animClip, curveBinding.path, curveBinding.type, "m_LocalPosition.z"); float curveRX_v = curveRX.Evaluate(second); float curveRY_v = curveRY.Evaluate(second); float curveRZ_v = curveRZ.Evaluate(second); float curveRW_v = curveRW.Evaluate(second); float curvePX_v = curvePX.Evaluate(second); float curvePY_v = curvePY.Evaluate(second); float curvePZ_v = curvePZ.Evaluate(second); Vector3 translation = new Vector3(curvePX_v, curvePY_v, curvePZ_v); Quaternion rotation = new Quaternion(curveRX_v, curveRY_v, curveRZ_v, curveRW_v); NormalizeQuaternion(ref rotation); matrices.Add( Matrix4x4.TRS(translation, rotation, Vector3.one) ); } frame.bones = bones2.ToArray(); frame.matrices = matrices.ToArray(); if (boneAnimation.bonesHierarchyNames == null) { boneAnimation.bonesHierarchyNames = bonesHierarchyNames.ToArray(); } } } // Save as ScriptableObject AssetDatabase.CreateAsset(boneAnimations[0], "Assets/GPUSkinning/Resources/anim0.asset"); AssetDatabase.Refresh(); #else // Read from ScriptableObject directly boneAnimations = new GPUSkinning_BoneAnimation[] { Resources.Load("anim0") as GPUSkinning_BoneAnimation }; foreach (var boneAnimation in boneAnimations) { foreach (var frame in boneAnimation.frames) { int numBones2 = boneAnimation.bonesHierarchyNames.Length; frame.bones = new GPUSkinning_Bone[numBones2]; for (int i = 0; i < numBones2; ++i) { frame.bones[i] = GetBoneByHierarchyName(boneAnimation.bonesHierarchyNames[i]); } } } #endif // Spawn many models if (spawnPoints != null) { List <GPUSkinning_SpawnObject> list = new List <GPUSkinning_SpawnObject>(); for (int i = 0; i < spawnPoints.Length; ++i) { for (int j = 0; j < spawnPoints[i].childCount; ++j) { GPUSkinning_SpawnObject spawnObject = new GPUSkinning_SpawnObject(); list.Add(spawnObject); spawnObject.transform = spawnPoints[i].GetChild(j); spawnObject.mf = spawnObject.transform.gameObject.AddComponent <MeshFilter>(); spawnObject.mr = spawnObject.transform.gameObject.AddComponent <MeshRenderer>(); spawnObject.mr.sharedMaterial = newMtrl; spawnObject.mf.sharedMesh = newMesh; } } spawnObjects = list.ToArray(); } }