Exemple #1
0
 /// @brief Method to change the number of players
 ///
 /// @note This method changes the player list. It will unselect all players and
 /// old player references might become invalid or irrelevant! This method also assumes that the
 /// player manager has already been initialized.
 /// @param newNum The new number of players
 /// @return True on success, false otherwise.
 public virtual bool ChangeNumberOfPlayers(int newNum)
 {
     if (newNum < 0)
     {
         return(false);
     }
     if (newNum == m_MaxNumberOfPlayers)
     {
         return(true); // nothing to do...
     }
     for (int i = 0; i < m_players.Count; i++)
     {
         UnselectPlayer(i);
     }
     if (newNum < m_MaxNumberOfPlayers)
     {
         while (m_players.Count > newNum)
         {
             m_players.RemoveAt(m_players.Count - 1);
         }
     }
     else
     {
         while (m_players.Count < newNum)
         {
             NISelectedPlayer newPlayer = new NISelectedPlayer();
             newPlayer.User = null;
             m_players.Add(newPlayer);
         }
     }
     m_MaxNumberOfPlayers = newNum;
     return(true); // success
 }
    /// mono-behavior fixedUpdate
    /// This is used to update the position for the previous frame.
    /// @note we use FixedUpdate because this can be updated multiple times during a frame.
    public void FixedUpdate()
    {
        NISelectedPlayer player = m_playerManager.GetPlayer(m_playerNum);

        if (player == null || player.Valid == false || player.Tracking == false)
        {
            return; // no player to work with
        }
        SkeletonJointPosition skelJointPos;

        if (player.GetSkeletonJointPosition(m_jointToUse, out skelJointPos))
        {
            m_lastFrameCurPoint.UpdatePoint(skelJointPos.Position, skelJointPos.Confidence);
        }
        if (m_startingPoseReferenceType == StartingPosReferenceType.StaticModifierToOtherJoint ||
            m_startingPoseReferenceType == StartingPosReferenceType.ScaledModifierToOtherJoint)
        {
            if (player.GetSkeletonJointPosition(m_referenceJoint, out skelJointPos))
            {
                m_lastFrameReferenceJoint.UpdatePoint(skelJointPos.Position, skelJointPos.Confidence);
            }
        }
        if (m_startingPoseReferenceType == StartingPosReferenceType.ScaledModifierToOtherJoint)
        {
            SkeletonJointPosition skelJointPos2;
            if (player.GetSkeletonJointPosition(m_referenceJointScale1, out skelJointPos) &&
                player.GetSkeletonJointPosition(m_referenceJointScale2, out skelJointPos2))
            {
                m_lastFrameScaleJoint1.UpdatePoint(skelJointPos.Position, skelJointPos.Confidence);
                m_lastFrameScaleJoint2.UpdatePoint(skelJointPos2.Position, skelJointPos2.Confidence);
            }
        }
    }
    /// @brief Gets the starting position if @ref m_startingPoseReferenceType is TrackedJointReference
    ///
    /// @return The reference position of the tracked joint (zero if there is a problem).
    protected Vector3 GetStartingPosFromTrackedJoint()
    {
        // The position we count from is the initial calibration pose.
        NISelectedPlayer player = m_playerManager.GetPlayer(m_playerNum);

        if (player == null || player.Valid == false)
        {
            return(Vector3.zero); // no position.
        }
        SkeletonJointTransformation skelTrans;

        if (player.GetReferenceSkeletonJointTransform(m_jointToUse, out skelTrans) == false)
        {
            return(Vector3.zero); // we don't have the transform
        }
        Point3D pos = skelTrans.Position.Position;
        Vector3 res = NIConvertCoordinates.ConvertPos(pos);

        if (skelTrans.Position.Confidence < 0.5f || float.IsNaN(res.magnitude) || res.z >= 0)
        {
            // this means the value is irrelevant.
            player.RecalcReferenceJoints();
            SkeletonJointPosition skelJointPos;
            if (player.GetSkeletonJointPosition(m_jointToUse, out skelJointPos) == false)
            {
                return(Vector3.zero);
            }
            res = NIConvertCoordinates.ConvertPos(skelJointPos.Position);
        }
        return(res);
    }
Exemple #4
0
    /// mono-behavior update (called once per frame)
    public void Update()
    {
        if (m_playerManager == null || m_playerManager.Valid == false)
        {
            return; // we can do nothing.
        }
        NISelectedPlayer player = m_playerManager.GetPlayer(m_playerNumber);

        if (player == null || player.Valid == false || player.Tracking == false)
        {
            RotateToCalibrationPose(); // we don't have anything to work with.
            return;
        }
        Vector3 skelPos = Vector3.zero;
        SkeletonJointTransformation skelTrans;

        if (player.GetReferenceSkeletonJointTransform(SkeletonJoint.Torso, out skelTrans))
        {
            if (skelTrans.Position.Confidence < 0.5f)
            {
                player.RecalcReferenceJoints(); // we NEED the torso to be good.
            }
            if (skelTrans.Position.Confidence >= 0.5f)
            {
                skelPos = NIConvertCoordinates.ConvertPos(skelTrans.Position.Position);
            }
        }
        UpdateSkeleton(player, skelPos);
    }
    /// used for updating every frame
    /// @note While we are still steady (i.e. we haven't gotten a "not steady" event) we update
    /// the time and frame every frame!
    public override void UpdateFrame()
    {
        if (m_context == null || m_context.UserSkeletonValid == false)
        {
            return; // no data;
        }
        NISkeletonTracker tracker = m_pointTracker as NISkeletonTracker;

        if (tracker.Valid == false)
        {
            return; // no one to track.
        }
        NISelectedPlayer player = tracker.GetTrackedPlayer();

        if (player == null || player.Valid == false)
        {
            return;
        }
        NIUserAndSkeleton.NIPoseDetectionStateStatus curStatus = new NIUserAndSkeleton.NIPoseDetectionStateStatus();
        if (m_context.UserGenrator.GetPoseStatus(player.OpenNIUserID, m_poseName, ref curStatus) == false)
        {
            return; // we do not have good pose information
        }
        if (curStatus.m_eState != PoseDetectionState.InPose)
        {
            return;
        }
        if (curStatus.m_timePoseHeld >= m_timeToHoldPose)
        {
            InternalFireDetectEvent();
        }
    }
    // protected methods
    protected override bool InternalInit(NIPointTracker hand)
    {
        NISkeletonTracker curHand = hand as NISkeletonTracker;

        if (curHand == null)
        {
            return(false);
        }
        if (m_context == null || m_context.UserSkeletonValid == false)
        {
            return(false);
        }
        NISelectedPlayer player = curHand.GetTrackedPlayer();

        if (player == null)
        {
            return(false); // no player
        }
        player.m_userChangeEventHandler += PlayerUserChangeHandler;
        if (player.Valid)
        {
            validRequestedPoseDetection = m_context.UserGenrator.RequestPoseDetection(m_poseName, player.OpenNIUserID);
            return(validRequestedPoseDetection);
        }
        validRequestedPoseDetection = false;
        return(true);
    }
Exemple #7
0
    public void UpdateBoneDistance(NISelectedPlayer player, SkeletonJointPosition torsoPos)
    {
        //initial adjustment wait...
        int countBuffer = 6; int countMax = 10;

        if (countBoneLenghthUpdate >= countMax)
        {
            return;
        }
        if (countBoneLenghthUpdate <= countBuffer)
        {
            countBoneLenghthUpdate++;
            return;
        }

        //bone distance adjustment
        int count = countBoneLenghthUpdate - countBuffer;

        if (count == 1)//for waist
        {
            //AdjustBone(SkeletonJoint.Waist, SkeletonJoint.Torso, player, torsoPos);
            //AdjustBone(SkeletonJoint.Neck, SkeletonJoint.Waist, player, torsoPos);
            AdjustBone(SkeletonJoint.LeftShoulder, SkeletonJoint.RightShoulder, player, torsoPos);
            AdjustBone(SkeletonJoint.LeftHip, SkeletonJoint.RightHip, player, torsoPos);
            AdjustBone(SkeletonJoint.LeftElbow, SkeletonJoint.LeftShoulder, player, torsoPos);
            AdjustBone(SkeletonJoint.LeftHand, SkeletonJoint.LeftElbow, player, torsoPos);
            AdjustBone(SkeletonJoint.LeftKnee, SkeletonJoint.LeftHip, player, torsoPos);
            //AdjustBone(SkeletonJoint.LeftFoot, SkeletonJoint.LeftKnee, player, torsoPos);
        }
        countBoneLenghthUpdate++;
    }
Exemple #8
0
    private void UpdateVertices(NISelectedPlayer player, SkeletonJointPosition torsoPos)
    {
        //initial adjustment wait...
        int countBuffer = 1; int countMax = 10;

        if (countBoneLenghthUpdate >= countMax)
        {
            return;
        }
        if (countBoneLenghthUpdate <= countBuffer)
        {
            countBoneLenghthUpdate++;
            return;
        }

        //adjustment
        int count = countBoneLenghthUpdate - countBuffer;

        if (count == 2)//for waist
        {
            SkinnedMeshRenderer mesh     = GetComponentInChildren <SkinnedMeshRenderer>();
            Vector3[]           vertices = mesh.sharedMesh.vertices;
            vertices[0].y += 100;
        }
    }
    public bool UpdateSkeletonData()
    {
        if (!IsSkeletonAvailable())
        {
            return(false); // we can do nothing.
        }
        NISelectedPlayer player = m_playerManager.GetPlayer(m_playerNumber);

        // we use the torso as root
        SkeletonJointTransformation skelTrans;

        if (player.GetSkeletonJoint(Joint.Torso, out skelTrans) == false)
        {
            // we don't have joint information so we simply return...
            return(false);
        }

        // update each joint with data from OpenNI
        foreach (Joint joint in Enum.GetValues(typeof(Joint)))
        {
            SkeletonJointTransformation skelTransJoint;
            if (player.GetSkeletonJoint(joint, out skelTransJoint) == false)
            {
                continue; // irrelevant joint
            }
            m_jointData[(int)joint].FromRaw(skelTransJoint);
        }
        return(true);
    }
Exemple #10
0
    /// @brief updates the skeleton
    ///
    /// This method is responsible for updating the skeleton based on new information.
    /// It is called by an external manager with the correct user which controls this specific skeleton.
    /// @param player The player object for the player controlling us.
    /// @param centerOffset the offset we should use on the center (when moving the root).
    /// This is usually the starting position (so the skeleton will not "jump" when doing the first update
    public void UpdateSkeleton(NISelectedPlayer player, Vector3 centerOffset)
    {
        if (player.Valid == false)
        {
            return; // irrelevant player
        }
        if (player.Tracking == false)
        {
            return; // not tracking
        }
        // we use the  torso as root
        SkeletonJointTransformation skelTrans;

        if (player.GetSkeletonJoint(SkeletonJoint.Torso, out skelTrans) == false)
        {
            // we don't have joint information so we simply return...
            return;
        }
        UpdateRoot(skelTrans.Position, centerOffset);

        // update each joint with data from OpenNI
        foreach (SkeletonJoint joint in Enum.GetValues(typeof(SkeletonJoint)))
        {
            SkeletonJointTransformation skelTransJoint;
            if (player.GetSkeletonJoint(joint, out skelTransJoint) == false)
            {
                continue; // irrelevant joint
            }
            UpdateJoint(joint, skelTransJoint, skelTrans.Position);
        }
    }
    /// mono-behavior GUI drawing
    void OnGUI()
    {
        Rect curPos = m_basePos;

        if (m_playerManager == null || m_playerManager.Valid == false)
        {
            return; // no player manager so nothing to do...
        }
        int numTracking = m_playerManager.GetNumberOfTrackingPlayers();

        if (m_AllPlayersMessage && numTracking >= m_playerManager.m_MaxNumberOfPlayers)
        {
            return; // all players are tracking, nothing to do here.
        }
        if (!m_AllPlayersMessage && numTracking > 0)
        {
            return; // at least one player is tracking and we don't want to show the message to the rest
        }
        // reaching here means we have a valid player mapper with no calibrated users, we need to
        // show a message...
        int numUnselected = 0;

        for (int i = 0; i < m_playerManager.m_MaxNumberOfPlayers; i++)
        {
            NISelectedPlayer player = m_playerManager.GetPlayer(i);
            if (player == null || player.Valid == false)
            {
                GUI.Box(curPos, "Player " + i + " is unselected.");
                numUnselected++;
            }
            else if (player.Tracking == false)
            {
                GUI.Box(curPos, "Player " + i + " is calibrating.");
            }
            else
            {
                continue;
            }
            curPos.y += 35;
        }

        if (numUnselected == 0)
        {
            return;
        }
        if (m_actionToSelect.CompareTo("") != 0)
        {
            curPos.width = m_actionToSelectRectWidth;
            GUI.Box(curPos, m_actionToSelect);
            curPos.y += 35;
        }

        if (m_Image != null)
        {
            curPos.width  = 128;
            curPos.height = 128;
            GUI.Box(curPos, m_Image);
        }
    }
    protected override bool UnsafeUnselectPlayer(int playerNumber)
    {
        NISelectedPlayer            player = m_players[playerNumber];
        NIPlayerPoseCandidateObject user   = player.User as NIPlayerPoseCandidateObject;

        user.m_unselectionOutOfPoseTime = float.MaxValue; // to make sure we can select again!
        return(base.UnsafeUnselectPlayer(playerNumber));
    }
Exemple #13
0
 /// @brief Internal method to initialize the players list.
 ///
 /// @note The players initialization is done during the mono behavior @ref Awake stage to enable
 /// calls to GetPlayer during the mono behavior start stage of @b other objects.
 protected virtual void InitPlayers()
 {
     // initialize the players to have an unselected user for each player.
     m_players = new List <NISelectedPlayer>();
     for (int i = 0; i < m_MaxNumberOfPlayers; i++)
     {
         NISelectedPlayer player = new NISelectedPlayer();
         player.User = null;
         m_players.Add(player);
     }
 }
Exemple #14
0
    /// mono-behavior Update is called once per frame
    public void Update()
    {
        if (Time.time < m_timeToCreateNextBall)
        {
            return; // we created a ball very recently, wait.
        }
        if (m_playerManager == null)
        {
            return; // this means we don't even have a plyer manager.
        }
        NISelectedPlayer player = m_playerManager.GetPlayer(0);

        if (player == null || player.Valid == false || player.Tracking == false)
        {
            return; // this means we don't have a calibrated user
        }
        if (SkeletonGuiControl.m_mode == SkeletonGuiControl.SkeletonGUIModes.GUIMode)
        {
            return; // we don't throw balls while in GUI mode.
        }
        // now we know we should throw a ball. We first figure out where (a random around the
        // x axis of the "where" transform and a constant modifier on the y and z).
        Vector3 pos = where.position;

        pos.x += Random.Range(-2.0f, 2.0f);
        pos.y += 8.0f;
        pos.z += 2.1f;
        // create the ball
        Instantiate(prefab, pos, Quaternion.identity);

        m_numBallsCreated++;
        // we set the time for the next ball. The time itself depends on how many balls were created
        // (the more balls, the less time on average).
        float maxTime = 5.0f;
        float minTime = 1.0f;

        if (m_numBallsCreated > 5)
        {
            maxTime = 4.0f;
        }
        if (m_numBallsCreated > 10)
        {
            maxTime = 3.0f;
        }
        if (m_numBallsCreated > 15)
        {
            minTime = 0.5f;
        }
        if (m_numBallsCreated > 20)
        {
            maxTime = 2.0f;
        }
        m_timeToCreateNextBall = Time.time + Random.Range(minTime, maxTime);
    }
Exemple #15
0
    public Vector3 CalcActualPosition(SkeletonJoint joint, NISelectedPlayer player, SkeletonJointPosition torsoPos)
    {
        Vector3 actualPos;
        SkeletonJointTransformation trans;

        if (player.GetSkeletonJoint(joint, out trans) == false || trans.Position.Confidence <= 0.5)
        {
            Debug.Log("No actual position for Joint: " + joint);
            actualPos = ERROR_VECTOR;
        }
        actualPos = CalcJointPosition(joint, ref trans, ref torsoPos);
        return(actualPos);
    }
    public bool IsSkeletonAvailable()
    {
        if (m_playerManager == null || m_playerManager.Valid == false)
        {
            return(false); // we can do nothing.
        }
        NISelectedPlayer player = m_playerManager.GetPlayer(m_playerNumber);

        if (player == null || player.Valid == false || player.Tracking == false)
        {
            return(false);
        }
        return(true);
    }
    // protected methods

    /// this method tries to fill a new point on each of the relevant joints.
    /// It returns true if it succeed and false otherwise
    /// @note it will fail if even one of the points has a low confidence!
    /// @return true on success, false on failure.
    protected bool FillPoints()
    {
        // first we find a reference to the skeleton capability
        NISkeletonTracker hand = m_pointTracker as NISkeletonTracker;

        if (hand == null)
        {
            return(false); // no hand to track
        }
        NISelectedPlayer player = hand.GetTrackedPlayer();

        if (player == null || player.Valid == false || player.Tracking == false)
        {
            return(false); // no player to work with...
        }
        // We need to figure out if we have a good confidence on all joints

        SkeletonJointPosition rightHand;
        SkeletonJointPosition leftHand;
        SkeletonJointPosition rightElbow;
        SkeletonJointPosition leftElbow;

        if (player.GetSkeletonJointPosition(SkeletonJoint.RightHand, out rightHand) == false || rightHand.Confidence <= 0.5f)
        {
            return(false);
        }
        if (player.GetSkeletonJointPosition(SkeletonJoint.LeftHand, out leftHand) == false || leftHand.Confidence <= 0.5f)
        {
            return(false);
        }
        if (player.GetSkeletonJointPosition(SkeletonJoint.RightElbow, out rightElbow) == false || rightElbow.Confidence <= 0.5f)
        {
            return(false);
        }
        if (player.GetSkeletonJointPosition(SkeletonJoint.LeftElbow, out leftElbow) == false || leftElbow.Confidence <= 0.5f)
        {
            return(false);
        }
        Vector3 pos = NIConvertCoordinates.ConvertPos(rightHand.Position);

        m_pointsRightHand.AddPoint(ref pos);
        pos = NIConvertCoordinates.ConvertPos(leftHand.Position);
        m_pointsLeftHand.AddPoint(ref pos);
        pos = NIConvertCoordinates.ConvertPos(rightElbow.Position);
        m_pointsRightElbow.AddPoint(ref pos);
        pos = NIConvertCoordinates.ConvertPos(leftElbow.Position);
        m_pointsLeftElbow.AddPoint(ref pos);
        return(true);
    }
 /// Release the gesture
 public override void ReleaseGesture()
 {
     if (m_context != null && m_context.UserSkeletonValid)
     {
         NISkeletonTracker tracker = m_pointTracker as NISkeletonTracker;
         if (tracker.Valid)
         {
             NISelectedPlayer player = tracker.GetTrackedPlayer();
             if (player != null && player.Valid && validRequestedPoseDetection)
             {
                 m_context.UserGenrator.ReleasePoseDetection(m_poseName, player.OpenNIUserID);
             }
         }
     }
     m_context      = null;
     m_poseName     = "";
     m_pointTracker = null;
 }
    /// returns the current position with confidence
    ///
    /// @param confidence the confidence of the point
    /// @return the position
    public Vector3 GetPosWithConfidence(out float confidence)
    {
        confidence = 0.0f;
        NISelectedPlayer player = m_playerManager.GetPlayer(m_playerNum);

        if (player == null || player.Valid == false || player.Tracking == false)
        {
            return(Vector3.zero); // no position.
        }
        SkeletonJointPosition skelJointPos;

        if (player.GetSkeletonJointPosition(m_jointToUse, out skelJointPos) == false)
        {
            return(Vector3.zero);
        }
        confidence = skelJointPos.Confidence;
        return(NIConvertCoordinates.ConvertPos(skelJointPos.Position));
    }
Exemple #20
0
    void DrawLineBetweenJoints(OpenNI.SkeletonJoint first, OpenNI.SkeletonJoint second)
    {
        NISelectedPlayer player = playerSelection.GetPlayer(0);

        OpenNI.SkeletonJointPosition firstJointPosition;
        player.GetSkeletonJointPosition(first, out firstJointPosition);
        OpenNI.SkeletonJointPosition secondJointPosition;
        player.GetSkeletonJointPosition(second, out secondJointPosition);

        if (firstJointPosition.Confidence <= 0.5 || secondJointPosition.Confidence <= 0.5)
        {
            return;
        }

        OpenNI.Point3D firstJointScreenPosition  = depthGenerator.ConvertRealWorldToProjective(firstJointPosition.Position);
        OpenNI.Point3D secondJointScreenPosition = depthGenerator.ConvertRealWorldToProjective(secondJointPosition.Position);
        DrawLine.DrawSimpleLine(ref mapPixels,
                                (int)(width - firstJointScreenPosition.X / factor), (int)(height - firstJointScreenPosition.Y / factor),
                                (int)(width - secondJointScreenPosition.X / factor), (int)(height - secondJointScreenPosition.Y / factor),
                                width, height,
                                Color.white);
    }
    /// This is true if the gesture is in the middle of doing (i.e. it has detected but not gone out of the gesture).
    /// for our purposes this means the steady event has occurred and the unsteady has not occurred yet
    /// @return a value between 0 and 1. 0 means no pose, 1 means the pose has been detected and held
    /// for a while. a value in the middle means the pose has been detected and has been held this
    /// portion of the time required to fire the trigger (@ref m_timeToHoldPose).
    public override float GestureInProgress()
    {
        if (m_context == null || m_context.UserSkeletonValid == false)
        {
            return(0.0f); // no data;
        }
        NISkeletonTracker tracker = m_pointTracker as NISkeletonTracker;

        if (tracker.Valid == false)
        {
            return(0.0f); // no one to track.
        }
        NISelectedPlayer player = tracker.GetTrackedPlayer();

        if (player == null || player.Valid == false)
        {
            return(0.0f);
        }
        NIUserAndSkeleton.NIPoseDetectionStateStatus curStatus = new NIUserAndSkeleton.NIPoseDetectionStateStatus();
        if (m_context.UserGenrator.GetPoseStatus(player.OpenNIUserID, m_poseName, ref curStatus) == false)
        {
            return(0.0f); // we do not have good pose information
        }
        if (curStatus.m_eState != PoseDetectionState.InPose)
        {
            return(0.0f);
        }
        if (curStatus.m_timePoseHeld < 0)
        {
            return(0.0f);
        }
        if (curStatus.m_timePoseHeld >= m_timeToHoldPose)
        {
            return(1.0f);
        }
        return(curStatus.m_timePoseHeld / m_timeToHoldPose);
    }
Exemple #22
0
    public void AdjustBone(SkeletonJoint joint1, SkeletonJoint joint2, NISelectedPlayer player, SkeletonJointPosition torsoPos)
    {
        //if(joint1)
        Vector3 joint1ActualPos = CalcActualPosition(joint1, player, torsoPos);
        Vector3 joint2ActualPos = CalcActualPosition(joint2, player, torsoPos);

        if (joint1ActualPos == ERROR_VECTOR || joint2ActualPos == ERROR_VECTOR)
        {
            return;
        }

        Transform joint1Trans      = m_jointTransforms[(int)joint1];
        Transform joint2Trans      = m_jointTransforms[(int)joint2];
        Vector3   joint1VirtualPos = joint1Trans.localPosition;
        Vector3   joint2VirtualPos = joint2Trans.localPosition;
        float     actualDist       = (joint1ActualPos - joint2ActualPos).magnitude;
        float     virtualDist      = (joint1VirtualPos - joint2VirtualPos).magnitude;

        float   translateValue  = actualDist - virtualDist;
        float   translateFactor = translateValue / virtualDist;
        Vector3 translateVector = (joint1VirtualPos - joint2VirtualPos) * translateFactor;

        Debug.Log("Joint: " + joint1 + " is found! and translateVector = " + translateVector);
        Debug.Log("translateFactor = " + translateFactor + " = " + translateValue + "/" + virtualDist);
        //how to translate
        if (joint1 == SkeletonJoint.Waist || joint1 == SkeletonJoint.Neck)//translate Y axis up/down
        {
            joint1Trans.localPosition += translateVector;
        }
        else if (joint1 == SkeletonJoint.LeftShoulder || joint1 == SkeletonJoint.LeftHip)
        {
            //for left shoulder
            joint1Trans.localPosition += translateVector / 2;
            //for right shoulder : added
            joint2Trans.localPosition -= translateVector / 2;
        }
        else if (joint1 == SkeletonJoint.LeftElbow) //mirror!
        {
            //for left
            joint1Trans.localPosition += translateVector;

            //for right: added
            Transform rightElbowTrans = m_jointTransforms[(int)SkeletonJoint.RightElbow];
            translateVector =
                (rightElbowTrans.localPosition - m_jointTransforms[(int)SkeletonJoint.RightShoulder].localPosition) * translateFactor;
            rightElbowTrans.localPosition += translateVector;
        }
        else if (joint1 == SkeletonJoint.LeftHand)//mirror!
        {
            joint1Trans.localPosition += translateVector;
            Transform rightHandTrans = m_jointTransforms[(int)SkeletonJoint.RightHand];
            translateVector =
                (rightHandTrans.localPosition - m_jointTransforms[(int)SkeletonJoint.RightElbow].localPosition) * translateFactor;
            rightHandTrans.localPosition += translateVector;
        }
        else if (joint1 == SkeletonJoint.LeftKnee)
        {
            joint1Trans.localPosition += translateVector;
            Transform rightKneeTrans = m_jointTransforms[(int)SkeletonJoint.RightKnee];
            translateVector =
                (rightKneeTrans.localPosition - m_jointTransforms[(int)SkeletonJoint.RightHip].localPosition) * translateFactor;
            rightKneeTrans.localPosition += translateVector;
        }
        else if (joint1 == SkeletonJoint.LeftFoot)
        {
            joint1Trans.localPosition += translateVector;
            Transform rightFootTrans = m_jointTransforms[(int)SkeletonJoint.RightFoot];
            translateVector =
                (rightFootTrans.localPosition - m_jointTransforms[(int)SkeletonJoint.RightKnee].localPosition) * translateFactor;
            rightFootTrans.localPosition += translateVector;
        }
    }
    /// @brief updates the skeleton
    /// 
    /// This method is responsible for updating the skeleton based on new information.
    /// It is called by an external manager with the correct user which controls this specific skeleton.
    /// @param player The player object for the player controlling us.
    /// @param centerOffset the offset we should use on the center (when moving the root). 
    /// This is usually the starting position (so the skeleton will not "jump" when doing the first update
    public void UpdateSkeleton(NISelectedPlayer player, Vector3 centerOffset)
    {
        if (player.Valid == false)
            return; // irrelevant player
        if (player.Tracking == false)
            return; // not tracking

        // we use the  torso as root
        SkeletonJointTransformation skelTrans;
        if (player.GetSkeletonJoint(SkeletonJoint.Torso, out skelTrans) == false)
        {
            // we don't have joint information so we simply return...
            return;
        }
        UpdateRoot(skelTrans.Position, centerOffset);

        // update each joint with data from OpenNI
        foreach (SkeletonJoint joint in Enum.GetValues(typeof(SkeletonJoint)))
        {
            SkeletonJointTransformation skelTransJoint;
            if(player.GetSkeletonJoint(joint,out skelTransJoint) == false)
                continue; // irrelevant joint
            UpdateJoint(joint, skelTransJoint, skelTrans.Position);
        }
    }
 /// @brief Internal method to initialize the players list.
 /// 
 /// @note The players initialization is done during the mono behavior @ref Awake stage to enable
 /// calls to GetPlayer during the mono behavior start stage of @b other objects.
 protected virtual void InitPlayers()
 {
     // initialize the players to have an unselected user for each player.
     m_players = new List<NISelectedPlayer>();
     for (int i = 0; i < m_MaxNumberOfPlayers; i++)
     {
         NISelectedPlayer player = new NISelectedPlayer();
         player.User = null;
         m_players.Add(player);
     }
 }
 /// @brief Method to change the number of players
 /// 
 /// @note This method changes the player list. It will unselect all players and 
 /// old player references might become invalid or irrelevant! This method also assumes that the
 /// player manager has already been initialized.
 /// @param newNum The new number of players
 /// @return True on success, false otherwise.
 public virtual bool ChangeNumberOfPlayers(int newNum)
 {
     if (newNum < 0)
         return false;
     if (newNum == m_MaxNumberOfPlayers)
         return true; // nothing to do...
     for(int i=0; i<m_players.Count; i++)
     {
         UnselectPlayer(i);
     }
     if (newNum < m_MaxNumberOfPlayers)
     {
         while (m_players.Count > newNum)
         {
             m_players.RemoveAt(m_players.Count - 1);
         }
     }
     else
     {
         while (m_players.Count < newNum)
         {
             NISelectedPlayer newPlayer = new NISelectedPlayer();
             newPlayer.User = null;
             m_players.Add(newPlayer);
         }
     }
     m_MaxNumberOfPlayers = newNum;
     return true; // success
 }