Astra SDK  v2.1.3
Hand.hpp
1 // This file is part of the Orbbec Astra SDK [https://orbbec3d.com]
2 // Copyright (c) 2015-2017 Orbbec 3D
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 // Be excellent to each other.
17 #ifndef ASTRA_HAND_HPP
18 #define ASTRA_HAND_HPP
19 
20 #include <stdexcept>
21 #include <cstdint>
22 #include <astra_core/astra_core.hpp>
23 #include <astra/capi/astra_ctypes.h>
24 #include <astra/capi/streams/hand_capi.h>
25 #include <astra/Vector.hpp>
26 
27 namespace astra {
28 
41  {
42  public:
52  HandPoint(std::int32_t trackingId,
53  astra_handstatus_t status,
54  Vector2i depthPosition,
55  Vector3f worldPosition,
56  Vector3f worldDeltaPosition)
57  {
58  astra_handpoint_t::trackingId = trackingId;
59  astra_handpoint_t::status = status;
60  astra_handpoint_t::depthPosition = depthPosition;
61  astra_handpoint_t::worldPosition = worldPosition;
62  astra_handpoint_t::worldDeltaPosition = worldDeltaPosition;
63  }
64 
70  HandPoint(const astra_handpoint_t& handPoint)
71  {
72  *this = handPoint;
73  }
74 
80  HandPoint& operator=(const ::astra_handpoint_t& handPoint)
81  {
82  astra_handpoint_t::trackingId = handPoint.trackingId;
83  astra_handpoint_t::status = handPoint.status;
84  astra_handpoint_t::depthPosition = handPoint.depthPosition;
85  astra_handpoint_t::worldPosition = handPoint.worldPosition;
86  astra_handpoint_t::worldDeltaPosition = handPoint.worldDeltaPosition;
87 
88  return *this;
89  }
90 
96  inline operator ::astra_handpoint_t*() { return this; }
97 
103  inline operator const ::astra_handpoint_t*() const { return this; }
104 
110  inline std::int32_t tracking_id() const { return astra_handpoint_t::trackingId; }
111 
117  inline astra_handstatus_t status() const { return astra_handpoint_t::status; }
118 
124  inline Vector2i depth_position() const { return astra_handpoint_t::depthPosition; }
125 
131  inline Vector3f world_position() const { return astra_handpoint_t::worldPosition; }
132 
138  inline Vector3f world_delta_position() const { return astra_handpoint_t::worldDeltaPosition; }
139 
140  private:
141  astra_handpoint_t handPoint_;
142  Vector2i depthPosition_;
143  Vector3f worldPosition_;
144  Vector3f worldDeltaPosition_;
145  };
146 
152  class HandStream : public DataStream
153  {
154  public:
161  : DataStream(connection),
162  handStream_(connection)
163  { }
164 
165  static const astra_stream_type_t id = ASTRA_STREAM_HAND;
166 
173  {
174  bool includeCandidatePoints;
175  astra_handstream_get_include_candidate_points(handStream_, &includeCandidatePoints);
176  return includeCandidatePoints;
177  }
178 
184  void set_include_candidate_points(bool includeCandidatePoints)
185  {
186  astra_handstream_set_include_candidate_points(handStream_, includeCandidatePoints);
187  }
188  private:
189  astra_handstream_t handStream_;
190  };
191 
197  class HandFrame
198  {
199  public:
200  using HandPointList = std::vector<HandPoint>;
201 
207  template<typename TFrameType>
208  static TFrameType acquire(astra_reader_frame_t readerFrame,
209  astra_stream_subtype_t subtype)
210  {
211  if (readerFrame != nullptr)
212  {
213  astra_handframe_t handFrame;
214  astra_frame_get_handframe_with_subtype(readerFrame, subtype, &handFrame);
215  return TFrameType(handFrame);
216  }
217 
218  return TFrameType(nullptr);
219  }
220 
227  {
228  handFrame_ = handFrame;
229  if (handFrame_)
230  {
231  astra_handframe_get_frameindex(handFrame_, &frameIndex_);
232 
233  std::uint32_t maxHandCount;
234  astra_handframe_get_hand_count(handFrame_, &maxHandCount);
235 
236  handPoints_.reserve(maxHandCount);
237  }
238  }
239 
245  bool is_valid() const { return handFrame_ != nullptr; }
246 
252  astra_handframe_t handle() const { return handFrame_; }
253 
259  size_t handpoint_count() const
260  {
261  throw_if_invalid_frame();
262  verify_handpoints();
263 
264  return handPoints_.size();
265  }
266 
272  const HandPointList& handpoints() const
273  {
274  throw_if_invalid_frame();
275  verify_handpoints();
276  return handPoints_;
277  }
278 
284  astra_frame_index_t frame_index() const
285  {
286  throw_if_invalid_frame();
287  return frameIndex_;
288  }
289 
290  private:
291  void throw_if_invalid_frame() const
292  {
293  if (!handFrame_) { throw std::logic_error("Cannot operate on an invalid frame"); }
294  }
295 
296  void verify_handpoints() const
297  {
298  if (handPointsInitialized_) { return; }
299  handPointsInitialized_ = true;
300 
301  astra_handpoint_t* handPtr;
302  std::uint32_t maxHandCount;
303 
304  astra_handframe_get_shared_hand_array(handFrame_, &handPtr, &maxHandCount);
305 
306  for (size_t i = 0; i < maxHandCount; ++i, ++handPtr)
307  {
308  astra_handpoint_t& p = *handPtr;
309  if (p.status != astra_handstatus_t::HAND_STATUS_NOTTRACKING)
310  {
311  handPoints_.emplace_back(HandPoint(p));
312  }
313  }
314  }
315 
316  // mutable for purposes of lazy computation
317  mutable bool handPointsInitialized_{false};
318  mutable HandPointList handPoints_;
319 
320  astra_handframe_t handFrame_{nullptr};
321  astra_frame_index_t frameIndex_;
322  };
324 }
325 
326 #endif /* ASTRA_HAND_HPP */
Data Stream
Definition: DataStream.hpp:33
A Hand Data Frame
Definition: Hand.hpp:198
const HandPointList & handpoints() const
get hand Points
Definition: Hand.hpp:272
astra_handframe_t handle() const
get handle
Definition: Hand.hpp:252
astra_frame_index_t frame_index() const
get frame index
Definition: Hand.hpp:284
size_t handpoint_count() const
get hand Points count
Definition: Hand.hpp:259
bool is_valid() const
get is valid
Definition: Hand.hpp:245
static TFrameType acquire(astra_reader_frame_t readerFrame, astra_stream_subtype_t subtype)
set is include candidate points
Definition: Hand.hpp:208
HandFrame(astra_handframe_t handFrame)
constructs
Definition: Hand.hpp:226
Hand Point struct
Definition: Hand.hpp:41
HandPoint(std::int32_t trackingId, astra_handstatus_t status, Vector2i depthPosition, Vector3f worldPosition, Vector3f worldDeltaPosition)
constructs
Definition: Hand.hpp:52
Vector3f world_position() const
get world position
Definition: Hand.hpp:131
std::int32_t tracking_id() const
get tracking id
Definition: Hand.hpp:110
astra_handstatus_t status() const
get status
Definition: Hand.hpp:117
HandPoint & operator=(const ::astra_handpoint_t &handPoint)
copy constructs
Definition: Hand.hpp:80
Vector2i depth_position() const
get depth position
Definition: Hand.hpp:124
Vector3f world_delta_position() const
get world delta position
Definition: Hand.hpp:138
HandPoint(const astra_handpoint_t &handPoint)
constructs
Definition: Hand.hpp:70
A Hand Stream
Definition: Hand.hpp:153
bool get_include_candidate_points() const
get is include candidate points
Definition: Hand.hpp:172
HandStream(astra_streamconnection_t connection)
constructs
Definition: Hand.hpp:160
void set_include_candidate_points(bool includeCandidatePoints)
set is include candidate points
Definition: Hand.hpp:184
Definition: stream_types.h:50
Definition: astra_plugin.h:24
Represents a float 2d vector
Definition: Vector2i.hpp:31
Represents a float 3d vector
Definition: Vector3f.hpp:30
Definition: hand_types.h:48