void Deactivate() { if (activeObject != null) { activeObject.OnDeactivate.Invoke(); } // To give user visual feedbacks, make the hand opaque as default. if (meshHandRenderMgr != null) { meshHandRenderMgr.FadeIn(); } }
void UpdatePinchState() { GestureName currentGesture = hand.GetGestureName(); bool isClosingFingers = (pinchSpeed < -closingSpeedThresh); bool isOpeningFingers = (pinchSpeed > openingSpeedThresh); if (activeObject != null && activeObject.IsAvailableForPinch() == false && pinchState != PinchState.ObjectInHold) // pinched by the other hand { activeObject = null; pinchState = PinchState.ObjectOutOfReach; } if ((pinchState == PinchState.ObjectOutOfReach) || (pinchState == PinchState.ObjectInReach && !isClosingFingers) || (pinchState == PinchState.ObjectReleased)) { // Iterate all pinchable objects, find the closest available one. PinchableObject closestAvailableObj = null; float minDistance = 1000f; foreach (PinchableObject obj in PinchableObject.instances) { if (obj.IsAvailableForPinch()) { float distance = Vector3.Distance(this.transform.position, obj.transform.position); if (distance < minDistance) { minDistance = distance; closestAvailableObj = obj; } } } // Mark the closest available object as active activeObject = closestAvailableObj; // Check if it is range. bool inReach = (minDistance < pinchEnableDistance); if (activeObject != null) { // To give user visual feedbacks, update the outline color on the active object // based on its current distance to the hand. activeObject.UpdateOutlineColorBasedOnDistance(minDistance); // Reset the outline color (fully transparent) on the last active object if it was different if (prevActiveObject != null && prevActiveObject != activeObject) { prevActiveObject.SetOutlineColorTransparency(0); } // If we are able to pinch the currently active object if (inReach && currentTipDist > pinchEnableTipDistance) { if (pinchState != PinchState.ObjectInReach || activeObject != prevActiveObject) { activeObject.OnGetInReach.Invoke(); pinchState = PinchState.ObjectInReach; } } } // Note, we want to ignore movement (which can cause ObjectInReach state to change to ObjectOutOfReach) // if user is already in the middle of pinching the object if (!inReach && !(pinchState == PinchState.ObjectInReach && isClosingFingers)) { if (pinchState != PinchState.ObjectOutOfReach || activeObject != prevActiveObject) { if (activeObject != null) { activeObject.OnOutOfReach.Invoke(); } pinchState = PinchState.ObjectOutOfReach; } } } if (pinchState == PinchState.ObjectInReach) { if ((currentTipDist < pinchStartTipDistance || currentGesture == GestureName.PinchCloseMRP || currentGesture == GestureName.PinchOpenMRP) && isClosingFingers) { // To give user visual feedbacks, make the hand transparent. if (meshHandRenderMgr != null) { meshHandRenderMgr.DisableHandOutline(); meshHandRenderMgr.FadeOut(); } if (activeObject != null) { activeObject.OnPickUp.Invoke(); // Save the parent transform pinchedObjectParent = activeObject.transform.parent; activeObject.transform.parent = this.transform; activeObject.transform.localPosition = Vector3.zero; // Disable the object for pinch activeObject.SetAvailableForPinch(false); } pinchState = PinchState.ObjectInHold; } } if (pinchState == PinchState.ObjectInHold) { if (currentTipDist > pinchEndTipDistance && isOpeningFingers) { // To give user visual feedbacks, make the hand opaque (default). if (meshHandRenderMgr != null) { meshHandRenderMgr.FadeIn(); } if (activeObject != null) { activeObject.OnRelease.Invoke(); Vector3 velocity = (velocityCalculator != null) ? velocityCalculator.CalculateVelocity() : Vector3.zero; if (Vector3.Magnitude(velocity) > 0) { activeObject.OnThrow.Invoke(velocity); // Enable the object for pinch later activeObject.SetAvailableForPinch(true, activeObject.FlyBackTime()); } else { // Enable the object for pinch right away activeObject.SetAvailableForPinch(true, 0); } // Restore the parent transform activeObject.transform.parent = pinchedObjectParent; } pinchState = PinchState.ObjectReleased; } } //Debug.Log("Pinch state = " + pinchState); // To give user visual feedbacks, highlight hand outline if it is hovering an object, otherwise disable outline. bool isHovering = (pinchState == PinchState.ObjectInReach); if (meshHandRenderMgr != null) { if (isHovering && !isHoveringLastFrame) { meshHandRenderMgr.EnableHandOutline(); } else if (!isHovering && isHoveringLastFrame) { meshHandRenderMgr.DisableHandOutline(); } } isHoveringLastFrame = isHovering; prevActiveObject = activeObject; }
void UpdateGrabState() { GestureName currentGesture = hand.GetGestureName(); bool isClosingFingers = (bendingAngularSpeed > anguarSpeedThresh); bool isOpeningFingers = (bendingAngularSpeed < -anguarSpeedThresh); if (activeObject != null && activeObject.IsAvailableForGrab() == false && grabState != GrabState.ObjectInHold) // grabbed by the other hand { activeObject = null; grabState = GrabState.ObjectOutOfReach; } if ((grabState == GrabState.ObjectOutOfReach) || (grabState == GrabState.ObjectInReach && !isClosingFingers) || (grabState == GrabState.ObjectReleased)) { // Iterate all grabbable objects, find the closest available one. GrabbaleObject closestAvailableObj = null; float minDistance = 1000f; foreach (GrabbaleObject obj in GrabbaleObject.instances) { if (obj.IsAvailableForGrab()) { float distance = Vector3.Distance(this.transform.position, obj.transform.position); if (distance < minDistance) { minDistance = distance; closestAvailableObj = obj; } } } // Mark the closest available object as active activeObject = closestAvailableObj; // Check if it is range. bool inReach = (minDistance < grabEnableDistance); if (activeObject != null && (currentGesture == GestureName.Grab || currentGesture == GestureName.Palm || currentBendingAngle < grabEnableAngle)) { // To give user visual feedbacks, update the outline color on the active object // based on its current distance to the hand. activeObject.UpdateOutlineColorBasedOnDistance(minDistance); // Reset the outline color (fully transparent) on the last active object if it was different if (prevActiveObject != null && prevActiveObject != activeObject) { prevActiveObject.SetOutlineColorTransparency(0); } // If we are close enough to grab the currently active object if (inReach && (grabState != GrabState.ObjectInReach || activeObject != prevActiveObject)) { activeObject.OnGetInReach.Invoke(); grabState = GrabState.ObjectInReach; } } // Note, we want to ignore movement (which can cause ObjectInReach state to change to ObjectOutOfReach) // if user is already in the middle of grabbing the object if (!inReach && !(grabState == GrabState.ObjectInReach && isClosingFingers)) { if (grabState != GrabState.ObjectOutOfReach || activeObject != prevActiveObject) { if (activeObject != null) { activeObject.OnOutOfReach.Invoke(); } grabState = GrabState.ObjectOutOfReach; } } } if (grabState == GrabState.ObjectInReach) { if ((currentBendingAngle > grabStartAngle || currentGesture == GestureName.Fist) && isClosingFingers) { // To give user visual feedbacks, make the hand transparent. if (meshHandRenderMgr != null) { meshHandRenderMgr.DisableHandOutline(); meshHandRenderMgr.FadeOut(); } if (activeObject != null) { activeObject.OnGrab.Invoke(); // Save the parent transform grabbedObjectParent = activeObject.transform.parent; activeObject.transform.parent = this.transform; activeObject.transform.localPosition = Vector3.zero; // Disable the object for grab activeObject.SetAvailableForGrab(false); } grabState = GrabState.ObjectInHold; } } if (grabState == GrabState.ObjectInHold) { if (currentBendingAngle < grabEndAngle && isOpeningFingers) { // To give user visual feedbacks, make the hand opaque (default). if (meshHandRenderMgr != null) { meshHandRenderMgr.FadeIn(); } if (activeObject != null) { activeObject.OnRelease.Invoke(); Vector3 velocity = (velocityCalculator != null) ? velocityCalculator.CalculateVelocity() : Vector3.zero; if (Vector3.Magnitude(velocity) > 0) { activeObject.OnThrow.Invoke(velocity); // Enable the object for grab later activeObject.SetAvailableForGrab(true, activeObject.FlyBackTime()); } else { // Enable the object for grab right away activeObject.SetAvailableForGrab(true, 0); } // Restore the parent transform activeObject.transform.parent = grabbedObjectParent; } grabState = GrabState.ObjectReleased; } } //Debug.Log("Grab state = " + grabState); // To give user visual feedbacks, highlight hand outline if it is hovering an object, otherwise disable outline. bool isHovering = (grabState == GrabState.ObjectInReach); if (meshHandRenderMgr != null) { if (isHovering && !isHoveringLastFrame) { meshHandRenderMgr.EnableHandOutline(); } else if (!isHovering && isHoveringLastFrame) { meshHandRenderMgr.DisableHandOutline(); } } isHoveringLastFrame = isHovering; prevActiveObject = activeObject; }