public override Tuple <Vector3, Quaternion, Vector3> TwoDevicePartUpdate(Func <Vector3, Vector3> scaleConstraint) { Vector3 scale = targetTransform.localScale; if (scaleLogic != null) { scale = scaleLogic.UpdateMap(eventDataDic.Values.Select(item => item.Position3D).ToArray()); } scale = scaleConstraint(scale); Quaternion rotation = targetTransform.rotation; if (rotateLogic != null) { rotation = rotateLogic.Update(eventDataDic.Values.Select(item => item.Position3D).ToArray(), rotation); } int count = 0; foreach (SCPointEventData eventDataItem in eventDataDic.Values) { position3DPoses[count].position = eventDataItem.Position3D; position3DPoses[count].rotation = Quaternion.identity;//handTipTransformArray[count].rotation; count++; } SCPose pointerCentroidPose = GetHandTipPointCentroid(position3DPoses); Vector3 position = moveLogic.Update(pointerCentroidPose, rotation, scale, true); return(new Tuple <Vector3, Quaternion, Vector3>(position, rotation, scale)); }
public override void OneDevicePartInit(Dictionary <InputDevicePartType, SCPointEventData> eventDataDic, Transform targetTransform, MoveLogic moveLogic, RotateLogic rotateLogic, ScaleLogic scaleLogic) { base.OneDevicePartInit(eventDataDic, targetTransform, moveLogic, rotateLogic, scaleLogic); this.eventData = this.eventDataDic.Values.ToArray()[0]; pointerPose = new SCPose(Vector3.zero, Quaternion.identity); Vector3 grabPosition = Vector3.zero; pointerPose.position = this.eventData.Position3D; pointerPose.rotation = Quaternion.identity; grabPosition = this.eventData.Position3D; moveLogic.Setup(pointerPose, grabPosition, targetTransform, targetTransform.localScale); }
public override void TwoDevicePartInit(Dictionary <InputDevicePartType, SCPointEventData> eventDataDic, Transform targetTransform, MoveLogic moveLogic, RotateLogic rotateLogic, ScaleLogic scaleLogic) { base.TwoDevicePartInit(eventDataDic, targetTransform, moveLogic, rotateLogic, scaleLogic); if (handTipTransformDic == null) { handTipTransformDic = new Dictionary <InputDevicePartType, Transform>(); } handTipTransformDic.Clear(); if (position3DDic == null) { position3DDic = new Dictionary <InputDevicePartType, Vector3>(); } position3DDic.Clear(); foreach (var eventData in eventDataDic) { InputDeviceHandPart inputDeviceHandPart = eventData.Value.inputDevicePartBase as InputDeviceHandPart; ModelHand modelHand = inputDeviceHandPart.inputDeviceHandPartUI.modelHand; Transform tipTransform = modelHand.ActiveHandModel.GetJointTransform(FINGER.forefinger, JOINT.One).transform; handTipTransformDic.Add(eventData.Key, tipTransform); position3DDic.Add(eventData.Key, eventData.Value.Position3D); } handTipTransformArray = handTipTransformDic.Values.ToArray(); if (scaleLogic != null) { scaleLogic.Setup(handTipTransformArray, targetTransform); } if (rotateLogic != null) { rotateLogic.Setup(handTipTransformArray, targetTransform); } int count = 0; foreach (SCPointEventData eventDataItem in eventDataDic.Values) { position3DPoses[count] = new SCPose(eventDataItem.Position3D, handTipTransformArray[count].rotation); count++; } SCPose pointerCentroidPose = GetHandTipPointCentroid(position3DPoses); Vector3 grabCentroid = GetRaycastPointCentroid(position3DDic.Values.ToArray()); moveLogic.Setup(pointerCentroidPose, grabCentroid, targetTransform, targetTransform.localScale); }
/// <summary> /// Setup function /// </summary> public void Setup(SCPose pointerCentroidPose, Vector3 grabCentroid, Transform objectPose, Vector3 objectScale) { pointerRefDistance = GetDistanceToBody(pointerCentroidPose); pointerPosIndependentOfHead = pointerRefDistance != 0; Quaternion worldToPointerRotation = Quaternion.Inverse(pointerCentroidPose.rotation); pointerLocalGrabPoint = worldToPointerRotation * (grabCentroid - pointerCentroidPose.position); objectLocalGrabPoint = Quaternion.Inverse(objectPose.rotation) * (grabCentroid - objectPose.position); objectLocalGrabPoint = Vector3.Scale(objectLocalGrabPoint, new Vector3(1f / objectScale.x, 1f / objectScale.y, 1f / objectScale.z)); grabToObject = objectPose.position - grabCentroid; }
private float GetDistanceToBody(SCPose pointerCentroidPose) { // The body is treated as a ray, parallel to the y-axis, where the start is head position. // This means that moving your hand down such that is the same distance from the body will // not cause the manipulated object to move further away from your hand. However, when you // move your hand upward, away from your head, the manipulated object will be pushed away. if (pointerCentroidPose.position.y > SvrManager.Instance.head.transform.position.y) { return(Vector3.Distance(pointerCentroidPose.position, SvrManager.Instance.head.transform.position)); } else { Vector2 headPosXZ = new Vector2(SvrManager.Instance.head.transform.position.x, SvrManager.Instance.head.transform.position.z); Vector2 pointerPosXZ = new Vector2(pointerCentroidPose.position.x, pointerCentroidPose.position.z); return(Vector2.Distance(pointerPosXZ, headPosXZ)); } }
public override void TwoDevicePartInit(Dictionary <InputDevicePartType, SCPointEventData> eventDataDic, Transform targetTransform, MoveLogic moveLogic, RotateLogic rotateLogic, ScaleLogic scaleLogic) { base.TwoDevicePartInit(eventDataDic, targetTransform, moveLogic, rotateLogic, scaleLogic); if (position3DDic == null) { position3DDic = new Dictionary <InputDevicePartType, Vector3>(); } position3DDic.Clear(); foreach (var eventData in eventDataDic) { position3DDic.Add(eventData.Key, eventData.Value.Position3D); } if (scaleLogic != null) { scaleLogic.Setup(eventDataDic.Values.Select(item => item.Position3D).ToArray(), targetTransform); } if (rotateLogic != null) { rotateLogic.Setup(eventDataDic.Values.Select(item => item.Position3D).ToArray(), targetTransform); } int count = 0; foreach (SCPointEventData eventDataItem in eventDataDic.Values) { position3DPoses[count] = new SCPose(eventDataItem.Position3D, Quaternion.identity); count++; } SCPose pointerCentroidPose = GetHandTipPointCentroid(position3DPoses); Vector3 grabCentroid = GetRaycastPointCentroid(position3DDic.Values.ToArray()); moveLogic.Setup(pointerCentroidPose, grabCentroid, targetTransform, targetTransform.localScale); }
/// <summary> /// Update the position based on input. /// </summary> /// <returns>A Vector3 describing the desired position</returns> public Vector3 Update(SCPose pointerCentroidPose, Quaternion objectRotation, Vector3 objectScale, bool usePointerRotation) { float distanceRatio = 1.0f; if (pointerPosIndependentOfHead) { // Compute how far away the object should be based on the ratio of the current to original hand distance float currentHandDistance = GetDistanceToBody(pointerCentroidPose); distanceRatio = currentHandDistance / pointerRefDistance; } if (usePointerRotation) { Vector3 scaledGrabToObject = Vector3.Scale(objectLocalGrabPoint, objectScale); Vector3 adjustedPointerToGrab = (pointerLocalGrabPoint * distanceRatio); adjustedPointerToGrab = pointerCentroidPose.rotation * adjustedPointerToGrab; return(adjustedPointerToGrab - objectRotation * scaledGrabToObject + pointerCentroidPose.position); } else { return(pointerCentroidPose.position + (pointerCentroidPose.rotation * pointerLocalGrabPoint + grabToObject) * distanceRatio); } }