File: PoseToggleUserSelector.cpp

package info (click to toggle)
openni 1.5.4.0%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 45,208 kB
  • sloc: cpp: 116,706; ansic: 58,794; sh: 10,287; cs: 7,698; java: 7,402; python: 1,544; makefile: 492; xml: 167
file content (181 lines) | stat: -rw-r--r-- 7,756 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/****************************************************************************
*                                                                           *
*  OpenNI 1.x Alpha                                                         *
*  Copyright (C) 2011 PrimeSense Ltd.                                       *
*                                                                           *
*  This file is part of OpenNI.                                             *
*                                                                           *
*  OpenNI is free software: you can redistribute it and/or modify           *
*  it under the terms of the GNU Lesser General Public License as published *
*  by the Free Software Foundation, either version 3 of the License, or     *
*  (at your option) any later version.                                      *
*                                                                           *
*  OpenNI is distributed in the hope that it will be useful,                *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the             *
*  GNU Lesser General Public License for more details.                      *
*                                                                           *
*  You should have received a copy of the GNU Lesser General Public License *
*  along with OpenNI. If not, see <http://www.gnu.org/licenses/>.           *
*                                                                           *
****************************************************************************/

//---------------------------------------------------------------------------
// Includes
//---------------------------------------------------------------------------
#include "PoseToggleUserSelector.h"



#define VALIDATE(cond, errorMsg)                                        \
    if(!cond)                                                       \
        {                                                               \
        printf("PoseUserSelector creation failed: %s\n",errorMsg);  \
        m_bValid=FALSE;                                             \
        return;                                                     \
        }                                                               \

#define VALIDATE_WITH_ACTION(cond, errorMsg, actionToDo)                \
    if(!cond)                                                           \
    {                                                                   \
    printf("PoseUserSelector creation failed: %s\n",errorMsg);      \
    actionToDo;                                                     \
    m_bValid=FALSE;                                                 \
    return;                                                         \
    }                                                                   \

//---------------------------------------------------------------------------
// Code
//---------------------------------------------------------------------------



PoseToggleUserSelector::PoseToggleUserSelector(xn::UserGenerator* pUserGenerator,
                                               TrackingInitializer* pTrackingInitializer, 
                                               const char* poseToTrack,
                                               XnUInt32 maxUsersToTrack,
                                               XnUInt64 timeBeforeToggle) : 
                    PoseUserSelector(pUserGenerator,pTrackingInitializer,poseToTrack),
                    m_nMaxUsersToTrack(maxUsersToTrack),
                    m_timeBeforeToggle(timeBeforeToggle)
{
    VALIDATE(m_bValid,"PoseUserSelector was not initialized properly"); // note we assume this tests the validity of the pose capability
    XnStatus nRetVal = m_pUserGenerator->GetPoseDetectionCap().RegisterToOutOfPose(OutOfPoseCallback,this,m_hOutOfPoseDetectCallback);
    VALIDATE_WITH_ACTION(nRetVal == XN_STATUS_OK,"Failed to register to pose detection",m_hOutOfPoseDetectCallback = NULL);
}
                                     

    /// @brief destructor.
PoseToggleUserSelector::~PoseToggleUserSelector()
{
    if(m_hOutOfPoseDetectCallback != NULL)
    {
        m_pUserGenerator->GetPoseDetectionCap().UnregisterFromOutOfPose(m_hOutOfPoseDetectCallback);
        m_hOutOfPoseDetectCallback = NULL;
    }
}

XnStatus PoseToggleUserSelector::DetectPose(XnUserID nUserId)
{
    UserSelectionState* pState;
    XnStatus nRetVal = m_hUsersState.Get(nUserId, pState);
    if(nRetVal!=XN_STATUS_OK)
    {
        return nRetVal;
    }
    XnUInt64 lastOutOfPoseTime;

    nRetVal=m_usersOutOfPoseTime.Get(nUserId, lastOutOfPoseTime);
    if(nRetVal!=XN_STATUS_OK)
    {
        return nRetVal; // we don't have a user time at all. This should not happen!!!
    }
    XnUInt64 curOutOfPoseTime=m_pUserGenerator->GetTimestamp();


    if(pState->m_eState == XN_SELECTION_UNSELECTED || pState->m_eState == XN_SELECTION_FAILED)
    {

        // we want to select the user
        if(lastOutOfPoseTime > 0 && (curOutOfPoseTime-lastOutOfPoseTime < m_timeBeforeToggle))
        {
            return XN_STATUS_OK; // not enough time has passed since out of pose
        }

        if(GetNumberOfSelectedUsers() >= m_nMaxUsersToTrack)
        {
            return XN_STATUS_OK; // we don't select because we already have enough selected users
        }
        XnUInt64 tmpTime = 0;
        m_usersOutOfPoseTime.Set(nUserId,tmpTime); // we start so we don't care about previous out of pose any more
        return PoseUserSelector::DetectPose(nUserId); // we select as the parent does.
    }
    else
    {
        // we might want to unselect the user.

        if(lastOutOfPoseTime == 0 || (curOutOfPoseTime - lastOutOfPoseTime < m_timeBeforeToggle))
        {
            return XN_STATUS_OK; // not enough time has passed
        }
        // we need to unselect!
        UpdateUserSelectionState(nUserId,XN_SELECTION_UNSELECTED,0);
        m_pTrackingInitializer->AbortTracking(nUserId); // stop tracking
        m_usersOutOfPoseTime.Set(nUserId,curOutOfPoseTime); // we are not tracking so no time is relevant

    }
    return XN_STATUS_ERROR;
}

XnStatus PoseToggleUserSelector::AddNewUser(XnUserID nUserId)
{
    XnStatus res=PoseUserSelector::AddNewUser(nUserId);
    if(res!=XN_STATUS_OK)
    {
        return res;
    }
    return m_usersOutOfPoseTime.Set(nUserId,0);
}

XnStatus PoseToggleUserSelector::RemoveUser(XnUserID nUserId)
{
    XnStatus res=PoseUserSelector::RemoveUser(nUserId);
    if(res!=XN_STATUS_OK)
    {
        return res;
    }
    return m_usersOutOfPoseTime.Remove(nUserId);
}

XnStatus PoseToggleUserSelector::DetectOutOfPose(XnUserID nUserId)
{
    XnUInt64 lastOutOfPoseTime;

    UserSelectionState* pState;
    XnStatus nRetVal=m_hUsersState.Get(nUserId, pState);
    if(nRetVal!=XN_STATUS_OK)
    {
        return nRetVal;
    }
    nRetVal=m_usersOutOfPoseTime.Get(nUserId,lastOutOfPoseTime);
    if(nRetVal!=XN_STATUS_OK)
    {
        return nRetVal;
    }
    if(lastOutOfPoseTime!=0)
    {
        return XN_STATUS_OK; // we already have a number...
    }
    lastOutOfPoseTime=m_pUserGenerator->GetTimestamp();
    m_usersOutOfPoseTime.Set(nUserId,lastOutOfPoseTime);
    return XN_STATUS_OK;
}

void XN_CALLBACK_TYPE PoseToggleUserSelector::OutOfPoseCallback(xn::PoseDetectionCapability& /*capability*/, const XnChar* strPose, XnUserID nUserId,void* pCookie)
{
    PoseToggleUserSelector *pPoseUserSelector=(PoseToggleUserSelector *)pCookie;
    if(xnOSStrCmp(strPose,pPoseUserSelector->m_strPoseToTrack)!=0)
        return; // this is not the pose we are looking for.
    pPoseUserSelector->DetectOutOfPose(nUserId);

}