public static List <AnimationRig.Joint> GetAvatarJoints(this Avatar avatar) { if (avatar == null) { return(null); } string assetPath = AssetDatabase.GetAssetPath(avatar); GameObject avatarRootObject = AssetDatabase.LoadAssetAtPath(assetPath, typeof(GameObject)) as GameObject; if (avatarRootObject == null) { return(null); } List <AnimationRig.Joint> jointsList = new List <AnimationRig.Joint>(); jointsList.Add(new AnimationRig.Joint() { name = avatarRootObject.transform.name, parentIndex = -1, localTransform = AffineTransform.identity, }); foreach (Transform child in avatarRootObject.transform) { AnimationRig.CollectJointsRecursive(jointsList, child, 0); } return(jointsList); }
void InitWithRigTransforms(AnimationRig targetRig) { animationCurves = new List <CurveInfo>(); jointSamplers = new NativeArray <TransformSampler>(targetRig.NumJoints, Allocator.Persistent); for (int i = 0; i < targetRig.NumJoints; ++i) { jointSamplers[i] = TransformSampler.CreateEmpty(targetRig.Joints[i].localTransform); } }
Preview(Asset asset) { targetRig = AnimationRig.Create(asset.DestinationAvatar); int trajectoryLength = Missing.truncToInt(2.0f * asset.TimeHorizon * asset.SampleRate) + 1; sampleTrajectory = Trajectory.Create(trajectoryLength, Allocator.Persistent); timeHorizon = asset.TimeHorizon; assetSampleRate = asset.SampleRate; trajectoryColor = Binary.TrajectoryFragmentDisplay.CreateOptions().baseColor; }
internal AnimationSampler(AnimationRig targetRig, AnimationClip animationClip) { this.targetRig = targetRig; this.animationClip = animationClip; int numJoints = targetRig.NumJoints; editorAnimation = KeyframeAnimation.Create(this, animationClip); bakedAnimation = null; try { poseSamplePostProcess = new PoseSamplePostProcess(targetRig, animationClip, editorAnimation.JointSamplers[0][0]); } catch (Exception e) { editorAnimation.Dispose(); throw e; } }
internal PoseSamplePostProcess(AnimationRig targetRig, AnimationClip animationClip, AffineTransform clipFirstFrameTrajectory) { bodyJointIndex = targetRig.BodyJointIndex; isRootInTrajectorySpace = animationClip.hasMotionCurves && !animationClip.hasRootCurves; if (!isRootInTrajectorySpace && bodyJointIndex < 0) { throw new Exception($"Animation clip {AssetDatabase.GetAssetPath(animationClip)} requires root bone, please setup root node in avatar {AssetDatabase.GetAssetPath(targetRig.Avatar)}"); } parentIndices = targetRig.GenerateParentIndices(); ModelImporterClipAnimation clipImporter = Utility.GetImporterFromClip(animationClip); applyRootImportOptions = animationClip.hasRootCurves && !animationClip.hasMotionCurves; if (applyRootImportOptions && clipImporter != null) { this.clipFirstFrameTrajectory = clipFirstFrameTrajectory; heightOffset = clipImporter.heightOffset; rotationOffset = clipImporter.rotationOffset; lockRootPositionXZ = clipImporter.lockRootPositionXZ; lockRootHeightY = clipImporter.lockRootHeightY; lockRootRotation = clipImporter.lockRootRotation; keepOriginalPositionY = clipImporter.keepOriginalPositionY; keepOriginalPositionXZ = clipImporter.keepOriginalPositionXZ; keepOriginalOrientation = clipImporter.keepOriginalOrientation; } else { this.clipFirstFrameTrajectory = AffineTransform.identity; heightOffset = 0.0f; rotationOffset = 0.0f; lockRootPositionXZ = false; lockRootHeightY = false; lockRootRotation = false; keepOriginalPositionY = false; keepOriginalPositionXZ = false; keepOriginalOrientation = false; } }
public static TwoBonesIK CreateTwoBonesIK(AnimationRig rig, int rootJointIndex, int midJointIndex, int tipJointIndex, ref NativeArray <AffineTransform> halfStretchedPose) { TwoBonesIK twoBonesIK = new TwoBonesIK { rig = rig }; var avatar = rig.Avatar; bool rootJointFound = false; bool midJointFound = false; bool rootHasParent = false; // gather joints starting from tip, moving upward in the hierarchy until root joint is reached List <int> jointIndicesList = new List <int>(); int jointIndex = tipJointIndex; while (jointIndex >= 0) { jointIndicesList.Add(jointIndex); if (jointIndex == rootJointIndex) { rootJointFound = true; int rootParent = rig.Joints[jointIndex].parentIndex; if (rootParent >= 0) { rootHasParent = true; jointIndicesList.Add(rootParent); } break; } jointIndex = rig.Joints[jointIndex].parentIndex; } if (!rootJointFound) { throw new Exception($"TwoBonesIK error : avatar {avatar.name} joint {rig.Joints[rootJointIndex].name} isn't above {rig.Joints[tipJointIndex].name} in rig hierarchy"); } jointIndicesList.Reverse(); twoBonesIK.jointIndices = jointIndicesList.ToArray(); twoBonesIK.localTransforms = new AffineTransform[twoBonesIK.jointIndices.Length]; twoBonesIK.globalTransforms = new AffineTransform[twoBonesIK.jointIndices.Length]; twoBonesIK.halfStretchedMidRotation = halfStretchedPose[midJointIndex].q; twoBonesIK.rootIndex = rootHasParent ? 1 : 0; for (int i = twoBonesIK.rootIndex + 1; i < twoBonesIK.jointIndices.Length; ++i) { if (twoBonesIK.jointIndices[i] == midJointIndex) { twoBonesIK.midIndex = i; midJointFound = true; break; } } if (!midJointFound) { throw new Exception($"TwoBonesIK error : avatar {avatar.name} joint {rig.Joints[midJointIndex].name} isn't above {rig.Joints[tipJointIndex].name} in rig hierarchy"); } twoBonesIK.tipIndex = twoBonesIK.jointIndices.Length - 1; return(twoBonesIK); }