示例#1
0
        protected override void Apply(HandDataAsset handDataAsset)
        {
            if (!handDataAsset.IsTracked)
            {
                return;
            }

            Profiler.BeginSample($"{nameof(OneEuroFilterRotationHand)}." +
                                 $"{nameof(OneEuroFilterRotationHand.Apply)}");

            if (Time.frameCount > _lastFrameUpdated)
            {
                _lastFrameUpdated = Time.frameCount;
                ApplyFilters(handDataAsset);
                _lastFiltered.CopyFrom(handDataAsset);
            }
            else
            {
                handDataAsset.CopyFrom(_lastFiltered);
            }

            handDataAsset.RootPoseOrigin = PoseOrigin.FilteredTrackedPose;

            Profiler.EndSample();
        }
        protected override void Apply(HandDataAsset data)
        {
            if (!data.IsDataValid)
            {
                return;
            }

            if (_capturedDataVersion != ModifyDataFromSource.CurrentDataVersion)
            {
                _capturedDataVersion = ModifyDataFromSource.CurrentDataVersion;

                _historyIndex = (_historyIndex + 1) % _historyLength;
                for (int i = 0; i < _jointHistory.Length; i++)
                {
                    _jointHistory[i][_historyIndex] = data.Joints[i];
                }
            }

            _historyOffset = Mathf.Clamp(_historyOffset, 0, _historyLength);
            int index = (_historyIndex + _historyLength - _historyOffset) % _historyLength;

            for (int i = 0; i < _jointHistory.Length; i++)
            {
                data.Joints[i] = _jointHistory[i][index];
            }
        }
示例#3
0
 private void UpdateAllLocalPoses(HandDataAsset data)
 {
     for (int i = 0; i < Constants.NUM_HAND_JOINTS; ++i)
     {
         HandSkeletonJoint originalJoint = _originalJoints[i];
         _localPoses[i].position = originalJoint.pose.position;
         _localPoses[i].rotation = data.Joints[i];
     }
 }
示例#4
0
        protected override void Apply(HandDataAsset data)
        {
            Pose rootToPointer = PoseUtils.RelativeOffset(data.PointerPose, data.Root);

            rootToPointer.position = (rootToPointer.position / data.HandScale) * _scale;
            PoseUtils.Multiply(data.Root, rootToPointer, ref data.PointerPose);

            data.HandScale = _scale;
        }
示例#5
0
        protected override void Start()
        {
            base.Start();

            InitFingerJointFilters();

            _lastFrameUpdated = 0;
            _lastFiltered     = new HandDataAsset();
            _wristFilter      = OneEuroFilter.CreateQuaternion();
        }
示例#6
0
 public void Update(HandDataAsset data, int dataVersion)
 {
     _dirtyWorldJoints = _dirtyWristJoints = (1 << (int)HandJointId.HandEnd) - 1; //set all dirty
     if (!data.IsDataValidAndConnected)
     {
         return;
     }
     LocalDataVersion = dataVersion;
     UpdateAllLocalPoses(data);
 }
示例#7
0
        private void ApplyFilters(HandDataAsset handDataAsset)
        {
            if (_wristFilterEnabled)
            {
                Pose rootPose = handDataAsset.Root;
                _wristFilter.SetProperties(_wristFilterProperties);
                rootPose.rotation  = _wristFilter.Step(rootPose.rotation, Time.fixedDeltaTime);
                handDataAsset.Root = rootPose;
            }

            if (_fingerFiltersEnabled)
            {
                foreach (var joint in _fingerJointFilters)
                {
                    joint.Filter.SetProperties(_fingerFilterProperties);
                    handDataAsset.Joints[(int)joint.JointId] =
                        joint.Filter.Step(handDataAsset.Joints[(int)joint.JointId], Time.fixedDeltaTime);
                }
            }
        }
示例#8
0
        protected override void Apply(HandDataAsset handDataAsset)
        {
            if (!handDataAsset.IsTracked)
            {
                return;
            }

            Profiler.BeginSample($"{nameof(OneEuroFilterPositionHand)}." +
                                 $"{nameof(OneEuroFilterPositionHand.Apply)}");

            if (Time.frameCount > _lastFrameUpdated)
            {
                _lastFrameUpdated = Time.frameCount;
                _lastSmoothedPose = ApplyFilter(handDataAsset.Root);
            }

            handDataAsset.Root           = _lastSmoothedPose;
            handDataAsset.RootPoseOrigin = PoseOrigin.FilteredTrackedPose;

            Profiler.EndSample();
        }
示例#9
0
        protected override void Apply(HandDataAsset data)
        {
            if (!data.IsDataValid || !data.IsTracked || !data.IsHighConfidence)
            {
                data.IsConnected    = false;
                data.RootPoseOrigin = PoseOrigin.None;
                _hasConnectedData   = false;
                return;
            }

            UpdateRequired.Invoke();
            _lastStates.CopyFrom(data);

            if (!_hasConnectedData)
            {
                _constrainedWristPose.CopyFrom(data.Root);
                _hasConnectedData = true;
            }

            UpdateJointsRotation(data);
            UpdateRootPose(ref data.Root);

            data.RootPoseOrigin = PoseOrigin.SyntheticPose;
        }
示例#10
0
        /// <summary>
        /// Updates the rotation of the joints in the hand
        /// using the visual provided values. Sometimes this
        /// might require lerping between the tracked pose
        /// and the provided ones to improve the movement of the fingers
        /// without worrying about when the overwrite values were written.
        ///
        /// During this update the modifier also ensures that fingers that disallow
        /// some movement (locked or constrained) have their values properly set, and
        /// when there is an unlock event the finger values are smoothly animated back to
        /// their tracked rotations.
        /// </summary>
        /// <param name="data">The entire hand data structure to read and write the joints rotations from</param>
        private void UpdateJointsRotation(HandDataAsset data)
        {
            float extraRotationAllowance = 0f;

            Quaternion[] jointRotations = data.Joints;

            for (int i = 0; i < FingersMetadata.HAND_JOINT_IDS.Length; ++i)
            {
                JointFreedom freedomLevel    = _jointsFreedomLevels[i];
                Quaternion   desiredRotation = _desiredJointsRotation[i];
                float        overrideFactor  = _jointsOverrideFactor[i];
                int          rawJointIndex   = (int)FingersMetadata.HAND_JOINT_IDS[i];

                if (freedomLevel == JointFreedom.Free)
                {
                    //nothing to do, we move the finger freely
                }
                else if (freedomLevel == JointFreedom.Locked)
                {
                    jointRotations[rawJointIndex] = Quaternion.Slerp(
                        jointRotations[rawJointIndex],
                        desiredRotation,
                        overrideFactor);
                }
                else if (freedomLevel == JointFreedom.Constrained)
                {
                    bool jointCanSpread = false;
                    if (FingersMetadata.HAND_JOINT_CAN_SPREAD[i])
                    {
                        jointCanSpread         = true;
                        extraRotationAllowance = 0f;
                    }

                    Quaternion maxRotation = desiredRotation * Quaternion.Euler(0f, 0f, -90f * extraRotationAllowance);

                    float overRotation = OverFlex(jointRotations[rawJointIndex], maxRotation);
                    extraRotationAllowance = Mathf.Max(extraRotationAllowance, overRotation);

                    if (overRotation < 0f)
                    {
                        jointRotations[rawJointIndex] = Quaternion.Slerp(
                            jointRotations[rawJointIndex],
                            maxRotation,
                            overrideFactor);
                    }
                    else if (jointCanSpread)
                    {
                        Quaternion trackedRotation = jointRotations[rawJointIndex];
                        float      spreadAngle     = Vector3.SignedAngle(
                            trackedRotation * Vector3.forward,
                            maxRotation * Vector3.forward,
                            trackedRotation * Vector3.up);

                        float spreadFactor = 1f - Mathf.Clamp01(overRotation * _spreadAllowance);
                        trackedRotation = trackedRotation * Quaternion.Euler(0f, spreadAngle * spreadFactor, 0f);
                        jointRotations[rawJointIndex] = trackedRotation;
                    }
                }

                float smoothFactor = _jointsFreedomLevels[i] == JointFreedom.Free ?
                                     _jointUnlockProgressCurves[i].Progress()
                    : _jointLockProgressCurves[i].Progress();

                jointRotations[rawJointIndex] = Quaternion.Slerp(
                    _constrainedJointRotations[i],
                    jointRotations[rawJointIndex],
                    smoothFactor);

                _lastSyntheticRotation[i] = jointRotations[rawJointIndex];
            }
        }