/// <summary> /// This function is called for every FixedUpdate cycle. It moves the snapper /// position towards the target position, but allows it to rotate in the plane /// normal to the knob's rotation axis, which is assumed to be the local "up" direction /// of the snapping rotation reference transform. /// </summary> /// <param name="snapper">The snapper in snapping region.</param> public override void OnSnappedStay(ISnapper snapper) { SnapperDexmo snapperDexmo = snapper as SnapperDexmo; if (snapperDexmo == null) { base.OnSnappedStay(snapper); return; } Transform positionReference = GetSnappingPositionReference(snapper); Transform rotationReference = GetSnappingRotationReference(snapper); if (positionReference == null || rotationReference == null) { return; } Transform palmCenterTransform = snapperDexmo.PalmCenter; // Find the deltaRotation in world needed to align palmCenterTransform to rotationReference // in only y-axis (i.e. "up" direction). Quaternion deltaRotation = Quaternion.FromToRotation(palmCenterTransform.up, rotationReference.up); Quaternion palmCenterTargetRotation = deltaRotation * palmCenterTransform.rotation; // Now palm center's local "up" direction will coincide with rotationReference.up, // and can rotate around the "up" axis. // Move the entire hand root transform to the target position and rotation calculated from // the target position and rotation of the palm center. Miscellaneous.MoveParentTransformGivenChildTransform( snapperDexmo.HandRootTransform, palmCenterTransform, positionReference.position, palmCenterTargetRotation, HandRootPositionRelativeToPalmCenter, HandRootRotationRelativeToPalmCenter); }
/// <summary> /// Get the snapping rotation reference for hand models. /// </summary> /// <param name="snapper">The snapper in snapping region.</param> /// <returns>Transform of snapping position reference..</returns> public override Transform GetSnappingRotationReference(ISnapper snapper) { SnapperDexmo snapperDexmo = snapper as SnapperDexmo; if (snapperDexmo == null) { return(base.GetSnappingRotationReference(snapper)); } return(snapperDexmo.IsRight ? SnappingRotationReferenceList[0] : SnappingRotationReferenceList[1]); }
/// <summary> /// Check if the snapper is still moving towards the target snapping position. /// </summary> /// <remarks> /// The snapper is in transition when the distance between the snapper and /// the target snapping position is greater than _snappingTransitionDistanceMin. /// </remarks> /// <param name="snapper">The snapper that is in snapping region.</param> /// <returns>True if the snapper is still moving towards the target snapping /// position.</returns> public virtual bool CheckInSnappingTransition(ISnapper snapper) { Transform positionReference = GetSnappingPositionReference(snapper); if (positionReference == null) { return(false); } SnapperDexmo snapperDexmo = snapper as SnapperDexmo; Vector3 snapperPosition = snapperDexmo == null ? snapper.Transform.position : snapperDexmo.PalmCenter.position; float dist = Vector3.Distance(positionReference.position, snapperPosition); bool inSnappingTransition = dist >= _snappingTransitionDistanceMin; return(inSnappingTransition); }
/// <summary> /// This function will be called for every FixedUpdate cycle when snapper /// is in snapping region. It fixes the snapper's rotation to that of /// snapping rotation reference and allows the snapper to move between /// start position constraint and end position constraint. /// </summary> /// <param name="snapper">The snapper in the snapping region.</param> public override void OnSnappedStay(ISnapper snapper) { SnapperDexmo snapperDexmo = snapper as SnapperDexmo; if (snapperDexmo == null) { base.OnSnappedStay(snapper); return; } Transform positionReference = GetSnappingPositionReference(snapper); // Adjust snapping position according to the current position of the snapper. // Snapping position will only move in a linear section between start point and // end point. if (positionReference == null) { return; } float vectorProjectionValueNormalized = Miscellaneous.GetVectorProjectionValueNormalized( _startPositionConstraintTransform.position, _endPositionConstraintTransform.position, snapperDexmo.PalmCenter.position); positionReference.position = Vector3.Lerp( _startPositionConstraintTransform.position, _endPositionConstraintTransform.position, vectorProjectionValueNormalized); Transform rotationReference = GetSnappingRotationReference(snapper); if (rotationReference == null) { return; } // Move the entire hand root transform to the target position and rotation calculated from // the target position and rotation of the palm center. Miscellaneous.MoveParentTransformGivenChildTransform( snapperDexmo.HandRootTransform, snapperDexmo.PalmCenter, positionReference.position, rotationReference.rotation, HandRootPositionRelativeToPalmCenter, HandRootRotationRelativeToPalmCenter); }
/// <summary> /// This function will be called when snapper just enters the snapping /// region. It sets some variables for later use. /// </summary> /// <param name="snapper">The snapper that just enters the snapping region.</param> public override void OnSnappedEnter(ISnapper snapper) { SnapperDexmo snapperDexmo = snapper as SnapperDexmo; if (snapperDexmo == null) { base.OnSnappedEnter(snapper); return; } Transform handRootTransform = snapperDexmo.HandRootTransform; Transform palmCenter = snapperDexmo.PalmCenter; if (handRootTransform != null) { HandRootPositionRelativeToPalmCenter = palmCenter.InverseTransformPoint( handRootTransform.position); HandRootRotationRelativeToPalmCenter = Quaternion.Inverse(palmCenter.rotation) * handRootTransform.rotation; } }
/// <summary> /// Check if the snapper is still moving towards the target position. /// </summary> /// <remarks> /// The snapper is in transition when the distance between the snapper and /// the target snapping position is greater than _snappingTransitionDistanceMin. /// </remarks> /// <param name="snapper">The snapper in the snapping region.</param> /// <returns>True if snapper is still moving towards the target position.</returns> public override bool CheckInSnappingTransition(ISnapper snapper) { SnapperDexmo snapperDexmo = snapper as SnapperDexmo; if (snapperDexmo == null) { return(base.CheckInSnappingTransition(snapper)); } Transform positionReference = GetSnappingPositionReference(snapper); if (positionReference == null) { return(false); } float dist = Vector3.Distance(positionReference.position, snapperDexmo.PalmCenter.position); bool inSnappingTransition = dist >= SnappingTransitionDistanceMin; return(inSnappingTransition); }
/// <summary> /// This function will be called for every FixedUpdate cycle when snapper is /// in the snapping region. It finds the target snapping position and rotation /// for the hand model and move the hand towards it. /// </summary> /// <param name="snapper">The snapper in the snapping region.</param> public override void OnSnappedStay(ISnapper snapper) { SnapperDexmo snapperDexmo = snapper as SnapperDexmo; if (snapperDexmo == null) { base.OnSnappedStay(snapper); return; } Transform positionReference = GetSnappingPositionReference(snapper); Transform rotationReference = GetSnappingRotationReference(snapper); if (positionReference == null || rotationReference == null) { return; } Miscellaneous.MoveParentTransformGivenChildTransform( snapperDexmo.HandRootTransform, snapperDexmo.PalmCenter, positionReference.position, rotationReference.rotation, HandRootPositionRelativeToPalmCenter, HandRootRotationRelativeToPalmCenter); }