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;
            }
        }
Example #5
0
        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;
            }
        }
Example #6
0
        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);
        }