예제 #1
0
    public bool detectShoot() //returns true when shoot gesture is detected
    {
        switch (_curShootState)
        {
        case shootState.NORM:
            if (_handRightRel.z > _shootDetZ && _handLeftRel.z > _shootDetZ)
            //if ((handRightRel.z > shootDetZ && handLeftRel.z < shootDetZ) || (handRightRel.z < shootDetZ && handLeftRel.z > shootDetZ))
            {
                _curShootState = shootState.SHOOT;
                _curHandState  = handState.MID;
                _maxRotY       = 0;
                //Debug.Log("PEEEEEEEEEEEEEEEEEEEEEEEEEEWWWWWWWWWWW");
                return(true);
            }
            break;

        case shootState.SHOOT:
            if (_handRightRel.z < _shootBackDetZ && _handLeftRel.z < _shootBackDetZ)
            {
                _curShootState = shootState.NORM;
            }
            break;

        default: Debug.LogWarning("detectShoot no STATE"); break;
        }
        return(false);
    }
예제 #2
0
 void Init()
 {
     trackedObj = GetComponent <SteamVR_TrackedObject>();
     held       = false;
     inHandItem = null;
     //OpenHand;
     if (handModel != null && !handModel.activeInHierarchy)
     {
         handModel.SetActive(true);
     }
     stateOfHand = handState.OPEN;
     return;
 }
예제 #3
0
    public float detectFlap() //returns a float between 0 and 1 when flap is detected(1frame), else 0
    {
        if (_handRightRel.z > _handDetZ && Mathf.Abs(_handRightRel.x - _handLeftRel.x) < _handDetDistX)
        {
            _maxRotY = 0;
            return(0.0f);
        }
        float avg = (_shoulderRightRotY + _shoulderLeftRotY) / 2;

        switch (_curHandState)
        {
        case handState.UP:
            if (avg > _maxRotY)
            {
                _maxRotY = avg;
            }
            if (_shoulderRightRotY < _detRotUpY && _shoulderLeftRotY < _detRotUpY)
            {
                _curHandState = handState.MID;
            }
            break;

        case handState.DOWN:
            if (_shoulderRightRotY > _detRotDownY && _shoulderLeftRotY > _detRotDownY)
            {
                _curHandState = handState.MID;
            }
            break;

        case handState.MID:     //to do handle start flap
            if (_shoulderRightRotY > _detRotUpY && _shoulderLeftRotY > _detRotUpY)
            {
                _curHandState = handState.UP;
            }
            else if (_shoulderRightRotY < _detRotDownY && _shoulderLeftRotY < _detRotDownY)
            {
                //Debug.Log("Flap: " + _maxRotY);
                _curHandState = handState.DOWN;
                float temp = _maxRotY;
                _maxRotY = 0;
                if (temp != 0)
                {
                    return(temp / 90f);
                }
            }
            break;

        default: Debug.LogWarning("detectFlap no STATE"); break;
        }
        return(0);
    }
예제 #4
0
    public override string GetMark()
    {
        // if detect hands change state machine.
        //Debug.Log(currDirection);

        if (handTrackingValue != null && handTrackingValue.PalmDetections != null && handTrackingValue.PalmDetections.Count > 0)
        {
            // blue color one...

            float width  = (float)handTrackingValue.PalmDetections[0].LocationData.RelativeBoundingBox.Width;
            float height = (float)handTrackingValue.PalmDetections[0].LocationData.RelativeBoundingBox.Height;
            // center of the X and Y
            float currX = width / 2 + (float)handTrackingValue.PalmDetections[0].LocationData.RelativeBoundingBox.Xmin;
            float currY = height / 2 + (float)handTrackingValue.PalmDetections[0].LocationData.RelativeBoundingBox.Ymin;

            // the filter to remove noise rect...
            if (width >= noise_radio_ratio && height >= noise_radio_ratio)
            {
                // send landmark here:
                if (handTrackingValue.HandLandmarkLists != null && handTrackingValue.HandLandmarkLists.Count > 0)
                {
                    NormalizedLandmarkList landmarks = handTrackingValue.HandLandmarkLists[0];
                    for (int i = 0; i < landmarks.Landmark.Count; i++)
                    {
                        float tempX, tempY, tempZ;
                        tempX = landmarks.Landmark[i].X;
                        tempY = landmarks.Landmark[i].Y;
                        tempZ = landmarks.Landmark[i].Z;
                        string temp = handsLandmarkMessage + "X=&" + tempX + "Y=&" + tempY + "Z=&" + tempZ;
                        MessageMgr.GetIns().Dispatch("HandMessage", temp);
                    }
                    //Debug.Log(landmarks.Landmark[0].X + "  ,  " + landmarks.Landmark[0].Y);
                }

                if (currState == handState.outScreen)
                {
                    /*
                     *   outScreen state.
                     *   once we detect the hand show in screen, There will be two situation,
                     *   1. first time came into the screen.
                     *   2. the hand left screen because of the move command..
                     *   For the first situation, We set a 3s frozon time,( just change the handState to move. and set time);
                     *   For the second situation. We should not change the original time,
                     *   because it's an instant state, we don't need to update location data, the location will be modified inside move state.
                     *
                     *   by combining this two situations, we need set a relative small time, (say frozen_time/2) to fit the both cases.
                     */

                    currState  = handState.move;
                    originTime = Time.time - freeze_time / 2;
                }
                else if (currState == handState.move)
                {
                    /*
                     *
                     *   move state
                     *   we set a frozon time, within it the program won't detect any move you've down.
                     *   but we will track your current position.
                     *   Time.time return current program running time.  1.0000s,  2.38491s......
                     */

                    originX = currX;
                    originY = currY;
                    if ((Time.time - originTime) > freeze_time)
                    {
                        // Frozon time end, change state to idle, ready to detect new action, Sync the time to current time.
                        currState     = handState.idle;
                        originTime    = Time.time;
                        currDirection = moveDirection.direction_idle;
                    }
                    else
                    {
                        // Frozon time, do nothing here..
                    }
                }
                else if (currState == handState.idle)
                {
                    /*
                     *
                     *   idle state
                     *   In this state, we detect hand shape instantly, (hand spread out, fist)
                     *   And we are ready to detect hand move direction (left, right, up, down)
                     *   If we detect a long range move, we change state to idle, change hand position to move direction, and start frozon time.
                     *
                     */


                    // detect hand shape by calculate vector.

                    if (handTrackingValue != null && handTrackingValue.HandLandmarkLists != null && handTrackingValue.HandLandmarkLists.Count > 0)
                    {
                        NormalizedLandmarkList landmarks = handTrackingValue.HandLandmarkLists[0];
                        Vector2[] cordinates             = new Vector2[landmarks.Landmark.Count];
                        for (int i = 0; i < cordinates.Length; i++)
                        {
                            cordinates[i] = new Vector2(landmarks.Landmark[i].X, landmarks.Landmark[i].Y);
                        }
                        Vector2 vector68   = cordinates[8] - cordinates[6];
                        Vector2 vector56   = cordinates[6] - cordinates[5];
                        Vector2 vector1012 = cordinates[12] - cordinates[10];
                        Vector2 vector910  = cordinates[10] - cordinates[9];
                        Vector2 vector1416 = cordinates[16] - cordinates[14];
                        Vector2 vector1314 = cordinates[14] - cordinates[13];
                        Vector2 vector1820 = cordinates[20] - cordinates[18];
                        Vector2 vector1718 = cordinates[18] - cordinates[17];

                        // the angle between some knuckles.

                        float angle_index  = Vector2.Angle(vector68, vector56);
                        float angle_middle = Vector2.Angle(vector910, vector1012);
                        float angle_ring   = Vector2.Angle(vector1314, vector1416);
                        float angle_pinky  = Vector2.Angle(vector1718, vector1820);

                        if (angle_index <= hand_spread_out_angle && angle_middle <= hand_spread_out_angle &&
                            angle_ring <= hand_spread_out_angle && angle_pinky <= hand_spread_out_angle)
                        {
                            //Debug.Log("finger_spread_out");
                            currShape = handShape.finger_spread_out;
                        }
                        else if (angle_index >= fist_angle && angle_middle >= fist_angle &&
                                 angle_ring >= fist_angle && angle_pinky >= fist_angle)
                        {
                            //Debug.Log("fist");
                            currShape = handShape.fist;
                        }
                        else
                        {
                            // none shape
                            currShape = handShape.none;
                        }
                    }


                    // calculate hand move direction.
                    float diffX = currX - originX;
                    float diffY = currY - originY;
                    if (Mathf.Abs(diffX) > 0.15 || Mathf.Abs(originY - currY) > 0.15)
                    {
                        currState  = handState.move;
                        originX    = currX;
                        originY    = currY;
                        originTime = Time.time;

                        // define which derection it move...
                        // first we just compare diff scale regrad horizontal and vertical...
                        if (Mathf.Pow(diffX, 2) - Mathf.Pow(diffY, 2) > 0)
                        {
                            // x is larger.
                            if (diffX > 0)
                            {
                                currDirection = moveDirection.right;
                            }
                            else
                            {
                                currDirection = moveDirection.left;
                            }
                        }
                        else
                        {
                            if (diffY > 0)
                            {
                                currDirection = moveDirection.down;
                            }
                            else
                            {
                                currDirection = moveDirection.up;
                            }
                        }
                    }
                    string temp = handShapeDirectionMessage + "Gesture=&" + currShape + "Direction=&" + currDirection;
                    MessageMgr.GetIns().Dispatch("HandMessage", temp);
                    Debug.Log(currShape + "  ,  " + currDirection);
                }
            }
        }
        else
        {
            currState = handState.outScreen;
        }
        return(null);
    }
예제 #5
0
    void Update()
    {
        //StartCoroutine(CheckAngle());
        if (held)
        {
            //Close hand
            stateOfHand = handState.CLOSED;

            if (inHandItem == null)
            {
                //Open hand
                stateOfHand = handState.OPEN;
                inHandItem  = null;
                if (handModel != null && !handModel.activeInHierarchy)
                {
                    handModel.SetActive(true);
                }
                held = false;
            }
        }
        if ((grabType == typeOfAction.TRIGGER_TO_GRAB && controller.GetPressDown(triggerButton)) || (grabType == typeOfAction.TOUCH_TO_GRAB))
        {
            float min = float.MaxValue;
            float distance;
            //Close Hand
            stateOfHand = handState.CLOSED;

            foreach (InteractableItem obj in objects)//Pick the closest object my controller is by if there are multiple objects near me with interactable item scripts attached
            {
                if (obj != null)
                {
                    distance = (obj.transform.position - transform.position).sqrMagnitude;

                    if (distance < min)
                    {
                        min         = distance;
                        closestItem = obj;
                    }
                    if (inHandItem != closestItem)
                    {
                        if (closestItem != null && inHandItem != null)
                        {
                            if (inHandItem.IsInteracting() && inHandItem.attachedWand != this)//If we are already interacting
                            {
                                inHandItem.EndInteraction(this);
                                held = false;
                            }
                            if (closestItem != null && !closestItem.IsInteracting() && !held)
                            {
                                inHandItem = closestItem;
                                inHandItem.BeginInteraction(this);
                                held = true;
                            }
                        }
                        else if (closestItem != null)
                        {
                            inHandItem = closestItem;
                            inHandItem.BeginInteraction(this);
                            held = true;
                        }
                    }
                }
                else
                {
                    objects.RemoveWhere(ShouldRemove => obj);
                }
            }

            if (handModel != null && handModel.activeInHierarchy)
            {
                handModel.SetActive(false);
            }
        }

        if ((controller.GetPressUp(triggerButton) && grabType == typeOfAction.TRIGGER_TO_GRAB) && inHandItem != null)//let go of item
        {
            held = false;
            //Open hand
            stateOfHand = handState.OPEN;

            if (handModel != null && !handModel.activeInHierarchy)
            {
                handModel.SetActive(true);
            }

            inHandItem.EndInteraction(this);
        }
        else if ((controller.GetPressUp(triggerButton) && grabType == typeOfAction.TRIGGER_TO_GRAB) && !held)
        {
            //Open hand
            stateOfHand = handState.OPEN;

            if (handModel != null && !handModel.activeInHierarchy)
            {
                handModel.SetActive(true);
            }
        }
    }
예제 #6
0
 public void reset()
 {
     _maxRotY       = 0;
     _curShootState = shootState.NORM;
     _curHandState  = handState.MID;
 }