OSVR-Core
SkeletonConfig.h
Go to the documentation of this file.
1 
11 // Copyright 2016 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 #ifndef INCLUDED_SkeletonConfig_h_GUID_A1D6BCE7_D044_4582_9BA5_860C790A3013
26 #define INCLUDED_SkeletonConfig_h_GUID_A1D6BCE7_D044_4582_9BA5_860C790A3013
27 
28 // Internal Includes
29 #include <osvr/Client/Export.h>
31 #include <osvr/Client/ViewerEye.h>
34 #include <osvr/Common/PathTree.h>
40 #include <osvr/Util/Pose3C.h>
41 #include <osvr/Util/TimeValue.h>
42 #include <osvr/Util/UniquePtr.h>
43 
44 // Library/third-party includes
45 // - none
46 
47 // Standard includes
48 #include <stdexcept>
49 #include <string>
50 #include <utility>
51 #include <vector>
52 
53 namespace osvr {
54 namespace client {
55 
56  typedef std::vector<std::pair<util::StringID, InternalInterfaceOwner>>
57  InterfaceMap;
58  typedef std::vector<std::pair<util::StringID, OSVR_Pose3>> PoseMap;
59 
60  struct NoCtxYet : std::runtime_error {
61  NoCtxYet()
62  : std::runtime_error("Client context is not yet initialized!") {}
63  };
64 
65  struct IdNotFound : std::runtime_error {
66  IdNotFound()
67  : std::runtime_error(
68  "Could not find joint/bone Id with provided info!") {}
69  };
70 
71  class SkeletonConfig;
72  typedef unique_ptr<SkeletonConfig> SkeletonConfigPtr;
74  public:
75  OSVR_CLIENT_EXPORT static SkeletonConfigPtr
76  create(OSVR_ClientContext ctx,
77  osvr::common::PathTree const &articulationTree);
78  };
79 
81  public:
82  // non-copyable
83  SkeletonConfig(SkeletonConfig const &) = delete;
84  SkeletonConfig &operator=(SkeletonConfig const &) = delete;
85 
86  bool getBoneId(const char *boneName,
87  OSVR_SkeletonBoneCount *boneId) const;
88  bool getJointId(const char *jointName,
89  OSVR_SkeletonJointCount *jointId) const;
90 
91  bool getAvailableJointId(OSVR_SkeletonJointCount jointIndex,
92  OSVR_SkeletonJointCount *jointId) const;
93 
94  bool getAvailableBoneId(OSVR_SkeletonBoneCount boneIndex,
95  OSVR_SkeletonBoneCount *boneId) const;
96 
97  std::string getBoneName(OSVR_SkeletonBoneCount boneId) const;
98  std::string getJointName(OSVR_SkeletonJointCount jointId) const;
99 
100  OSVR_Pose3 getBoneState(OSVR_SkeletonBoneCount boneId) const;
101  OSVR_Pose3 getJointState(OSVR_SkeletonJointCount jointId) const;
102 
103  OSVR_SkeletonBoneCount getNumBones() const;
104  OSVR_SkeletonJointCount getNumJoints() const;
105  void
106  updateArticulationTree(osvr::common::PathTree const &articulationTree);
107  /* @brief Go thru the joint and bone interfaces and set the poses
108  */
109  void updateSkeletonPoses();
110 
111  private:
112  friend class SkeletonConfigFactory;
116  bool isSkeletonTreeUpdated() const;
117  OSVR_ClientContext m_ctx;
118  osvr::common::PathTree m_articulationTree;
121  InterfaceMap m_jointInterfaces;
122  InterfaceMap m_boneInterfaces;
123  PoseMap m_jointPoses;
124  PoseMap m_bonePoses;
125  };
126 
127  inline bool
128  SkeletonConfig::getBoneId(const char *boneName,
129  OSVR_SkeletonBoneCount *boneId) const {
130  if (boneId == nullptr) {
131  return false;
132  }
133  osvr::util::StringID id = m_boneMap.getStringID(boneName);
134  if (id.empty()) {
135  return false;
136  }
137  *boneId = id.value();
138  return true;
139  }
140 
141  inline bool SkeletonConfig::getAvailableJointId(
142  OSVR_SkeletonJointCount jointIndex,
143  OSVR_SkeletonJointCount *jointId) const {
144  if (jointId == nullptr) {
145  return false;
146  }
147  *jointId = 0;
148  if (jointIndex >= m_jointInterfaces.size()) {
149  return false;
150  }
151 
152  // m_jointInterfaces[jointIndex].first.value() is the return value,
153  // but we need to make sure we actually allocate an entry for it
154 
155  // get the string id
156  auto stringId =
157  m_jointMap.getStringFromId(m_jointInterfaces[jointIndex].first);
158 
159  // then get the joint id
160  auto ret = getJointId(stringId.c_str(), jointId);
161 
162  return ret;
163  }
164 
165  inline bool
166  SkeletonConfig::getAvailableBoneId(OSVR_SkeletonBoneCount boneIndex,
167  OSVR_SkeletonBoneCount *boneId) const {
168  if (boneId == nullptr) {
169  return false;
170  }
171  *boneId = 0;
172  if (boneIndex >= m_boneMap.getEntries().size()) {
173  return false;
174  }
175 
176  auto boneName = m_boneMap.getEntries().at(boneIndex);
177 
178  auto ret = getBoneId(boneName.c_str(), boneId);
179 
180  return ret;
181  }
182 
183  inline bool
184  SkeletonConfig::getJointId(const char *jointName,
185  OSVR_SkeletonJointCount *jointId) const {
186  if (jointId == nullptr) {
187  return false;
188  }
189  osvr::util::StringID id = m_jointMap.getStringID(jointName);
190  if (id.empty()) {
191  return false;
192  }
193  *jointId = id.value();
194  return true;
195  }
196 
197  inline OSVR_Pose3
198  SkeletonConfig::getJointState(OSVR_SkeletonJointCount jointId) const {
199 
200  // find an interface for given jointId
201  for (auto val : m_jointPoses) {
202  if (val.first.value() == jointId) {
203  // return the joint state
204  return val.second;
205  }
206  }
207  // pose not available for this frame
208  throw NoPoseYet();
209  }
210 
211  inline OSVR_Pose3
214 
215  // find an interface for given boneId
216  for (auto val : m_bonePoses) {
217  if (val.first.value() == boneId) {
218  // return the bone state
219  return val.second;
220  }
221  }
222  // pose not available for this frame
223  throw NoPoseYet();
224  }
225 
226  inline OSVR_SkeletonBoneCount SkeletonConfig::getNumBones() const {
227  return static_cast<OSVR_SkeletonBoneCount>(
228  m_boneMap.getEntries().size());
229  }
230 
231  inline OSVR_SkeletonJointCount SkeletonConfig::getNumJoints() const {
232  return static_cast<OSVR_SkeletonJointCount>(
233  m_jointMap.getEntries().size());
234  }
235 
236  inline std::string
237  SkeletonConfig::getBoneName(OSVR_SkeletonBoneCount boneId) const {
238  auto boneName = m_boneMap.getStringFromId(util::StringID(boneId));
239  if (boneName.empty()) {
240  throw IdNotFound();
241  }
242  return boneName;
243  }
244  inline std::string
245  SkeletonConfig::getJointName(OSVR_SkeletonJointCount jointId) const {
246  auto jointName = m_jointMap.getStringFromId(util::StringID(jointId));
247  if (jointName.empty()) {
248  throw IdNotFound();
249  }
250  return jointName;
251  }
252 } // namespace client
253 } // namespace osvr
254 
255 #endif // INCLUDED_SkeletonConfig_h_GUID_A1D6BCE7_D044_4582_9BA5_860C790A3013
OSVR_Pose3 getBoneState(OSVR_SkeletonBoneCount boneId) const
Definition: SkeletonConfig.h:212
Centralize a string registry.
Definition: RegisteredStringMap.h:43
Definition: ViewerEye.h:57
Header.
A tree representation, with path/url syntax, of the known OSVR system.
Definition: PathTree.h:43
Header declaring opaque types used by Client and ClientKit.
Header providing a class template suitable for inheritance that wraps an arbitrary STL-like container...
The main namespace for all C++ elements of the framework, internal and external.
Definition: namespace_osvr.dox:3
uint32_t OSVR_SkeletonBoneCount
integer type specifying bone count/index(Id)
Definition: ClientReportTypesC.h:348
Definition: SkeletonConfig.h:65
Header to bring unique_ptr into the osvr namespace.
Definition: TypeSafeId.h:41
Definition: SkeletonConfig.h:80
Header.
Definition: SkeletonConfig.h:73
Header providing a C++ wrapper around TimeValueC.h.
Definition: ClientContext.h:50
A structure defining a 3D (6DOF) rigid body pose: translation and rotation.
Definition: Pose3C.h:54
Definition: SkeletonConfig.h:60
Header.
uint32_t OSVR_SkeletonJointCount
integer type specifying joint count/index(Id)
Definition: ClientReportTypesC.h:345