RflySimSDK v3.05
RflySimSDK说明文档
载入中...
搜索中...
未找到
vrpn_Imager.h
1// ImagerControl (should be built into Imager, because it will always
2// be the same device). The app doesn't have to use all of the
3// functions if they don't want to.
4// XXX Client can sent request for only subregion of image to be sent
5// Server may ignore this message.
6// XXX Server sets region back to total region when last connection closed.
7// XXX Client can request a frame rate from the server. This is passed on
8// to the server code as a handled message. Server should reset to the
9// default when the last connection is closed.
10// XXX Binning
11// XXX integration times
12// XXX Which data sets to send (nano)
13
14// ImagerPose (may be a separate physical device from the imager)
15// XXX Lets client request new pose for imager
16
17// XXX When transcoding to a lower-bitcount resolution, should we
18// adjust the scale and offset to make best use of the bits? Perhaps
19// a local and a global scale and offset?
20
21#ifndef VRPN_IMAGER_H
22#define VRPN_IMAGER_H
23#include <stdio.h> // for fprintf, stderr
24#include <string.h> // for NULL, memcpy
25
26#include "vrpn_BaseClass.h" // for vrpn_Callback_List, etc
27#include "vrpn_Configure.h" // for VRPN_CALLBACK, VRPN_API
28#include "vrpn_Connection.h"
29#include "vrpn_Shared.h" // for vrpn_buffer, vrpn_unbuffer, etc
30#include "vrpn_Types.h" // for vrpn_uint16, vrpn_int32, etc
31
32const unsigned vrpn_IMAGER_MAX_CHANNELS = 100;
33
37const unsigned vrpn_IMAGER_MAX_REGIONu8 =
38 (vrpn_CONNECTION_TCP_BUFLEN
39 - 8 * sizeof(vrpn_int16) // vrpn_Imager header size
40 - 6 * sizeof(vrpn_int32)) / // VRPN message header
41 sizeof(vrpn_uint8);
42const unsigned vrpn_IMAGER_MAX_REGIONu16 =
43 (vrpn_CONNECTION_TCP_BUFLEN
44 - 8 * sizeof(vrpn_int16) // vrpn_Imager header size
45 - 6 * sizeof(vrpn_int32)) / // VRPN message header
46 sizeof(vrpn_uint16);
47const unsigned vrpn_IMAGER_MAX_REGIONu12in16 = vrpn_IMAGER_MAX_REGIONu16;
48const unsigned vrpn_IMAGER_MAX_REGIONf32 =
49 (vrpn_CONNECTION_TCP_BUFLEN
50 - 8 * sizeof(vrpn_int16) // vrpn_Imager header size
51 - 6 * sizeof(vrpn_int32)) / // VRPN message header
52 sizeof(vrpn_float32);
53
56class VRPN_API vrpn_Imager_Channel {
57 friend class vrpn_Imager_Remote; // provides access to compression status
58 friend class vrpn_Imager_Server; // provides access to compression status
59 friend class vrpn_Imager_Stream_Buffer; // provides access to
60 // buffer/unbuffer
61public:
63 {
64 name[0] = '\0';
65 units[0] = '\0';
66 minVal = maxVal = 0.0;
67 scale = 1;
68 offset = 0;
69 d_compression = NONE;
70 };
71
72 vrpn_CNAME name; //< Name of the data set stored in this channel
73 vrpn_CNAME units; //< Units for the data set stored in this channel
74 vrpn_float32 minVal,
75 maxVal; //< Range of possible values for pixels in this channel
76 vrpn_float32 offset,
77 scale; //< Values in units are (raw_values * scale) + offset
78
79protected:
80 // The following methods are here for the derived classes and are not
81 // relevant
82 // to user code.
83 inline bool buffer(char **insertPt, vrpn_int32 *buflen) const
84 {
85 if (vrpn_buffer(insertPt, buflen, minVal) ||
86 vrpn_buffer(insertPt, buflen, maxVal) ||
87 vrpn_buffer(insertPt, buflen, offset) ||
88 vrpn_buffer(insertPt, buflen, scale) ||
89 vrpn_buffer(insertPt, buflen, (vrpn_uint32)d_compression) ||
90 vrpn_buffer(insertPt, buflen, name, sizeof(name)) ||
91 vrpn_buffer(insertPt, buflen, units, sizeof(units))) {
92 return false;
93 }
94 else {
95 return true;
96 }
97 }
98
99 inline bool unbuffer(const char **buffer)
100 {
101 vrpn_uint32 compression;
102 if (vrpn_unbuffer(buffer, &minVal) || vrpn_unbuffer(buffer, &maxVal) ||
103 vrpn_unbuffer(buffer, &offset) || vrpn_unbuffer(buffer, &scale) ||
104 vrpn_unbuffer(buffer, &compression) ||
105 vrpn_unbuffer(buffer, name, sizeof(name)) ||
106 vrpn_unbuffer(buffer, units, sizeof(units))) {
107 return false;
108 }
109 else {
110 d_compression = (ChannelCompression)compression;
111 return true;
112 }
113 }
114
115 typedef enum { NONE = 0 } ChannelCompression;
116 ChannelCompression d_compression;
117};
118
120class VRPN_API vrpn_Imager : public vrpn_BaseClass {
121public:
122 vrpn_Imager(const char *name, vrpn_Connection *c = NULL);
123
124 // Data member accessors.
125 vrpn_int32 nRows(void) const { return d_nRows; };
126 vrpn_int32 nCols(void) const { return d_nCols; };
127 vrpn_int32 nDepth(void) const { return d_nDepth; };
128 vrpn_int32 nChannels(void) const { return d_nChannels; };
129
130protected:
131 vrpn_int32 d_nRows; //< Number of rows in the image
132 vrpn_int32 d_nCols; //< Number of columns in the image
133 vrpn_int32 d_nDepth; //< Number of depth stacks in the image
134 vrpn_int32 d_nChannels; //< Number of image data channels
135 vrpn_Imager_Channel d_channels[vrpn_IMAGER_MAX_CHANNELS];
136
137 virtual int register_types(void);
138 vrpn_int32 d_description_m_id; //< ID of the message type describing the
139 // range and channels
140 vrpn_int32 d_begin_frame_m_id; //< ID of the message type describing the
141 // start of a region
142 vrpn_int32 d_end_frame_m_id; //< ID of the message type describing the start
143 // of a region
144 vrpn_int32 d_discarded_frames_m_id; //< ID of the message type describing
145 // the discarding of one or more regions
146 vrpn_int32 d_throttle_frames_m_id; //< ID of the message type requesting
147 // throttling of sending.
148 vrpn_int32 d_regionu8_m_id; //< ID of the message type describing a region
149 // with 8-bit unsigned entries
150 vrpn_int32 d_regionu12in16_m_id; //< ID of the message type describing a
151 // region with 12-bit unsigned entries
152 // packed in 16 bits
153 vrpn_int32 d_regionu16_m_id; //< ID of the message type describing a region
154 // with 16-bit unsigned entries
155 vrpn_int32 d_regionf32_m_id; //< ID of the message type describing a region
156 // with 32-bit float entries
157};
158
159class VRPN_API vrpn_Imager_Server : public vrpn_Imager {
160public:
161 vrpn_Imager_Server(const char *name, vrpn_Connection *c, vrpn_int32 nCols,
162 vrpn_int32 nRows, vrpn_int32 nDepth = 1);
163
166 int add_channel(const char *name, const char *units = "unsigned8bit",
167 vrpn_float32 minVal = 0, vrpn_float32 maxVal = 255,
168 vrpn_float32 scale = 1, vrpn_float32 offset = 0);
169
172 // to provide hints to the client about when to refresh displays and such.
173 // If they can determine when frames are missed, they should also send a
174 // description of missed frames, telling how many are skipped (default of
175 // zero means "some but don't know how many").
176 bool send_begin_frame(const vrpn_uint16 cMin, const vrpn_uint16 cMax,
177 const vrpn_uint16 rMin, const vrpn_uint16 rMax,
178 const vrpn_uint16 dMin = 0,
179 const vrpn_uint16 dMax = 0,
180 const struct timeval *time = NULL);
181 bool send_end_frame(const vrpn_uint16 cMin, const vrpn_uint16 cMax,
182 const vrpn_uint16 rMin, const vrpn_uint16 rMax,
183 const vrpn_uint16 dMin = 0, const vrpn_uint16 dMax = 0,
184 const struct timeval *time = NULL);
185 bool send_discarded_frames(const vrpn_uint16 count = 0,
186 const struct timeval *time = NULL);
187
190 // These functions each take a pointer to the base of the image to be sent:
191 // its [0,0] element.
192 // If rows are being inverted, then we need to know how many rows there are
193 // in the total image.
195 vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax,
196 vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_uint8 *data,
197 vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows = 0,
198 bool invert_rows = false, vrpn_uint32 depthStride = 0,
199 vrpn_uint16 dMin = 0, vrpn_uint16 dMax = 0,
200 const struct timeval *time = NULL);
201 bool send_region_using_base_pointer(
202 vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax,
203 vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_uint16 *data,
204 vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows = 0,
205 bool invert_rows = false, vrpn_uint32 depthStride = 0,
206 vrpn_uint16 dMin = 0, vrpn_uint16 dMax = 0,
207 const struct timeval *time = NULL);
208 bool send_region_using_base_pointer(
209 vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax,
210 vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_float32 *data,
211 vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows = 0,
212 bool invert_rows = false, vrpn_uint32 depthStride = 0,
213 vrpn_uint16 dMin = 0, vrpn_uint16 dMax = 0,
214 const struct timeval *time = NULL);
215
218 // These functions each take a pointer to the first of the data values to be
219 // sent. This is a
220 // pointer to the [cMin, rMin] element of the image to be sent. Note that
221 // if the Y value is inverted,
222 // this will NOT be a pointer to the beginning of the data block, but rather
223 // the the beginning of
224 // the last line in the data block. Note that rowStride will be less than
225 // the number of rows in the
226 // whole image if the data is tightly packed into a block and the region
227 // does not cover all columns.
229 vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax,
230 vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_uint8 *data,
231 vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows = 0,
232 bool invert_rows = false, vrpn_uint32 depthStride = 0,
233 vrpn_uint16 dMin = 0, vrpn_uint16 dMax = 0,
234 const struct timeval *time = NULL);
235 bool send_region_using_first_pointer(
236 vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax,
237 vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_uint16 *data,
238 vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows = 0,
239 bool invert_rows = false, vrpn_uint32 depthStride = 0,
240 vrpn_uint16 dMin = 0, vrpn_uint16 dMax = 0,
241 const struct timeval *time = NULL);
242 bool send_region_using_first_pointer(
243 vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax,
244 vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_float32 *data,
245 vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows = 0,
246 bool invert_rows = false, vrpn_uint32 depthStride = 0,
247 vrpn_uint16 dMin = 0, vrpn_uint16 dMax = 0,
248 const struct timeval *time = NULL);
249
252 bool set_resolution(vrpn_int32 nCols, vrpn_int32 nRows,
253 vrpn_int32 nDepth = 1);
254
258
260 virtual void mainloop(void);
261
262protected:
263 bool d_description_sent; //< Has the description message been sent?
264 vrpn_int32 d_frames_to_send; //< Set to -1 if continuous, zero or positive
265 // tells how many to send and then start
266 // dropping
267 vrpn_uint16 d_dropped_due_to_throttle; //< Number of frames dropped due to
268 // the throttle request
269
270 // This method makes sure we send a description whenever we get a ping from
271 // a client object.
272 static int VRPN_CALLBACK
273 handle_ping_message(void *userdata, vrpn_HANDLERPARAM p);
274
275 // This method handles requests to throttle the number of frames.
276 static int VRPN_CALLBACK
277 handle_throttle_message(void *userdata, vrpn_HANDLERPARAM p);
278 static int VRPN_CALLBACK
279 handle_last_drop_message(void *userdata, vrpn_HANDLERPARAM p);
280};
281
282class VRPN_API vrpn_ImagerPose : public vrpn_BaseClass {
283public:
284 vrpn_ImagerPose(const char *name, vrpn_Connection *c = NULL);
285
287 // the location of the corner of the (0,0,0) pixel. Note that
288 // the pixel coordinate is centered in that pixel, but that the
289 // pixel extends a half-pixel into the "negative" coordinates.
290 void get_origin(vrpn_float64 *origin) const
291 {
292 memcpy(origin, d_origin, sizeof(d_origin));
293 }
294
296 // it is how far and in what direction to go from the origin
297 // of the image to one pixel past the pixel at the end of
298 // the column that (0,0,0) is in: this is the total image
299 // width.
300 void get_dCol(vrpn_float64 *dCol) const
301 {
302 memcpy(dCol, d_dCol, sizeof(d_dCol));
303 }
304
306 // it is how far and in what direction to go from the origin
307 // of the image to one pixel past the pixel at the end of
308 // the row that (0,0,0) is in: this is the total image height.
309 void get_dRow(vrpn_float64 *dRow) const
310 {
311 memcpy(dRow, d_dRow, sizeof(d_dRow));
312 }
313
315 // it is how far and in what direction to go from the origin
316 // of the image to one pixel past the pixel at the end of
317 // the depth pixel that (0,0,0) is in: this is the total
318 // image depth.
319 void get_dDepth(vrpn_float64 *dDepth) const
320 {
321 memcpy(dDepth, d_dDepth, sizeof(d_dDepth));
322 }
323
325 // pixel within the image, assuming that the image covers the
326 // space described by this imagerpose. Note that none of the pixel
327 // centers will be at the end of the space, except where the image
328 // has no dimension (Z for a 2D image). Returns false if there is
329 // a problem (coordinates out of bounds).
330 bool compute_pixel_center(vrpn_float64 *center, const vrpn_Imager &image,
331 vrpn_uint16 col, vrpn_uint16 row,
332 vrpn_uint16 depth = 0);
333
334protected:
335 vrpn_float64 d_origin[3]; //< Origin, pixel (0,0,0) in meters
336 vrpn_float64
337 d_dCol[3]; //< End of first columne in coordinate system in meters
338 vrpn_float64 d_dRow[3]; //< End of first row in coordinate system in meters
339 vrpn_float64 d_dDepth[3]; //< End of depth in coordinate system in meters
340
341 virtual int register_types(void);
342 vrpn_int32 d_description_m_id; //< ID of the message type describing the
343 // range and channels
344};
345
347public:
348 vrpn_ImagerPose_Server(const char *name, const vrpn_float64 origin[3],
349 const vrpn_float64 dCol[3],
350 const vrpn_float64 dRow[3],
351 const vrpn_float64 *dDepth = NULL,
352 vrpn_Connection *c = NULL);
353
355 bool set_range(const vrpn_float64 origin[3], const vrpn_float64 dCol[3],
356 const vrpn_float64 dRow[3],
357 const vrpn_float64 *dDepth = NULL);
358
362
364 virtual void mainloop(void);
365
366protected:
367 // This method makes sure we send a description whenever we get a ping from
368 // a client object.
369 static int VRPN_CALLBACK
370 handle_ping_message(void *userdata, vrpn_HANDLERPARAM p);
371};
372
373//------------------------------------------------------------------------------
374// Users deal with things below this line.
375
376//------------------------------------------------------------------------------
377// Imager_Remote is used for passing image values (pixels), converting them
378// to physical units, and saying when regions are started and finished.
379
380const vrpn_uint16 vrpn_IMAGER_VALTYPE_UNKNOWN = 0;
381const vrpn_uint16 vrpn_IMAGER_VALTYPE_UINT8 = 1;
382// XXX Bad idea -- do not do this! const vrpn_uint16
383// vrpn_IMAGER_VALTYPE_UINT8RGB = 2; // Placeholder
384// XXX Bad idea -- do not do this! const vrpn_uint16
385// vrpn_IMAGER_VALTYPE_UINT8BGR = 3; // Placeholder
386const vrpn_uint16 vrpn_IMAGER_VALTYPE_UINT16 = 4;
387const vrpn_uint16 vrpn_IMAGER_VALTYPE_UINT12IN16 = 5;
388const vrpn_uint16 vrpn_IMAGER_VALTYPE_FLOAT32 = 6;
389
390class VRPN_API vrpn_Imager_Region;
391
392typedef struct _vrpn_IMAGERREGIONCB {
393 struct timeval msg_time; //< Timestamp of the region data's change
394 const vrpn_Imager_Region *region; //< New region of the image
396
397typedef void(VRPN_CALLBACK *vrpn_IMAGERREGIONHANDLER)(
398 void *userdata, const vrpn_IMAGERREGIONCB info);
399// There is no data in the description callback other than the time; the
400// data members for the class will have been filled in, so the client should
401// call nRows() and other functions to read the new values.
402typedef void(VRPN_CALLBACK *vrpn_IMAGERDESCRIPTIONHANDLER)(
403 void *userdata, const struct timeval msg_time);
404
406 struct timeval msg_time; //< Timestamp of the begin-frame message
407 vrpn_uint16 rMin; //< Minimum row in the frame
408 vrpn_uint16 rMax; //< Maximum row in the frame
409 vrpn_uint16 cMin; //< Minimum column in the frame
410 vrpn_uint16 cMax; //< Maximum column in the frame
411 vrpn_uint16 dMin; //< Minimum depth in the frame
412 vrpn_uint16 dMax; //< Maximum depth in the frame
414
416 struct timeval msg_time; //< Timestamp of the end-frame message
417 vrpn_uint16 rMin; //< Minimum row in the frame
418 vrpn_uint16 rMax; //< Maximum row in the frame
419 vrpn_uint16 cMin; //< Minimum column in the frame
420 vrpn_uint16 cMax; //< Maximum column in the frame
421 vrpn_uint16 dMin; //< Minimum depth in the frame
422 vrpn_uint16 dMax; //< Maximum depth in the frame
424
426 struct timeval msg_time; //< Timestamp of the begin-frame message
427 vrpn_uint16 count; //< Number of discarded frames (0 means "1 or more")
429
430typedef void(VRPN_CALLBACK *vrpn_IMAGERBEGINFRAMEHANDLER)(
431 void *userdata, const vrpn_IMAGERBEGINFRAMECB info);
432typedef void(VRPN_CALLBACK *vrpn_IMAGERENDFRAMEHANDLER)(
433 void *userdata, const vrpn_IMAGERENDFRAMECB info);
434typedef void(VRPN_CALLBACK *vrpn_IMAGERDISCARDEDFRAMESHANDLER)(
435 void *userdata, const vrpn_IMAGERDISCARDEDFRAMESCB info);
436
438// the image. This is passed to the user callback handler and aids in
439// getting values out of the buffer. The region is only valid during
440// the actual callback handler, so users should not store pointers to
441// it for later use.
442class VRPN_API vrpn_Imager_Region {
443 friend class VRPN_API vrpn_Imager_Remote;
444 friend void VRPN_CALLBACK
445 java_vrpn_handle_region_change(void *userdata,
446 const vrpn_IMAGERREGIONCB info);
447
448public:
450 {
451 d_chanIndex = -1;
452 d_rMin = d_rMax = d_cMin = d_cMax = 0;
453 d_valBuf = NULL;
454 d_valType = vrpn_IMAGER_VALTYPE_UNKNOWN;
455 d_valid = false;
456 }
457
459 inline vrpn_uint32 getNumVals() const
460 {
461 if (!d_valid) {
462 return 0;
463 }
464 else {
465 return (d_rMax - d_rMin + 1) * (d_cMax - d_cMin + 1);
466 }
467 }
468
473 inline bool read_unscaled_pixel(vrpn_uint16 c, vrpn_uint16 r,
474 vrpn_uint8 &val, vrpn_uint16 d = 0) const
475 {
476 if (!d_valid || (c < d_cMin) || (c > d_cMax) || (r < d_rMin) ||
477 (r > d_rMax)) {
478 fprintf(stderr, "vrpn_Imager_Region::read_unscaled_pixel(): "
479 "Invalid region or out of range\n");
480 return false;
481 }
482 else {
483 if (d_valType != vrpn_IMAGER_VALTYPE_UINT8) {
484 fprintf(stderr, "XXX "
485 "vrpn_Imager_Region::read_unscaled_pixel(): "
486 "Transcoding not implemented yet\n");
487 return false;
488 }
489 else {
490 // The data is packed in with column varying fastest, row
491 // varying next, and depth
492 // varying slowest. Depth steps are therefore the largest
493 // steps.
494 val =
495 ((const vrpn_uint8 *)
496 d_valBuf)[(c - d_cMin) +
497 (d_cMax - d_cMin + 1) *
498 ((r - d_rMin) +
499 (d - d_dMin) * (d_rMax - d_rMin + 1))];
500 }
501 }
502 return true;
503 }
504
507 // the most efficient way to read the pixels out -- use the block read
508 // routines.
509 inline bool read_unscaled_pixel(vrpn_uint16 c, vrpn_uint16 r,
510 vrpn_uint16 &val, vrpn_uint16 d = 0) const
511 {
512 if (!d_valid || (d < d_dMin) || (d > d_dMax) || (c < d_cMin) ||
513 (c > d_cMax) || (r < d_rMin) || (r > d_rMax)) {
514 fprintf(stderr, "vrpn_Imager_Region::read_unscaled_pixel(): "
515 "Invalid region or out of range\n");
516 return false;
517 }
518 else {
519 if ((d_valType != vrpn_IMAGER_VALTYPE_UINT16) &&
520 (d_valType != vrpn_IMAGER_VALTYPE_UINT12IN16)) {
521 fprintf(stderr, "XXX "
522 "vrpn_Imager_Region::read_unscaled_pixel(): "
523 "Transcoding not implemented yet\n");
524 return false;
525 }
526 else if (vrpn_big_endian) {
527 fprintf(stderr, "XXX "
528 "vrpn_Imager_Region::read_unscaled_pixel(): "
529 "Not implemented on big-endian yet\n");
530 return false;
531 }
532 else {
533 // The data is packed in with column varying fastest, row
534 // varying next, and depth
535 // varying slowest. Depth steps are therefore the largest
536 // steps.
537 val =
538 ((const vrpn_uint16 *)
539 d_valBuf)[(c - d_cMin) +
540 (d_cMax - d_cMin + 1) *
541 ((r - d_rMin) +
542 (d - d_dMin) * (d_rMax - d_rMin + 1))];
543 }
544 }
545 return true;
546 }
547
550 // the most efficient way to read the pixels out -- use the block read
551 // routines.
552 inline bool read_unscaled_pixel(vrpn_uint16 c, vrpn_uint16 r,
553 vrpn_float32 &val, vrpn_uint16 d = 0) const
554 {
555 if (!d_valid || (d < d_dMin) || (d > d_dMax) || (c < d_cMin) ||
556 (c > d_cMax) || (r < d_rMin) || (r > d_rMax)) {
557 fprintf(stderr, "vrpn_Imager_Region::read_unscaled_pixel(): "
558 "Invalid region or out of range\n");
559 return false;
560 }
561 else {
562 if (d_valType != vrpn_IMAGER_VALTYPE_FLOAT32) {
563 fprintf(stderr, "XXX "
564 "vrpn_Imager_Region::read_unscaled_pixel(): "
565 "Transcoding not implemented yet\n");
566 return false;
567 }
568 else if (vrpn_big_endian) {
569 fprintf(stderr, "XXX "
570 "vrpn_Imager_Region::read_unscaled_pixel(): "
571 "Not implemented on big-endian yet\n");
572 return false;
573 }
574 else {
575 // The data is packed in with column varying fastest, row
576 // varying next, and depth
577 // varying slowest. Depth steps are therefore the largest
578 // steps.
579 val =
580 ((const vrpn_float32 *)
581 d_valBuf)[(c - d_cMin) +
582 (d_cMax - d_cMin + 1) *
583 ((r - d_rMin) +
584 (d - d_dMin) * (d_rMax - d_rMin + 1))];
585 }
586 }
587 return true;
588 }
589
590 // Bulk read routines to copy the whole region right into user structures as
591 // efficiently as possible.
592 bool decode_unscaled_region_using_base_pointer(
593 vrpn_uint8 *data, vrpn_uint32 colStride, vrpn_uint32 rowStride,
594 vrpn_uint32 depthStride = 0, vrpn_uint16 nRows = 0,
595 bool invert_rows = false, unsigned repeat = 1) const;
596 // This routine also reads 12-bits-in-16-bit values.
597 bool decode_unscaled_region_using_base_pointer(
598 vrpn_uint16 *data, vrpn_uint32 colStride, vrpn_uint32 rowStride,
599 vrpn_uint32 depthStride = 0, vrpn_uint16 nRows = 0,
600 bool invert_rows = false, unsigned repeat = 1) const;
601 bool decode_unscaled_region_using_base_pointer(
602 vrpn_float32 *data, vrpn_uint32 colStride, vrpn_uint32 rowStride,
603 vrpn_uint32 depthStride = 0, vrpn_uint16 nRows = 0,
604 bool invert_rows = false, unsigned repeat = 1) const;
605
606 // XXX Add routines to read scaled pixels. Clamp values.
607
608 // Report the type of the values stored in the region. The above routines
609 // use this to decode automatically, but user code may want to do different
610 // things with different types of data.
611 vrpn_uint16 get_val_type(void) const { return d_valType; }
612
613 vrpn_int16 d_chanIndex; //< Which channel this region holds data for
614 vrpn_uint16 d_rMin, d_rMax; //< Range of indices for the rows
615 vrpn_uint16 d_cMin, d_cMax; //< Range of indices for the columns
616 vrpn_uint16 d_dMin, d_dMax; //< Range of indices for the depth
617
618protected:
619 const void *d_valBuf; //< Pointer to the buffer of values
620 vrpn_uint16 d_valType; //< Type of the values in the buffer
621 bool d_valid; //< Tells whether the helper can be used.
622};
623
626class VRPN_API vrpn_Imager_Remote : public vrpn_Imager {
627public:
628 vrpn_Imager_Remote(const char *name, vrpn_Connection *c = NULL);
629
632 virtual int register_region_handler(void *userdata,
633 vrpn_IMAGERREGIONHANDLER handler)
634 {
635 return d_region_list.register_handler(userdata, handler);
636 };
637 virtual int unregister_region_handler(void *userdata,
638 vrpn_IMAGERREGIONHANDLER handler)
639 {
640 return d_region_list.unregister_handler(userdata, handler);
641 }
642
645 virtual int
647 vrpn_IMAGERDESCRIPTIONHANDLER handler)
648 {
649 return d_description_list.register_handler(userdata, handler);
650 };
651 virtual int
652 unregister_description_handler(void *userdata,
653 vrpn_IMAGERDESCRIPTIONHANDLER handler)
654 {
655 return d_description_list.unregister_handler(userdata, handler);
656 }
657
659 virtual int
661 vrpn_IMAGERBEGINFRAMEHANDLER handler)
662 {
663 return d_begin_frame_list.register_handler(userdata, handler);
664 };
665 virtual int
666 unregister_begin_frame_handler(void *userdata,
667 vrpn_IMAGERBEGINFRAMEHANDLER handler)
668 {
669 return d_begin_frame_list.unregister_handler(userdata, handler);
670 }
671
673 virtual int register_end_frame_handler(void *userdata,
674 vrpn_IMAGERENDFRAMEHANDLER handler)
675 {
676 return d_end_frame_list.register_handler(userdata, handler);
677 };
678 virtual int unregister_end_frame_handler(void *userdata,
679 vrpn_IMAGERENDFRAMEHANDLER handler)
680 {
681 return d_end_frame_list.unregister_handler(userdata, handler);
682 }
683
686 virtual int
688 vrpn_IMAGERDISCARDEDFRAMESHANDLER handler)
689 {
690 return d_discarded_frames_list.register_handler(userdata, handler);
691 };
692 virtual int unregister_discarded_frames_handler(
693 void *userdata, vrpn_IMAGERDISCARDEDFRAMESHANDLER handler)
694 {
695 return d_discarded_frames_list.unregister_handler(userdata, handler);
696 }
697
700 // This is used to throttle senders that are incurring lots of latency by
701 // filling
702 // the network with packets and blocking. The next request for "N" will add
703 // onto
704 // the request. Sending "-1" means to send continuously as fast as
705 // possible,
706 // which is the default.
707 virtual bool throttle_sender(vrpn_int32 N);
708
710 // region size changed (which would be called only if the description had
711 // a different region size than the last time, and also the first time it
712 // is called) and channel changes (which would require keeping a copy of
713 // the old and diffing when a new description came in). Also, the interace
714 // could hook different callbacks for different channels IDs to let the
715 // Imager do the work of sorting out any mapping changes and keeping track
716 // of which channel is handled by which callback -- like the Tracker and its
717 // sensors. This should happen by name, rather than by index. It might be
718 // nice to provide a delete callback when a channel is removed and an add
719 // callback when a channel is added as well, and a change callback if the
720 // name, units, scale or offset change.
721
723 virtual void mainloop(void);
724
727 const vrpn_Imager_Channel *channel(unsigned chanNum) const;
728
730 bool is_description_valid() { return d_got_description; }
731
732protected:
733 bool d_got_description; //< Have we gotten a description yet?
734 // Lists to keep track of registered user handlers.
735 vrpn_Callback_List<struct timeval> d_description_list;
740
742 static int VRPN_CALLBACK
744
746 static int VRPN_CALLBACK
748
750 static int VRPN_CALLBACK
752
754 static int VRPN_CALLBACK
756
758 static int VRPN_CALLBACK
760
762 static int VRPN_CALLBACK
764};
765
766//------------------------------------------------------------------------------
767// ImagerPose_Remote deals with the physical size and location the pixels in
768// an image.
769
770typedef void(VRPN_CALLBACK *vrpn_IMAGERPOSEDESCRIPTIONHANDLER)(
771 void *userdata, const struct timeval msg_time);
772
774public:
775 vrpn_ImagerPose_Remote(const char *name, vrpn_Connection *c = NULL);
776
779 virtual int
781 vrpn_IMAGERDESCRIPTIONHANDLER handler)
782 {
783 return d_description_list.register_handler(userdata, handler);
784 };
785 virtual int
786 unregister_description_handler(void *userdata,
787 vrpn_IMAGERDESCRIPTIONHANDLER handler)
788 {
789 return d_description_list.unregister_handler(userdata, handler);
790 }
791
793 virtual void mainloop(void);
794
795protected:
796 // Lists to keep track of registered user handlers.
797 vrpn_Callback_List<struct timeval> d_description_list;
798
800 static int VRPN_CALLBACK
802};
803
804#endif
定义 vrpn_BaseClass.h:310
定义 vrpn_BaseClass.h:361
Generic connection class not specific to the transport mechanism.
定义 vrpn_Connection.h:562
定义 vrpn_Imager.h:773
virtual void mainloop(void)
Call this each time through the program's main loop
static int VRPN_CALLBACK handle_description_message(void *userdata, vrpn_HANDLERPARAM p)
Handler for resolution and channel list message from the server.
virtual int register_description_handler(void *userdata, vrpn_IMAGERDESCRIPTIONHANDLER handler)
定义 vrpn_Imager.h:780
定义 vrpn_Imager.h:346
bool send_description(void)
virtual void mainloop(void)
Handle baseclass ping/pong messages
bool set_range(const vrpn_float64 origin[3], const vrpn_float64 dCol[3], const vrpn_float64 dRow[3], const vrpn_float64 *dDepth=NULL)
Set the range or units. Return true on success.
定义 vrpn_Imager.h:282
void get_origin(vrpn_float64 *origin) const
Returns the origin of the coordinate system,
定义 vrpn_Imager.h:290
void get_dRow(vrpn_float64 *dRow) const
This is the total span of the image in rows;
定义 vrpn_Imager.h:309
virtual int register_types(void)
void get_dDepth(vrpn_float64 *dDepth) const
This is the total span of the image in depth;
定义 vrpn_Imager.h:319
void get_dCol(vrpn_float64 *dCol) const
This is the total span of the image in columns;
定义 vrpn_Imager.h:300
bool compute_pixel_center(vrpn_float64 *center, const vrpn_Imager &image, vrpn_uint16 col, vrpn_uint16 row, vrpn_uint16 depth=0)
This will return the location of the center of the specified
定义 vrpn_Imager.h:56
Helper function to convert data for a sub-region of one channel of
定义 vrpn_Imager.h:442
bool read_unscaled_pixel(vrpn_uint16 c, vrpn_uint16 r, vrpn_uint8 &val, vrpn_uint16 d=0) const
定义 vrpn_Imager.h:473
bool read_unscaled_pixel(vrpn_uint16 c, vrpn_uint16 r, vrpn_float32 &val, vrpn_uint16 d=0) const
定义 vrpn_Imager.h:552
vrpn_uint32 getNumVals() const
Returns the number of values in the region.
定义 vrpn_Imager.h:459
bool read_unscaled_pixel(vrpn_uint16 c, vrpn_uint16 r, vrpn_uint16 &val, vrpn_uint16 d=0) const
定义 vrpn_Imager.h:509
定义 vrpn_Imager.h:626
bool is_description_valid()
have we gotten a description message yet?
定义 vrpn_Imager.h:730
virtual bool throttle_sender(vrpn_int32 N)
static int VRPN_CALLBACK handle_begin_frame_message(void *userdata, vrpn_HANDLERPARAM p)
Handler for begin-frame message from the server.
virtual int register_end_frame_handler(void *userdata, vrpn_IMAGERENDFRAMEHANDLER handler)
Register a handler for frame end (if the application cares)
定义 vrpn_Imager.h:673
const vrpn_Imager_Channel * channel(unsigned chanNum) const
virtual int register_begin_frame_handler(void *userdata, vrpn_IMAGERBEGINFRAMEHANDLER handler)
Register a handler for frame beginning (if the application cares)
定义 vrpn_Imager.h:660
virtual void mainloop(void)
XXX It could be nice to let the user specify separate callbacks for
static int VRPN_CALLBACK handle_discarded_frames_message(void *userdata, vrpn_HANDLERPARAM p)
Handler for discarded-frames message from the server.
static int VRPN_CALLBACK handle_description_message(void *userdata, vrpn_HANDLERPARAM p)
Handler for resolution and channel list message from the server.
static int VRPN_CALLBACK handle_connection_dropped_message(void *userdata, vrpn_HANDLERPARAM p)
Handler for connection dropped message
static int VRPN_CALLBACK handle_region_message(void *userdata, vrpn_HANDLERPARAM p)
Handler for region update message from the server.
virtual int register_discarded_frames_handler(void *userdata, vrpn_IMAGERDISCARDEDFRAMESHANDLER handler)
定义 vrpn_Imager.h:687
virtual int register_region_handler(void *userdata, vrpn_IMAGERREGIONHANDLER handler)
定义 vrpn_Imager.h:632
static int VRPN_CALLBACK handle_end_frame_message(void *userdata, vrpn_HANDLERPARAM p)
Handler for end-frame message from the server.
virtual int register_description_handler(void *userdata, vrpn_IMAGERDESCRIPTIONHANDLER handler)
定义 vrpn_Imager.h:646
定义 vrpn_Imager.h:159
bool send_region_using_base_pointer(vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax, vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_uint8 *data, vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows=0, bool invert_rows=false, vrpn_uint32 depthStride=0, vrpn_uint16 dMin=0, vrpn_uint16 dMax=0, const struct timeval *time=NULL)
bool send_description(void)
virtual void mainloop(void)
Handle baseclass ping/pong messages
bool set_resolution(vrpn_int32 nCols, vrpn_int32 nRows, vrpn_int32 nDepth=1)
bool send_region_using_first_pointer(vrpn_int16 chanIndex, vrpn_uint16 cMin, vrpn_uint16 cMax, vrpn_uint16 rMin, vrpn_uint16 rMax, const vrpn_uint8 *data, vrpn_uint32 colStride, vrpn_uint32 rowStride, vrpn_uint16 nRows=0, bool invert_rows=false, vrpn_uint32 depthStride=0, vrpn_uint16 dMin=0, vrpn_uint16 dMax=0, const struct timeval *time=NULL)
int add_channel(const char *name, const char *units="unsigned8bit", vrpn_float32 minVal=0, vrpn_float32 maxVal=255, vrpn_float32 scale=1, vrpn_float32 offset=0)
bool send_begin_frame(const vrpn_uint16 cMin, const vrpn_uint16 cMax, const vrpn_uint16 rMin, const vrpn_uint16 rMax, const vrpn_uint16 dMin=0, const vrpn_uint16 dMax=0, const struct timeval *time=NULL)
定义 vrpn_Imager_Stream_Buffer.h:594
Base class for Imager class
定义 vrpn_Imager.h:120
virtual int register_types(void)
定义 vrpn_Imager.h:405
定义 vrpn_Imager.h:425
定义 vrpn_Imager.h:415
定义 vrpn_Imager.h:392
This structure is what is passed to a vrpn_Connection message callback.
定义 vrpn_Connection.h:41