/// <summary> /// Find the picker's angle of rotation from zero. /// </summary> /// <remarks> /// Once the picker is grasping the pickable object, it will stay on the "surface" of the /// pickable by maintaining a fixed displacement with a constrain point. The constrain point /// is a game object that will rotate together with this one. E.g. it can be the edge of the /// lever. When picker is moved to new position, the position of the new constrain point can /// be found in turn. Picker's angle of rotation can be calculated from the angle that needs /// to rotate from zero deg to the direction from centre of rotation to new constrain point. /// </remarks> /// <param name="picker">The picker that is grasping the object.</param> /// <returns>Picker's angle of rotation from zero.</returns> protected override float GetPickerAngleInRotationAxis(IPicker picker) { PickerDexmo pickerDexmo = picker as PickerDexmo; Transform pickerReference = pickerDexmo == null ? picker.Transform : pickerDexmo.PalmCenter; // We want the picker transform to maintain a fixed displacement in world space with the // constrain point, so when picker transform is moved to a new point, the new // constrain point can be obtained by subtracting the fixed displacement from // the picker transform. Vector3 newConstrainPoint = pickerReference.position - PickerFixedDisplacementWrtConstrainPoint; // Since the object itself is the centre of rotation and will rotate during runtime, // all the directions here is calculated in parent transform's coordinate. // transform.position is the centre of rotation. Find the direction pointing from // centre of rotation to new constrain point position. Vector3 pickerRelativeDirectionInParentCoordinate = Miscellaneous.InverseTransformDirectionInParentCoordinate(transform, newConstrainPoint - transform.position); // Find the angle of rotation from zero reference to the direction connecting the // centre of rotation to new constrain point position. float angle = RotationUtils.AngleInPlane(LocalRotationAxisInParentCoordinate, ZeroReferenceDirectionInParentCoordinate, pickerRelativeDirectionInParentCoordinate); return(angle); }
/// <summary> /// Get this pickable object's current angle of rotation from zero. /// </summary> /// <returns>The current angle of rotation.</returns> private float GetCurrentAngle() { // _zeroReferenceDirection is in local local coordinate, so it will rotate together with // the pickable object, so _zeroReferenceDirection is more like the minute hand in clock // that makes an angle with the zero direction determined by _zeroReferenceDirectionInParentCoordinate. Vector3 currentRotationReferenceInParent = TransformDirectionFromLocalToParent( _zeroReferenceDirection); // Get the angle of rotation from zero in the plane normal to the rotation axis float angle = RotationUtils.AngleInPlane(_localRotationAxisInParentCoordinate, _zeroReferenceDirectionInParentCoordinate, currentRotationReferenceInParent); return(angle); }
/// <summary> /// Find the target angle of rotation from zero based on current picker's rotation. /// </summary> /// <remarks> /// The picker will maintain a fixed relative rotation with knob since the start of /// grasping, so given the current rotation of picker, we can compute the new target /// rotation of knob. /// </remarks> /// <param name="picker">The picker that is grasping it.</param> /// <returns>Target angle of rotation of knob based on the picker's rotation.</returns> protected override float GetPickerAngleInRotationAxis(IPicker picker) { PickerDexmo pickerDexmo = picker as PickerDexmo; Transform pickerReference = pickerDexmo == null ? picker.Transform : pickerDexmo.PalmCenter; // Calculate the target rotation of knob based on current rotation of the picker Quaternion newKnobTargetRotation = pickerReference.rotation * Quaternion.Inverse(_pickerRelativeRotationWrtKnob); // Convert the current angle reference from world coordinate to parent transform's // coordinate. Angle reference is the direction that indicates the current angle // of rotation from zero. Vector3 newAngleReferenceDirectionInWorld = newKnobTargetRotation * ZeroReferenceDirection; Vector3 pickerRelativeDirectionInParentCoordinate = Miscellaneous.InverseTransformDirectionInParentCoordinate(transform, newAngleReferenceDirectionInWorld); // Find the target angle of rotation from zero in the plane normal to rotation axis float angle = RotationUtils.AngleInPlane(LocalRotationAxisInParentCoordinate, ZeroReferenceDirectionInParentCoordinate, pickerRelativeDirectionInParentCoordinate); return(angle); }