vrpn 07.35
Virtual Reality Peripheral Network
Loading...
Searching...
No Matches
vrpn_ForceDevice.C
Go to the documentation of this file.
1// Include vrpn_Shared.h _first_ to avoid conflicts with sys/time.h
2// and unistd.h
3#include <math.h> // for sqrt
4#include <stdio.h> // for fprintf, stderr, NULL, etc
5
6#include "vrpn_Connection.h" // for vrpn_Connection, etc
7#include "vrpn_Shared.h" // for vrpn_buffer, vrpn_unbuffer, etc
8
9#if defined(linux) || defined(__sparc) || defined(hpux) || defined(__GNUC__)
10#include <string.h> // for memcpy
11#endif
12
13#include <quat.h> // for q_matrix_type, etc
14
15#include "vrpn_ForceDevice.h"
16
17/* cheezy hack to make sure this enum is defined in the case we didn't
18 include trimesh.h */
19#ifndef TRIMESH_H
20// the different types of trimeshes we have available for haptic display
22#endif
23
24#define CHECK(a) \
25 if (a == -1) return -1
26
27#if 0
28// c = a x b
29static void vector_cross (const vrpn_float64 a [3], const vrpn_float64 b [3],
30 vrpn_float64 c [3]) {
31
32 c[0] = a[1] * b[2] - a[2] * b[1];
33 c[1] = a[2] * b[0] - a[0] * b[2];
34 c[2] = a[0] * b[1] - a[1] * b[0];
35
36}
37
38// vprime = v * T
39static void rotate_vector (const vrpn_float64 v [3], const vrpn_float64 T [9],
40 vrpn_float64 vprime [3]) {
41 vprime[0] = v[0] * T[0] + v[1] * T[3] + v[2] * T[6];
42 vprime[1] = v[0] * T[1] + v[1] * T[4] + v[2] * T[7];
43 vprime[2] = v[0] * T[2] + v[1] * T[5] + v[2] * T[8];
44}
45
46static vrpn_float64 vector_dot (const vrpn_float64 a [3],
47 const vrpn_float64 b [3]) {
48 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
49}
50#endif
51
53 : vrpn_BaseClass(name, c)
54{
56
57 // set the current time to zero
58 timestamp.tv_sec = 0;
59 timestamp.tv_usec = 0;
60
61 // set the force to zero
62 // d_force[0] = d_force[1] = d_force[2] = 0.0;
63 SurfaceKspring = 0.8f;
64 SurfaceFdynamic = 0.3f;
65 SurfaceFstatic = 0.7f;
66 SurfaceKdamping = 0.001f;
67
68 numRecCycles = 1;
70
71 SurfaceKadhesionNormal = 0.0001f;
73 SurfaceBuzzFreq = 0.0003f;
74 SurfaceBuzzAmp = 0.0004f;
77
78 // ajout ONDIM
79 customEffectId = -1;
80 customEffectParams = NULL;
82 // fin ajout ONDIM
83}
84
85// ajout ONDIM
86void vrpn_ForceDevice::setCustomEffect(vrpn_int32 effectId,
87 vrpn_float32 *params,
88 vrpn_uint32 nbParams)
89{
90 customEffectId = effectId;
91 if (customEffectParams != NULL) {
92 try {
93 delete[] customEffectParams;
94 } catch (...) {
95 fprintf(stderr, "vrpn_ForceDevice::setCustomEffect(): delete failed\n");
96 return;
97 }
98 customEffectParams = NULL;
99 }
100 try { customEffectParams = new vrpn_float32[nbParams]; }
101 catch (...) {
102 fprintf(stderr, "vrpn_ForceDevice::setCustomEffect(): Out of memory\n");
103 return;
104 }
105 memcpy(customEffectParams, params, sizeof(vrpn_float32) * nbParams);
106 nbCustomEffectParams = nbParams;
107}
108// fin ajout ondim
109
111{
113 d_connection->register_message_type("vrpn_ForceDevice Force");
115 d_connection->register_message_type("vrpn_ForceDevice Force_Field");
117 d_connection->register_message_type("vrpn_ForceDevice Plane");
119 d_connection->register_message_type("vrpn_ForceDevice Plane2");
121 d_connection->register_message_type("vrpn_ForceDevice addObject");
123 "vrpn_ForceDevice addObjectExScene");
125 d_connection->register_message_type("vrpn_ForceDevice moveToParent");
127 "vrpn_ForceDevice setObjectPosition");
129 "vrpn_ForceDevice setObjectOrientation");
131 d_connection->register_message_type("vrpn_ForceDevice setObjectScale");
133 d_connection->register_message_type("vrpn_ForceDevice removeObject");
135 d_connection->register_message_type("vrpn_ForceDevice setVertex");
137 d_connection->register_message_type("vrpn_ForceDevice setNormal");
139 d_connection->register_message_type("vrpn_ForceDevice setTriangle");
141 d_connection->register_message_type("vrpn_ForceDevice removeTriangle");
143 "vrpn_ForceDevice updateTrimeshChanges");
145 "vrpn_ForceDevice transformTrimesh");
147 d_connection->register_message_type("vrpn_ForceDevice setTrimeshType");
149 d_connection->register_message_type("vrpn_ForceDevice clearTrimesh");
150
152 d_connection->register_message_type("vrpn_ForceDevice setHapticOrigin");
154 d_connection->register_message_type("vrpn_ForceDevice setHapticScale");
156 d_connection->register_message_type("vrpn_ForceDevice setSceneOrigin");
157
159 d_connection->register_message_type("vrpn_ForceDevice getNewObjectID");
161 "vrpn_ForceDevice setObjectIsTouchable");
163 d_connection->register_message_type("vrpn_ForceDevice SCP");
165 d_connection->register_message_type("vrpn_ForceDevice Force_Error");
166
168 "vrpn_ForceDevice constraint_enable");
170 d_connection->register_message_type("vrpn_ForceDevice constraint_mode");
172 "vrpn_ForceDevice constraint_point");
174 "vrpn_ForceDevice constraint_linept");
176 "vrpn_ForceDevice constraint_linedir");
178 d_connection->register_message_type("vrpn_ForceDevice constraint_plpt");
180 "vrpn_ForceDevice constraint_plnorm");
182 "vrpn_ForceDevice constraint_KSpring");
183
184 // ajout ONDIM
186 d_connection->register_message_type("vrpn_ForceDevice Custom Effect");
187 // fin ajout ONDIM
188
189 return 0;
190}
191
192// virtual
194{
195 if (customEffectParams != NULL) {
196 try {
197 delete[] customEffectParams;
198 } catch (...) {
199 fprintf(stderr, "vrpn_ForceDevice::~vrpn_ForceDevice(): delete failed\n");
200 return;
201 }
202 }
203}
204
206{
207 printf("plane: %f, %f, %f, %f\n", plane[0], plane[1], plane[2], plane[3]);
208}
209
211{
212 // Nothing sets d_force any more!
213 printf("Timestamp:%ld:%ld\n", timestamp.tv_sec,
214 static_cast<long>(timestamp.tv_usec));
215 // printf("Force :%lf, %lf, %lf\n", d_force[0],d_force[1],d_force[2]);
216}
217
218// static
219char *vrpn_ForceDevice::encode_force(vrpn_int32 &length,
220 const vrpn_float64 *force)
221{
222 // Message includes: vrpn_float64 force[3]
223 // Byte order of each needs to be reversed to match network standard
224
225 int i;
226 char *buf = NULL;
227 char *mptr;
228 vrpn_int32 mlen;
229
230 length = 3 * sizeof(vrpn_float64);
231 mlen = length;
232
233 try { buf = new char[length]; }
234 catch (...) { return NULL; }
235 mptr = buf;
236
237 // Move the force there
238 for (i = 0; i < 3; i++) {
239 vrpn_buffer(&mptr, &mlen, force[i]);
240 }
241
242 return buf;
243}
244
245// static
246vrpn_int32 vrpn_ForceDevice::decode_force(const char *buffer,
247 const vrpn_int32 len,
248 vrpn_float64 *force)
249{
250 int i;
251 const char *mptr = buffer;
252
253 if (len != (3 * sizeof(vrpn_float64))) {
254 fprintf(stderr, "vrpn_ForceDevice: force message payload error\n");
255 fprintf(stderr, " (got %d, expected %lud)\n", len,
256 static_cast<unsigned long>(3 * sizeof(vrpn_float64)));
257 return -1;
258 }
259
260 for (i = 0; i < 3; i++)
261 CHECK(vrpn_unbuffer(&mptr, &(force[i])));
262
263 return 0;
264}
265
266// ajout ONDIM
268 vrpn_uint32 effectId,
269 const vrpn_float32 *params,
270 vrpn_uint32 nbParams)
271{
272 char *buf = NULL;
273 char *mptr;
274 vrpn_int32 mlen;
275
276 len = sizeof(vrpn_uint32) * 2 + nbParams * sizeof(vrpn_float32);
277 mlen = len;
278
279 try { buf = new char[len]; }
280 catch (...) { return NULL; }
281 mptr = buf;
282
283 vrpn_buffer(&mptr, &mlen, effectId);
284 vrpn_buffer(&mptr, &mlen, nbParams);
285
286 for (unsigned int i = 0; i < nbParams; i++) {
287 vrpn_buffer(&mptr, &mlen, params[i]);
288 }
289
290 return buf;
291}
292
293// static
294vrpn_int32 vrpn_ForceDevice::decode_custom_effect(const char *buffer,
295 const vrpn_int32 len,
296 vrpn_uint32 *effectId,
297 vrpn_float32 **params,
298 vrpn_uint32 *nbParams)
299{
300 const char *mptr = buffer;
301
302 // OutputDebugString("decoding custom effect\n");
303
304 if (static_cast<size_t>(len) < (sizeof(vrpn_uint32) * 2)) {
305 fprintf(stderr,
306 "vrpn_ForceDevice: custom effect message payload error\n");
307 fprintf(stderr, " (got %d, expected at least %lud)\n", len,
308 static_cast<unsigned long>(2 * sizeof(vrpn_uint32)));
309 return -1;
310 }
311
312 CHECK(vrpn_unbuffer(&mptr, effectId));
313 CHECK(vrpn_unbuffer(&mptr, nbParams));
314
315 if ((vrpn_uint32)(len) <
316 (2 * sizeof(vrpn_uint32) + (*nbParams) * sizeof(vrpn_float32))) {
317 fprintf(stderr,
318 "vrpn_ForceDevice: custom effect message payload error\n");
319 fprintf(stderr, " (got %d, expected at least %lud)\n", len,
320 static_cast<unsigned long>(2 * sizeof(vrpn_uint32) +
321 (*nbParams) * sizeof(vrpn_float32)));
322 return -2;
323 }
324
325 if (*params != NULL) {
326 try {
327 delete[] * params;
328 } catch (...) {
329 fprintf(stderr, "vrpn_ForceDevice::decode_custom_effect(): delete failed\n");
330 return -3;
331 }
332 }
333 try { *params = new vrpn_float32[(*nbParams)]; }
334 catch (...) {
335 fprintf(stderr, "vrpn_ForceDevice::decode_custom_effect(): Out of memory\n");
336 return -4;
337 }
338
339 for (vrpn_uint32 i = 0; i < (*nbParams); i++) {
340 CHECK(vrpn_unbuffer(&mptr, &((*params)[i])));
341 }
342
343 return 0;
344}
345// fin ajout ONDIM
346
347// static
348char *vrpn_ForceDevice::encode_scp(vrpn_int32 &length, const vrpn_float64 *pos,
349 const vrpn_float64 *quat)
350{
351 int i;
352 char *buf;
353 char *mptr;
354 vrpn_int32 mlen;
355
356 length = 7 * sizeof(vrpn_float64);
357 mlen = length;
358
359 try { buf = new char[length]; }
360 catch (...) { return NULL; }
361 mptr = buf;
362
363 for (i = 0; i < 3; i++) {
364 vrpn_buffer(&mptr, &mlen, pos[i]);
365 }
366 for (i = 0; i < 4; i++) {
367 vrpn_buffer(&mptr, &mlen, quat[i]);
368 }
369
370 return buf;
371}
372
373// static
374vrpn_int32 vrpn_ForceDevice::decode_scp(const char *buffer,
375 const vrpn_int32 len, vrpn_float64 *pos,
376 vrpn_float64 *quat)
377{
378 int i;
379 const char *mptr = buffer;
380 int desiredLen = 7 * sizeof(vrpn_float64);
381
382 if (len != desiredLen) {
383 fprintf(stderr, "vrpn_ForceDevice: scp message payload error\n");
384 fprintf(stderr, " (got %d, expected %d)\n", len,
385 desiredLen);
386 return -1;
387 }
388
389 for (i = 0; i < 3; i++)
390 CHECK(vrpn_unbuffer(&mptr, &(pos[i])));
391 for (i = 0; i < 4; i++)
392 CHECK(vrpn_unbuffer(&mptr, &(quat[i])));
393
394 return 0;
395}
396
397// static
399 vrpn_int32 &len, const vrpn_float32 *plane, const vrpn_float32 kspring,
400 const vrpn_float32 kdamp, const vrpn_float32 fdyn, const vrpn_float32 fstat,
401 const vrpn_int32 plane_index, const vrpn_int32 n_rec_cycles)
402{
403 // Message includes: vrpn_float32 plane[4],
404
405 int i;
406 char *buf;
407 char *mptr;
408 vrpn_int32 mlen;
409
410 len = 8 * sizeof(vrpn_float32) + 2 * sizeof(vrpn_int32);
411 mlen = len;
412
413 try { buf = new char[len]; }
414 catch (...) { return NULL; }
415
416 mptr = buf;
417
418 for (i = 0; i < 4; i++) {
419 vrpn_buffer(&mptr, &mlen, plane[i]);
420 }
421
422 vrpn_buffer(&mptr, &mlen, kspring);
423 vrpn_buffer(&mptr, &mlen, kdamp);
424 vrpn_buffer(&mptr, &mlen, fdyn);
425 vrpn_buffer(&mptr, &mlen, fstat);
426 vrpn_buffer(&mptr, &mlen, plane_index);
427 vrpn_buffer(&mptr, &mlen, n_rec_cycles);
428
429 return buf;
430}
431
432// static
434 const char *buffer, const vrpn_int32 len, vrpn_float32 *plane,
435 vrpn_float32 *kspring, vrpn_float32 *kdamp, vrpn_float32 *fdyn,
436 vrpn_float32 *fstat, vrpn_int32 *plane_index, vrpn_int32 *n_rec_cycles)
437{
438 int i;
439 const char *mptr = buffer;
440
441 if (len != 8 * sizeof(vrpn_float32) + 2 * sizeof(vrpn_int32)) {
442 fprintf(stderr, "vrpn_ForceDevice: plane message payload error\n");
443 fprintf(stderr, " (got %d, expected %lud)\n", len,
444 static_cast<unsigned long>(8 * sizeof(vrpn_float32) +
445 2 * sizeof(vrpn_int32)));
446 return -1;
447 }
448
449 for (i = 0; i < 4; i++)
450 CHECK(vrpn_unbuffer(&mptr, &(plane[i])));
451 CHECK(vrpn_unbuffer(&mptr, kspring));
452 CHECK(vrpn_unbuffer(&mptr, kdamp));
453 CHECK(vrpn_unbuffer(&mptr, fdyn));
454 CHECK(vrpn_unbuffer(&mptr, fstat));
455 CHECK(vrpn_unbuffer(&mptr, plane_index));
456 CHECK(vrpn_unbuffer(&mptr, n_rec_cycles));
457
458 return 0;
459}
460
461// static
463 vrpn_int32 &len, const vrpn_float32 k_adhesion_normal,
464 const vrpn_float32 k_adhesion_lateral, const vrpn_float32 tex_amp,
465 const vrpn_float32 tex_wl, const vrpn_float32 buzz_amp,
466 const vrpn_float32 buzz_freq)
467{
468
469 char *buf;
470 char *mptr;
471 vrpn_int32 mlen;
472
473 len = 6 * sizeof(vrpn_float32);
474 mlen = len;
475
476 try { buf = new char[len]; }
477 catch (...) { return NULL; }
478
479 mptr = buf;
480
481 vrpn_buffer(&mptr, &mlen, k_adhesion_normal);
482 vrpn_buffer(&mptr, &mlen, k_adhesion_lateral);
483 vrpn_buffer(&mptr, &mlen, tex_amp);
484 vrpn_buffer(&mptr, &mlen, tex_wl);
485 vrpn_buffer(&mptr, &mlen, buzz_amp);
486 vrpn_buffer(&mptr, &mlen, buzz_freq);
487
488 return buf;
489}
490
491// static
493 const char *buffer, const vrpn_int32 len, vrpn_float32 *k_adhesion_normal,
494 vrpn_float32 *k_adhesion_lateral, vrpn_float32 *tex_amp,
495 vrpn_float32 *tex_wl, vrpn_float32 *buzz_amp, vrpn_float32 *buzz_freq)
496{
497
498 const char *mptr = buffer;
499
500 if (len != 6 * sizeof(vrpn_float32)) {
501 fprintf(stderr, "vrpn_ForceDevice: surface effects message payload ");
502 fprintf(stderr, "error\n (got %d, expected %lud)\n", len,
503 static_cast<unsigned long>(6 * sizeof(vrpn_float32)));
504 return -1;
505 }
506
507 CHECK(vrpn_unbuffer(&mptr, k_adhesion_normal));
508 CHECK(vrpn_unbuffer(&mptr, k_adhesion_lateral));
509 CHECK(vrpn_unbuffer(&mptr, tex_amp));
510 CHECK(vrpn_unbuffer(&mptr, tex_wl));
511 CHECK(vrpn_unbuffer(&mptr, buzz_amp));
512 CHECK(vrpn_unbuffer(&mptr, buzz_freq));
513
514 return 0;
515}
516
517// static
518char *vrpn_ForceDevice::encode_vertex(vrpn_int32 &len, const vrpn_int32 objNum,
519 const vrpn_int32 vertNum,
520 const vrpn_float32 x,
521 const vrpn_float32 y,
522 const vrpn_float32 z)
523{
524
525 char *buf;
526 char *mptr;
527 vrpn_int32 mlen;
528
529 len = sizeof(objNum) + sizeof(vertNum) + 3 * sizeof(vrpn_float32);
530 mlen = len;
531
532 try { buf = new char[len]; }
533 catch (...) { return NULL; }
534
535 mptr = buf;
536
537 vrpn_buffer(&mptr, &mlen, objNum);
538 vrpn_buffer(&mptr, &mlen, vertNum);
539 vrpn_buffer(&mptr, &mlen, x);
540 vrpn_buffer(&mptr, &mlen, y);
541 vrpn_buffer(&mptr, &mlen, z);
542
543 return buf;
544}
545
546// static
547vrpn_int32 vrpn_ForceDevice::decode_vertex(const char *buffer,
548 const vrpn_int32 len,
549 vrpn_int32 *objNum,
550 vrpn_int32 *vertNum, vrpn_float32 *x,
551 vrpn_float32 *y, vrpn_float32 *z)
552{
553 const char *mptr = buffer;
554
555 if (len != (sizeof(objNum) + sizeof(vertNum) + 3 * sizeof(vrpn_float32))) {
556 fprintf(stderr, "vrpn_ForceDevice: vertex message payload error\n");
557 fprintf(stderr, " (got %d, expected %lud)\n", len,
558 static_cast<unsigned long>(sizeof(objNum) + sizeof(vertNum) +
559 3 * sizeof(vrpn_float32)));
560 return -1;
561 }
562
563 CHECK(vrpn_unbuffer(&mptr, objNum));
564 CHECK(vrpn_unbuffer(&mptr, vertNum));
565 CHECK(vrpn_unbuffer(&mptr, x));
566 CHECK(vrpn_unbuffer(&mptr, y));
567 CHECK(vrpn_unbuffer(&mptr, z));
568
569 return 0;
570}
571
572// static
573char *vrpn_ForceDevice::encode_normal(vrpn_int32 &len, const vrpn_int32 objNum,
574 const vrpn_int32 normNum,
575 const vrpn_float32 x,
576 const vrpn_float32 y,
577 const vrpn_float32 z)
578{
579
580 char *buf;
581 char *mptr;
582 vrpn_int32 mlen;
583
584 len = sizeof(vrpn_int32) + sizeof(vrpn_int32) + 3 * sizeof(vrpn_float32);
585 mlen = len;
586
587 try { buf = new char[len]; }
588 catch (...) { return NULL; }
589
590 mptr = buf;
591 vrpn_buffer(&mptr, &mlen, objNum);
592 vrpn_buffer(&mptr, &mlen, normNum);
593 vrpn_buffer(&mptr, &mlen, x);
594 vrpn_buffer(&mptr, &mlen, y);
595 vrpn_buffer(&mptr, &mlen, z);
596
597 return buf;
598}
599
600// static
601vrpn_int32 vrpn_ForceDevice::decode_normal(const char *buffer,
602 const vrpn_int32 len,
603 vrpn_int32 *objNum,
604 vrpn_int32 *vertNum, vrpn_float32 *x,
605 vrpn_float32 *y, vrpn_float32 *z)
606{
607
608 const char *mptr = buffer;
609
610 if (len !=
611 (sizeof(vrpn_int32) + sizeof(vrpn_int32) + 3 * sizeof(vrpn_float32))) {
612 fprintf(stderr, "vrpn_ForceDevice: normal message payload error\n");
613 fprintf(stderr, " (got %d, expected %lud)\n", len,
614 static_cast<unsigned long>(sizeof(vrpn_int32) +
615 sizeof(vrpn_int32) +
616 3 * sizeof(vrpn_float32)));
617 return -1;
618 }
619
620 CHECK(vrpn_unbuffer(&mptr, objNum));
621 CHECK(vrpn_unbuffer(&mptr, vertNum));
622 CHECK(vrpn_unbuffer(&mptr, x));
623 CHECK(vrpn_unbuffer(&mptr, y));
624 CHECK(vrpn_unbuffer(&mptr, z));
625
626 return 0;
627}
628
629// static
631 vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_int32 triNum,
632 const vrpn_int32 vert0, const vrpn_int32 vert1, const vrpn_int32 vert2,
633 const vrpn_int32 norm0, const vrpn_int32 norm1, const vrpn_int32 norm2)
634{
635 char *buf;
636 char *mptr;
637 vrpn_int32 mlen;
638
639 len = sizeof(vrpn_int32) + 7 * sizeof(vrpn_int32);
640 mlen = len;
641
642 try { buf = new char[len]; }
643 catch (...) { return NULL; }
644 mptr = buf;
645
646 vrpn_buffer(&mptr, &mlen, objNum);
647 vrpn_buffer(&mptr, &mlen, triNum);
648 vrpn_buffer(&mptr, &mlen, vert0);
649 vrpn_buffer(&mptr, &mlen, vert1);
650 vrpn_buffer(&mptr, &mlen, vert2);
651 vrpn_buffer(&mptr, &mlen, norm0);
652 vrpn_buffer(&mptr, &mlen, norm1);
653 vrpn_buffer(&mptr, &mlen, norm2);
654
655 return buf;
656}
657
658// static
660 const char *buffer, const vrpn_int32 len, vrpn_int32 *objNum,
661 vrpn_int32 *triNum, vrpn_int32 *vert0, vrpn_int32 *vert1, vrpn_int32 *vert2,
662 vrpn_int32 *norm0, vrpn_int32 *norm1, vrpn_int32 *norm2)
663{
664 const char *mptr = buffer;
665
666 if (len != (sizeof(vrpn_int32) + 7 * sizeof(vrpn_int32))) {
667 fprintf(stderr, "vrpn_ForceDevice: triangle message payload error\n");
668 fprintf(stderr, " (got %d, expected %lud)\n", len,
669 static_cast<unsigned long>(sizeof(vrpn_int32) +
670 7 * sizeof(vrpn_int32)));
671 return -1;
672 }
673
674 CHECK(vrpn_unbuffer(&mptr, objNum));
675 CHECK(vrpn_unbuffer(&mptr, triNum));
676 CHECK(vrpn_unbuffer(&mptr, vert0));
677 CHECK(vrpn_unbuffer(&mptr, vert1));
678 CHECK(vrpn_unbuffer(&mptr, vert2));
679 CHECK(vrpn_unbuffer(&mptr, norm0));
680 CHECK(vrpn_unbuffer(&mptr, norm1));
681 CHECK(vrpn_unbuffer(&mptr, norm2));
682
683 return 0;
684}
685
686// static
688 const vrpn_int32 objNum,
689 const vrpn_int32 triNum)
690{
691
692 char *buf;
693 char *mptr;
694 vrpn_int32 mlen;
695
696 len = sizeof(vrpn_int32) + sizeof(vrpn_int32);
697 mlen = len;
698
699 try { buf = new char[len]; }
700 catch (...) { return NULL; }
701 mptr = buf;
702
703 vrpn_buffer(&mptr, &mlen, objNum);
704 vrpn_buffer(&mptr, &mlen, triNum);
705
706 return buf;
707}
708
709// static
710vrpn_int32 vrpn_ForceDevice::decode_removeTriangle(const char *buffer,
711 const vrpn_int32 len,
712 vrpn_int32 *objNum,
713 vrpn_int32 *triNum)
714{
715 const char *mptr = buffer;
716
717 if (len != (sizeof(vrpn_int32) + sizeof(vrpn_int32))) {
718 fprintf(stderr, "vrpn_ForceDevice: remove triangle message payload");
719 fprintf(stderr, " error\n (got %d, expected %lud)\n", len,
720 static_cast<unsigned long>(sizeof(vrpn_int32) +
721 sizeof(vrpn_int32)));
722 return -1;
723 }
724
725 CHECK(vrpn_unbuffer(&mptr, objNum));
726 CHECK(vrpn_unbuffer(&mptr, triNum));
727
728 return 0;
729}
730
731// static
732// this is where we send down our surface parameters
734 vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_float32 kspring,
735 const vrpn_float32 kdamp, const vrpn_float32 fstat, const vrpn_float32 fdyn)
736{
737
738 char *buf;
739 char *mptr;
740 vrpn_int32 mlen;
741
742 len = sizeof(vrpn_int32) + 4 * sizeof(vrpn_float32);
743 mlen = len;
744
745 try { buf = new char[len]; }
746 catch (...) { return NULL; }
747 mptr = buf;
748
749 vrpn_buffer(&mptr, &mlen, objNum);
750 vrpn_buffer(&mptr, &mlen, kspring);
751 vrpn_buffer(&mptr, &mlen, kdamp);
752 vrpn_buffer(&mptr, &mlen, fstat);
753 vrpn_buffer(&mptr, &mlen, fdyn);
754
755 return buf;
756}
757
758// static
760 const char *buffer, const vrpn_int32 len, vrpn_int32 *objNum,
761 vrpn_float32 *kspring, vrpn_float32 *kdamp, vrpn_float32 *fstat,
762 vrpn_float32 *fdyn)
763{
764
765 const char *mptr = buffer;
766
767 if (len != (sizeof(vrpn_int32) + 4 * sizeof(vrpn_float32))) {
768 fprintf(stderr, "vrpn_ForceDevice: update trimesh message payload");
769 fprintf(stderr, " error\n (got %d, expected %lud)\n", len,
770 static_cast<unsigned long>(sizeof(vrpn_int32) +
771 4 * sizeof(vrpn_float32)));
772 return -1;
773 }
774
775 CHECK(vrpn_unbuffer(&mptr, objNum));
776 CHECK(vrpn_unbuffer(&mptr, kspring));
777 CHECK(vrpn_unbuffer(&mptr, kdamp));
778 CHECK(vrpn_unbuffer(&mptr, fstat));
779 CHECK(vrpn_unbuffer(&mptr, fdyn));
780
781 return 0;
782}
783
784// static
786 const vrpn_int32 objNum,
787 const vrpn_int32 type)
788{
789
790 char *buf;
791 char *mptr;
792 vrpn_int32 mlen;
793
794 len = sizeof(vrpn_int32) + sizeof(vrpn_int32);
795 mlen = len;
796
797 try { buf = new char[len]; }
798 catch (...) { return NULL; }
799 mptr = buf;
800
801 vrpn_buffer(&mptr, &mlen, objNum);
802 vrpn_buffer(&mptr, &mlen, type);
803
804 return buf;
805}
806
807// static
808vrpn_int32 vrpn_ForceDevice::decode_setTrimeshType(const char *buffer,
809 const vrpn_int32 len,
810 vrpn_int32 *objNum,
811 vrpn_int32 *type)
812{
813
814 const char *mptr = buffer;
815
816 if (len != (sizeof(vrpn_int32) + sizeof(vrpn_int32))) {
817 fprintf(stderr, "vrpn_ForceDevice: trimesh type message payload");
818 fprintf(stderr, " error\n (got %d, expected %lud)\n", len,
819 static_cast<unsigned long>(sizeof(vrpn_int32) +
820 sizeof(vrpn_int32)));
821 return -1;
822 }
823
824 CHECK(vrpn_unbuffer(&mptr, objNum));
825 CHECK(vrpn_unbuffer(&mptr, type));
826
827 return 0;
828}
829
830// static
832 vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_float32 homMatrix[16])
833{
834 int i;
835 char *buf;
836 char *mptr;
837 vrpn_int32 mlen;
838
839 len = sizeof(vrpn_int32) + 16 * sizeof(vrpn_float32);
840 mlen = len;
841
842 try { buf = new char[len]; }
843 catch (...) { return NULL; }
844 mptr = buf;
845
846 vrpn_buffer(&mptr, &mlen, objNum);
847 for (i = 0; i < 16; i++)
848 vrpn_buffer(&mptr, &mlen, homMatrix[i]);
849
850 return buf;
851}
852
853// static
854vrpn_int32 vrpn_ForceDevice::decode_trimeshTransform(const char *buffer,
855 const vrpn_int32 len,
856 vrpn_int32 *objNum,
857 vrpn_float32 homMatrix[16])
858{
859 int i;
860 const char *mptr = buffer;
861
862 if (len != (sizeof(vrpn_int32) + 16 * sizeof(vrpn_float32))) {
863 fprintf(stderr, "vrpn_ForceDevice: trimesh transform message payload ");
864 fprintf(stderr, "error\n (got %d, expected %lud)\n", len,
865 static_cast<unsigned long>(sizeof(vrpn_int32) +
866 16 * sizeof(vrpn_float32)));
867 return -1;
868 }
869
870 CHECK(vrpn_unbuffer(&mptr, objNum));
871 for (i = 0; i < 16; i++)
872 CHECK(vrpn_unbuffer(&mptr, &(homMatrix[i])));
873
874 return 0;
875}
876
878 const vrpn_int32 objNum,
879 const vrpn_int32 ParentNum)
880{
881 char *buf;
882 char *mptr;
883 vrpn_int32 mlen;
884
885 len = 2 * sizeof(vrpn_int32);
886 mlen = len;
887
888 try { buf = new char[len]; }
889 catch (...) { return NULL; }
890 mptr = buf;
891
892 vrpn_buffer(&mptr, &mlen, objNum);
893 vrpn_buffer(&mptr, &mlen, ParentNum);
894
895 return buf;
896}
897
898vrpn_int32 vrpn_ForceDevice::decode_addObject(const char *buffer,
899 vrpn_int32 len,
900 vrpn_int32 *objNum,
901 vrpn_int32 *ParentNum)
902{
903 const char *mptr = buffer;
904
905 if (len != 2 * sizeof(vrpn_int32)) {
906 fprintf(stderr, "vrpn_ForceDevice: add object message payload ");
907 fprintf(stderr, "error\n (got %d, expected %lud)\n", len,
908 static_cast<unsigned long>(2 * sizeof(vrpn_int32)));
909 return -1;
910 }
911
912 CHECK(vrpn_unbuffer(&mptr, objNum));
913 CHECK(vrpn_unbuffer(&mptr, ParentNum));
914
915 return 0;
916}
917
919 const vrpn_int32 objNum)
920{
921 char *buf;
922 char *mptr;
923 vrpn_int32 mlen;
924
925 len = sizeof(objNum);
926 mlen = len;
927
928 try { buf = new char[len]; }
929 catch (...) { return NULL; }
930 mptr = buf;
931
932 vrpn_buffer(&mptr, &mlen, objNum);
933
934 return buf;
935}
936
937vrpn_int32 vrpn_ForceDevice::decode_addObjectExScene(const char *buffer,
938 vrpn_int32 len,
939 vrpn_int32 *objNum)
940{
941 const char *mptr = buffer;
942
943 if (len != sizeof(vrpn_int32)) {
944 fprintf(stderr, "vrpn_ForceDevice: add object message payload ");
945 fprintf(stderr, "error\n (got %d, expected %lud)\n", len,
946 static_cast<unsigned long>(sizeof(vrpn_int32)));
947 return -1;
948 }
949
950 CHECK(vrpn_unbuffer(&mptr, objNum));
951
952 return 0;
953}
954
956 const vrpn_int32 objNum,
957 const vrpn_float32 Pos[3])
958{
959 char *buf;
960 char *mptr;
961 vrpn_int32 mlen;
962
963 len = sizeof(vrpn_int32) + 3 * sizeof(vrpn_float32);
964 mlen = len;
965
966 try { buf = new char[len]; }
967 catch (...) { return NULL; }
968 mptr = buf;
969
970 vrpn_buffer(&mptr, &mlen, objNum);
971 vrpn_buffer(&mptr, &mlen, Pos[0]);
972 vrpn_buffer(&mptr, &mlen, Pos[1]);
973 vrpn_buffer(&mptr, &mlen, Pos[2]);
974
975 return buf;
976}
977
978vrpn_int32 vrpn_ForceDevice::decode_objectPosition(const char *buffer,
979 vrpn_int32 len,
980 vrpn_int32 *objNum,
981 vrpn_float32 Pos[3])
982{
983 const char *mptr = buffer;
984
985 if (len != (sizeof(vrpn_int32) + 3 * sizeof(vrpn_float32))) {
986 fprintf(stderr, "vrpn_ForceDevice: object position message payload ");
987 fprintf(stderr, "error\n (got %d, expected %lud)\n", len,
988 static_cast<unsigned long>(sizeof(vrpn_int32) +
989 3 * sizeof(vrpn_float32)));
990 return -1;
991 }
992
993 CHECK(vrpn_unbuffer(&mptr, objNum));
994 CHECK(vrpn_unbuffer(&mptr, &Pos[0]));
995 CHECK(vrpn_unbuffer(&mptr, &Pos[1]));
996 CHECK(vrpn_unbuffer(&mptr, &Pos[2]));
997
998 return 0;
999}
1000
1002 const vrpn_int32 objNum,
1003 const vrpn_float32 axis[3],
1004 const vrpn_float32 angle)
1005{
1006 char *buf;
1007 char *mptr;
1008 vrpn_int32 mlen;
1009
1010 len = sizeof(vrpn_int32) + 4 * sizeof(vrpn_float32);
1011 mlen = len;
1012
1013 try { buf = new char[len]; }
1014 catch (...) { return NULL; }
1015 mptr = buf;
1016
1017 vrpn_buffer(&mptr, &mlen, objNum);
1018 vrpn_buffer(&mptr, &mlen, axis[0]);
1019 vrpn_buffer(&mptr, &mlen, axis[1]);
1020 vrpn_buffer(&mptr, &mlen, axis[2]);
1021 vrpn_buffer(&mptr, &mlen, angle);
1022
1023 return buf;
1024}
1025
1027 vrpn_int32 len,
1028 vrpn_int32 *objNum,
1029 vrpn_float32 axis[3],
1030 vrpn_float32 *angle)
1031{
1032 const char *mptr = buffer;
1033
1034 if (len != (sizeof(vrpn_int32) + 4 * sizeof(vrpn_float32))) {
1035 fprintf(stderr,
1036 "vrpn_ForceDevice: object orientation message payload ");
1037 fprintf(stderr, "error\n (got %d, expected %lud)\n", len,
1038 static_cast<unsigned long>(sizeof(vrpn_int32) +
1039 4 * sizeof(vrpn_float32)));
1040 return -1;
1041 }
1042
1043 CHECK(vrpn_unbuffer(&mptr, objNum));
1044 CHECK(vrpn_unbuffer(&mptr, &axis[0]));
1045 CHECK(vrpn_unbuffer(&mptr, &axis[1]));
1046 CHECK(vrpn_unbuffer(&mptr, &axis[2]));
1047 CHECK(vrpn_unbuffer(&mptr, angle));
1048
1049 return 0;
1050}
1051
1053 const vrpn_int32 objNum,
1054 const vrpn_float32 Scale[3])
1055{
1056 char *buf;
1057 char *mptr;
1058 vrpn_int32 mlen;
1059
1060 len = sizeof(vrpn_int32) + 3 * sizeof(vrpn_float32);
1061 mlen = len;
1062
1063 try { buf = new char[len]; }
1064 catch (...) { return NULL; }
1065 mptr = buf;
1066
1067 vrpn_buffer(&mptr, &mlen, objNum);
1068 vrpn_buffer(&mptr, &mlen, Scale[0]);
1069 vrpn_buffer(&mptr, &mlen, Scale[1]);
1070 vrpn_buffer(&mptr, &mlen, Scale[2]);
1071
1072 return buf;
1073}
1074
1075vrpn_int32 vrpn_ForceDevice::decode_objectScale(const char *buffer,
1076 vrpn_int32 len,
1077 vrpn_int32 *objNum,
1078 vrpn_float32 Scale[3])
1079{
1080 const char *mptr = buffer;
1081
1082 if (len != (sizeof(vrpn_int32) + 3 * sizeof(vrpn_float32))) {
1083 fprintf(stderr, "vrpn_ForceDevice: object scale message payload ");
1084 fprintf(stderr, "error\n (got %d, expected %lud)\n", len,
1085 static_cast<unsigned long>(sizeof(vrpn_int32) +
1086 3 * sizeof(vrpn_float32)));
1087 return -1;
1088 }
1089
1090 CHECK(vrpn_unbuffer(&mptr, objNum));
1091 CHECK(vrpn_unbuffer(&mptr, &Scale[0]));
1092 CHECK(vrpn_unbuffer(&mptr, &Scale[1]));
1093 CHECK(vrpn_unbuffer(&mptr, &Scale[2]));
1094
1095 return 0;
1096}
1097
1099 const vrpn_int32 objNum)
1100{
1101 char *buf;
1102 char *mptr;
1103 vrpn_int32 mlen;
1104
1105 len = sizeof(vrpn_int32);
1106 mlen = len;
1107
1108 try { buf = new char[len]; }
1109 catch (...) { return NULL; }
1110 mptr = buf;
1111
1112 vrpn_buffer(&mptr, &mlen, objNum);
1113
1114 return buf;
1115}
1116
1117vrpn_int32 vrpn_ForceDevice::decode_removeObject(const char *buffer,
1118 vrpn_int32 len,
1119 vrpn_int32 *objNum)
1120{
1121 const char *mptr = buffer;
1122
1123 if (len != sizeof(vrpn_int32)) {
1124 fprintf(stderr, "vrpn_ForceDevice: remove object message payload ");
1125 fprintf(stderr, "error\n (got %d, expected %lud)\n", len,
1126 static_cast<unsigned long>(sizeof(vrpn_int32)));
1127 return -1;
1128 }
1129
1130 CHECK(vrpn_unbuffer(&mptr, objNum));
1131
1132 return 0;
1133}
1134
1136 const vrpn_int32 objNum)
1137{
1138 char *buf;
1139 char *mptr;
1140 vrpn_int32 mlen;
1141
1142 len = sizeof(vrpn_int32);
1143 mlen = len;
1144
1145 try { buf = new char[len]; }
1146 catch (...) { return NULL; }
1147 mptr = buf;
1148
1149 vrpn_buffer(&mptr, &mlen, objNum);
1150
1151 return buf;
1152}
1153
1154vrpn_int32 vrpn_ForceDevice::decode_clearTrimesh(const char *buffer,
1155 vrpn_int32 len,
1156 vrpn_int32 *objNum)
1157{
1158 const char *mptr = buffer;
1159
1160 if (len != sizeof(vrpn_int32)) {
1161 fprintf(stderr, "vrpn_ForceDevice: clear TriMesh message payload ");
1162 fprintf(stderr, "error\n (got %d, expected %lud)\n", len,
1163 static_cast<unsigned long>(sizeof(vrpn_int32)));
1164 return -1;
1165 }
1166
1167 CHECK(vrpn_unbuffer(&mptr, objNum));
1168
1169 return 0;
1170}
1171
1173 const vrpn_int32 objNum,
1174 const vrpn_int32 parentNum)
1175{
1176 char *buf;
1177 char *mptr;
1178 vrpn_int32 mlen;
1179
1180 len = sizeof(vrpn_int32) + sizeof(vrpn_int32);
1181 mlen = len;
1182
1183 try { buf = new char[len]; }
1184 catch (...) { return NULL; }
1185 mptr = buf;
1186
1187 vrpn_buffer(&mptr, &mlen, objNum);
1188 vrpn_buffer(&mptr, &mlen, parentNum);
1189
1190 return buf;
1191}
1192
1193vrpn_int32 vrpn_ForceDevice::decode_moveToParent(const char *buffer,
1194 vrpn_int32 len,
1195 vrpn_int32 *objNum,
1196 vrpn_int32 *parentNum)
1197{
1198 const char *mptr = buffer;
1199
1200 if (len != (sizeof(vrpn_int32) + sizeof(vrpn_int32))) {
1201 fprintf(stderr,
1202 "vrpn_ForceDevice: move object to parent message payload ");
1203 fprintf(stderr, "error\n (got %d, expected %lud)\n", len,
1204 static_cast<unsigned long>(sizeof(vrpn_int32) +
1205 sizeof(vrpn_int32)));
1206 return -1;
1207 }
1208
1209 CHECK(vrpn_unbuffer(&mptr, objNum));
1210 CHECK(vrpn_unbuffer(&mptr, parentNum));
1211
1212 return 0;
1213}
1214
1216 const vrpn_float32 Pos[3],
1217 const vrpn_float32 axis[3],
1218 const vrpn_float32 angle)
1219{
1220 int i;
1221 char *buf;
1222 char *mptr;
1223 vrpn_int32 mlen;
1224
1225 len = 7 * sizeof(vrpn_float32);
1226 mlen = len;
1227
1228 try { buf = new char[len]; }
1229 catch (...) { return NULL; }
1230 mptr = buf;
1231
1232 for (i = 0; i < 3; i++)
1233 vrpn_buffer(&mptr, &mlen, Pos[i]);
1234
1235 for (i = 0; i < 3; i++)
1236 vrpn_buffer(&mptr, &mlen, axis[i]);
1237
1238 vrpn_buffer(&mptr, &mlen, angle);
1239
1240 return buf;
1241}
1242
1243vrpn_int32 vrpn_ForceDevice::decode_setHapticOrigin(const char *buffer,
1244 vrpn_int32 len,
1245 vrpn_float32 Pos[3],
1246 vrpn_float32 axis[3],
1247 vrpn_float32 *angle)
1248{
1249 int i;
1250 const char *mptr = buffer;
1251
1252 if (len != 7 * sizeof(vrpn_int32)) {
1253 fprintf(stderr,
1254 "vrpn_ForceDevice: sethapticorigin message payload error\n");
1255 fprintf(stderr, " (got %d, expected %lud)\n", len,
1256 static_cast<unsigned long>(7 * sizeof(vrpn_int32)));
1257 return -1;
1258 }
1259
1260 for (i = 0; i < 3; i++)
1261 CHECK(vrpn_unbuffer(&mptr, &Pos[i]));
1262
1263 for (i = 0; i < 3; i++)
1264 CHECK(vrpn_unbuffer(&mptr, &axis[i]));
1265
1266 CHECK(vrpn_unbuffer(&mptr, angle));
1267 return 0;
1268}
1269
1271 const vrpn_float32 scale)
1272{
1273 char *buf;
1274 char *mptr;
1275 vrpn_int32 mlen;
1276
1277 len = sizeof(vrpn_float32);
1278 mlen = len;
1279
1280 try { buf = new char[len]; }
1281 catch (...) { return NULL; }
1282 mptr = buf;
1283
1284 vrpn_buffer(&mptr, &mlen, scale);
1285
1286 return buf;
1287}
1288
1289vrpn_int32 vrpn_ForceDevice::decode_setHapticScale(const char *buffer,
1290 vrpn_int32 len,
1291 vrpn_float32 *scale)
1292{
1293 const char *mptr = buffer;
1294
1295 if (len != sizeof(vrpn_float32)) {
1296 fprintf(stderr,
1297 "vrpn_ForceDevice: sethapticscale message payload error\n");
1298 fprintf(stderr, " (got %d, expected %lud)\n", len,
1299 static_cast<unsigned long>(7 * sizeof(vrpn_float32)));
1300 return -1;
1301 }
1302
1303 CHECK(vrpn_unbuffer(&mptr, scale));
1304
1305 return 0;
1306}
1307
1309 const vrpn_float32 Pos[3],
1310 const vrpn_float32 axis[3],
1311 const vrpn_float32 angle)
1312{
1313 int i;
1314 char *buf;
1315 char *mptr;
1316 vrpn_int32 mlen;
1317
1318 len = 7 * sizeof(vrpn_float32);
1319 mlen = len;
1320
1321 try { buf = new char[len]; }
1322 catch (...) { return NULL; }
1323 mptr = buf;
1324
1325 for (i = 0; i < 3; i++)
1326 vrpn_buffer(&mptr, &mlen, Pos[i]);
1327
1328 for (i = 0; i < 3; i++)
1329 vrpn_buffer(&mptr, &mlen, axis[i]);
1330
1331 vrpn_buffer(&mptr, &mlen, angle);
1332
1333 return buf;
1334}
1335
1336vrpn_int32 vrpn_ForceDevice::decode_setSceneOrigin(const char *buffer,
1337 vrpn_int32 len,
1338 vrpn_float32 Pos[3],
1339 vrpn_float32 axis[3],
1340 vrpn_float32 *angle)
1341{
1342 int i;
1343 const char *mptr = buffer;
1344
1345 if (len != 7 * sizeof(vrpn_int32)) {
1346 fprintf(stderr,
1347 "vrpn_ForceDevice: setsceneorigin message payload error\n");
1348 fprintf(stderr, " (got %d, expected %lud)\n", len,
1349 static_cast<unsigned long>(7 * sizeof(vrpn_int32)));
1350 return -1;
1351 }
1352
1353 for (i = 0; i < 3; i++)
1354 CHECK(vrpn_unbuffer(&mptr, &Pos[i]));
1355
1356 for (i = 0; i < 3; i++)
1357 CHECK(vrpn_unbuffer(&mptr, &axis[i]));
1358
1359 CHECK(vrpn_unbuffer(&mptr, angle));
1360
1361 return 0;
1362}
1363
1365 const vrpn_int32 objNum,
1366 const vrpn_bool IsTouchable)
1367{
1368 char *buf;
1369 char *mptr;
1370 vrpn_int32 mlen;
1371
1372 len = sizeof(vrpn_int32) + sizeof(vrpn_bool);
1373 mlen = len;
1374
1375 try { buf = new char[len]; }
1376 catch (...) { return NULL; }
1377 mptr = buf;
1378
1379 vrpn_buffer(&mptr, &mlen, objNum);
1380 vrpn_buffer(&mptr, &mlen, IsTouchable);
1381
1382 return buf;
1383}
1384
1386 vrpn_int32 len,
1387 vrpn_int32 *objNum,
1388 vrpn_bool *IsTouchable)
1389{
1390 const char *mptr = buffer;
1391
1392 if (len != (sizeof(vrpn_int32) + sizeof(vrpn_bool))) {
1393 fprintf(stderr, "vrpn_ForceDevice: set object is touchable message "
1394 "payload error\n");
1395 fprintf(
1396 stderr, " (got %d, expected %lud)\n", len,
1397 static_cast<unsigned long>(sizeof(vrpn_int32) + sizeof(vrpn_bool)));
1398 return -1;
1399 }
1400
1401 CHECK(vrpn_unbuffer(&mptr, objNum));
1402 CHECK(vrpn_unbuffer(&mptr, IsTouchable));
1403
1404 return 0;
1405}
1406
1407// static
1409 const vrpn_float32 origin[3],
1410 const vrpn_float32 force[3],
1411 const vrpn_float32 jacobian[3][3],
1412 const vrpn_float32 radius)
1413{
1414 int i, j;
1415 char *buf;
1416 char *mptr;
1417 vrpn_int32 mlen;
1418
1419 len = 16 * sizeof(vrpn_float32);
1420 mlen = len;
1421
1422 try { buf = new char[len]; }
1423 catch (...) { return NULL; }
1424 mptr = buf;
1425
1426 for (i = 0; i < 3; i++)
1427 vrpn_buffer(&mptr, &mlen, origin[i]);
1428
1429 for (i = 0; i < 3; i++)
1430 vrpn_buffer(&mptr, &mlen, force[i]);
1431
1432 for (i = 0; i < 3; i++)
1433 for (j = 0; j < 3; j++)
1434 vrpn_buffer(&mptr, &mlen, jacobian[i][j]);
1435
1436 vrpn_buffer(&mptr, &mlen, radius);
1437
1438 return buf;
1439}
1440
1441// static
1443 const char *buffer, const vrpn_int32 len, vrpn_float32 origin[3],
1444 vrpn_float32 force[3], vrpn_float32 jacobian[3][3], vrpn_float32 *radius)
1445{
1446 int i, j;
1447 const char *mptr = buffer;
1448
1449 if (len != 16 * sizeof(vrpn_float32)) {
1450 fprintf(stderr,
1451 "vrpn_ForceDevice: force field message payload error\n");
1452 fprintf(stderr, " (got %d, expected %lud)\n", len,
1453 static_cast<unsigned long>(16 * sizeof(vrpn_float32)));
1454 return -1;
1455 }
1456
1457 for (i = 0; i < 3; i++)
1458 CHECK(vrpn_unbuffer(&mptr, &(origin[i])));
1459
1460 for (i = 0; i < 3; i++)
1461 CHECK(vrpn_unbuffer(&mptr, &(force[i])));
1462
1463 for (i = 0; i < 3; i++)
1464 for (j = 0; j < 3; j++)
1465 CHECK(vrpn_unbuffer(&mptr, &(jacobian[i][j])));
1466
1467 CHECK(vrpn_unbuffer(&mptr, radius));
1468
1469 return 0;
1470}
1471
1473 const vrpn_int32 error_code)
1474{
1475
1476 char *buf;
1477 char *mptr;
1478 vrpn_int32 mlen;
1479
1480 len = sizeof(vrpn_int32);
1481 mlen = len;
1482
1483 try { buf = new char[len]; }
1484 catch (...) { return NULL; }
1485 mptr = buf;
1486
1487 vrpn_buffer(&mptr, &mlen, error_code);
1488
1489 return buf;
1490}
1491
1492vrpn_int32 vrpn_ForceDevice::decode_error(const char *buffer,
1493 const vrpn_int32 len,
1494 vrpn_int32 *error_code)
1495{
1496
1497 const char *mptr = buffer;
1498
1499 if (len != sizeof(vrpn_int32)) {
1500 fprintf(stderr, "vrpn_ForceDevice: error message payload error\n");
1501 fprintf(stderr, " (got %d, expected %lud)\n", len,
1502 static_cast<unsigned long>(sizeof(vrpn_int32)));
1503 return -1;
1504 }
1505
1506 CHECK(vrpn_unbuffer(&mptr, error_code));
1507
1508 return 0;
1509}
1510
1511void vrpn_ForceDevice::set_plane(vrpn_float32 *p)
1512{
1513 for (int i = 0; i < 4; i++) {
1514 plane[i] = p[i];
1515 }
1516}
1517
1518void vrpn_ForceDevice::set_plane(vrpn_float32 a, vrpn_float32 b, vrpn_float32 c,
1519 vrpn_float32 d)
1520{
1521 plane[0] = a;
1522 plane[1] = b;
1523 plane[2] = c;
1524 plane[3] = d;
1525}
1526
1527void vrpn_ForceDevice::set_plane(vrpn_float32 *normal, vrpn_float32 d)
1528{
1529 for (int i = 0; i < 3; i++) {
1530 plane[i] = normal[i];
1531 }
1532
1533 plane[3] = d;
1534}
1535
1537{
1538 char *msgbuf;
1539 vrpn_int32 len;
1540 struct timeval current_time;
1541
1542 vrpn_gettimeofday(&current_time, NULL);
1543 timestamp.tv_sec = current_time.tv_sec;
1544 timestamp.tv_usec = current_time.tv_usec;
1545
1546 if (d_connection) {
1547 msgbuf = encode_error(len, error_code);
1549 d_sender_id, msgbuf,
1551 fprintf(stderr, "Phantom: cannot write message: tossing\n");
1552 }
1553 try {
1554 delete[] msgbuf;
1555 } catch (...) {
1556 fprintf(stderr, "vrpn_ForceDevice::sendError(): delete failed\n");
1557 return;
1558 }
1559 }
1560}
1561
1562// constraint message encode/decode methods
1563
1564// static
1566 vrpn_int32 enable)
1567{
1568 char *buf;
1569 char *mptr;
1570 vrpn_int32 mlen;
1571
1572 len = sizeof(vrpn_int32);
1573 mlen = len;
1574
1575 try { buf = new char[len]; }
1576 catch (...) { return NULL; }
1577 mptr = buf;
1578
1579 vrpn_buffer(&mptr, &mlen, enable);
1580
1581 return buf;
1582}
1583
1584// static
1585vrpn_int32 vrpn_ForceDevice::decode_enableConstraint(const char *buffer,
1586 const vrpn_int32 len,
1587 vrpn_int32 *enable)
1588{
1589 const char *mptr = buffer;
1590
1591 if (len != sizeof(vrpn_int32)) {
1592 fprintf(stderr, "vrpn_ForceDevice: "
1593 "enable constraint message payload error\n"
1594 " (got %d, expected %lud)\n",
1595 len, static_cast<unsigned long>(sizeof(vrpn_int32)));
1596 return -1;
1597 }
1598
1599 CHECK(vrpn_unbuffer(&mptr, enable));
1600
1601 return 0;
1602}
1603
1604// static
1606 ConstraintGeometry mode)
1607{
1608 char *buf;
1609 char *mptr;
1610 vrpn_int32 modeint;
1611 vrpn_int32 mlen;
1612
1613 len = sizeof(vrpn_int32);
1614 mlen = len;
1615
1616 try { buf = new char[len]; }
1617 catch (...) { return NULL; }
1618 mptr = buf;
1619
1620 switch (mode) {
1621 case NO_CONSTRAINT:
1622 modeint = 0;
1623 break;
1624 case POINT_CONSTRAINT:
1625 modeint = 1;
1626 break;
1627 case LINE_CONSTRAINT:
1628 modeint = 2;
1629 break;
1630 case PLANE_CONSTRAINT:
1631 modeint = 3;
1632 break;
1633 default:
1634 fprintf(stderr, "vrpn_ForceDevice: "
1635 "Unknown or illegal constraint mode.\n");
1636 modeint = 0;
1637 break;
1638 }
1639
1640 vrpn_buffer(&mptr, &mlen, modeint);
1641
1642 return buf;
1643}
1644
1645// static
1647 const vrpn_int32 len,
1648 ConstraintGeometry *mode)
1649{
1650 const char *mptr = buffer;
1651 vrpn_int32 modeint;
1652
1653 if (len != sizeof(vrpn_int32)) {
1654 fprintf(stderr, "vrpn_ForceDevice: "
1655 "constraint mode payload error\n"
1656 " (got %d, expected %lud)\n",
1657 len, static_cast<unsigned long>(sizeof(vrpn_int32)));
1658 return -1;
1659 }
1660
1661 CHECK(vrpn_unbuffer(&mptr, &modeint));
1662
1663 switch (modeint) {
1664 case 0:
1665 *mode = NO_CONSTRAINT;
1666 break;
1667 case 1:
1668 *mode = POINT_CONSTRAINT;
1669 break;
1670 case 2:
1671 *mode = LINE_CONSTRAINT;
1672 break;
1673 case 3:
1674 *mode = PLANE_CONSTRAINT;
1675 break;
1676 default:
1677 fprintf(stderr, "vrpn_ForceDevice: "
1678 "Unknown or illegal constraint mode.\n");
1679 *mode = NO_CONSTRAINT;
1680 return -1;
1681 }
1682
1683 return 0;
1684}
1685
1686// static
1688 vrpn_float32 x,
1689 vrpn_float32 y,
1690 vrpn_float32 z)
1691{
1692 return encodePoint(len, x, y, z);
1693}
1694
1695// static
1697 const vrpn_int32 len,
1698 vrpn_float32 *x,
1699 vrpn_float32 *y,
1700 vrpn_float32 *z)
1701{
1702 return decodePoint(buffer, len, x, y, z);
1703}
1704
1705// static
1707 vrpn_float32 x,
1708 vrpn_float32 y,
1709 vrpn_float32 z)
1710{
1711 return encodePoint(len, x, y, z);
1712}
1713
1714// static
1716 const vrpn_int32 len,
1717 vrpn_float32 *x,
1718 vrpn_float32 *y,
1719 vrpn_float32 *z)
1720{
1721 return decodePoint(buffer, len, x, y, z);
1722}
1723
1724// static
1726 vrpn_float32 x,
1727 vrpn_float32 y,
1728 vrpn_float32 z)
1729{
1730 return encodePoint(len, x, y, z);
1731}
1732
1733// static
1735 const char *buffer, const vrpn_int32 len, vrpn_float32 *x, vrpn_float32 *y,
1736 vrpn_float32 *z)
1737{
1738 return decodePoint(buffer, len, x, y, z);
1739}
1740
1741// static
1743 vrpn_float32 x,
1744 vrpn_float32 y,
1745 vrpn_float32 z)
1746{
1747 return encodePoint(len, x, y, z);
1748}
1749
1750// static
1752 const char *buffer, const vrpn_int32 len, vrpn_float32 *x, vrpn_float32 *y,
1753 vrpn_float32 *z)
1754{
1755 return decodePoint(buffer, len, x, y, z);
1756}
1757
1758// static
1760 vrpn_float32 x,
1761 vrpn_float32 y,
1762 vrpn_float32 z)
1763{
1764 return encodePoint(len, x, y, z);
1765}
1766
1767// static
1769 const char *buffer, const vrpn_int32 len, vrpn_float32 *x, vrpn_float32 *y,
1770 vrpn_float32 *z)
1771{
1772 return decodePoint(buffer, len, x, y, z);
1773}
1774
1775// static
1777 vrpn_float32 k)
1778{
1779 char *buf;
1780 char *mptr;
1781 vrpn_int32 mlen;
1782
1783 len = sizeof(vrpn_float32);
1784 mlen = len;
1785
1786 try { buf = new char[len]; }
1787 catch (...) { return NULL; }
1788 mptr = buf;
1789
1790 vrpn_buffer(&mptr, &mlen, k);
1791
1792 return buf;
1793}
1794
1795// static
1797 const vrpn_int32 len,
1798 vrpn_float32 *k)
1799{
1800 const char *mptr = buffer;
1801
1802 if (len != sizeof(vrpn_float32)) {
1803 fprintf(stderr, "vrpn_ForceDevice: "
1804 "set constraint spring message payload error\n"
1805 " (got %d, expected %lud)\n",
1806 len, static_cast<unsigned long>(sizeof(vrpn_float32)));
1807 return -1;
1808 }
1809
1810 CHECK(vrpn_unbuffer(&mptr, k));
1811
1812 return 0;
1813}
1814
1815//
1816// utility functions
1817//
1818
1819// static
1820char *vrpn_ForceDevice::encodePoint(vrpn_int32 &len, vrpn_float32 x,
1821 vrpn_float32 y, vrpn_float32 z)
1822{
1823 char *buf;
1824 char *mptr;
1825 vrpn_int32 mlen;
1826
1827 len = 3 * sizeof(vrpn_float32);
1828 mlen = len;
1829
1830 try { buf = new char[len]; }
1831 catch (...) { return NULL; }
1832 mptr = buf;
1833
1834 vrpn_buffer(&mptr, &mlen, x);
1835 vrpn_buffer(&mptr, &mlen, y);
1836 vrpn_buffer(&mptr, &mlen, z);
1837
1838 return buf;
1839}
1840
1841// static
1842vrpn_int32 vrpn_ForceDevice::decodePoint(const char *buffer,
1843 const vrpn_int32 len, vrpn_float32 *x,
1844 vrpn_float32 *y, vrpn_float32 *z)
1845{
1846 const char *mptr = buffer;
1847
1848 if (len != 3 * sizeof(vrpn_float32)) {
1849 fprintf(stderr, "vrpn_ForceDevice: "
1850 "decode point message payload error\n"
1851 " (got size %d, expected %lud)\n",
1852 len, static_cast<unsigned long>(3 * sizeof(vrpn_float32)));
1853 return -1;
1854 }
1855
1856 CHECK(vrpn_unbuffer(&mptr, x));
1857 CHECK(vrpn_unbuffer(&mptr, y));
1858 CHECK(vrpn_unbuffer(&mptr, z));
1859
1860 return 0;
1861}
1862
1863/* ******************** vrpn_ForceDevice_Remote ********************** */
1864
1866 vrpn_Connection *cn)
1867 : vrpn_ForceDevice(name, cn)
1868 , d_conEnabled(0)
1869 , d_conMode(POINT_CONSTRAINT)
1870{
1871 which_plane = 0;
1872
1873 // Make sure that we have a valid connection
1874 if (d_connection == NULL) {
1875 fprintf(stderr, "vrpn_ForceDevice_Remote: No connection\n");
1876 return;
1877 }
1878
1879 // Register a handler for the change callback from this device.
1882 fprintf(stderr, "vrpn_ForceDevice_Remote:can't register handler\n");
1883 d_connection = NULL;
1884 }
1885
1886 // Register a handler for the scp change callback from this device.
1888 this, d_sender_id)) {
1889 fprintf(stderr, "vrpn_ForceDevice_Remote:can't register handler\n");
1890 d_connection = NULL;
1891 }
1892
1893 // Register a handler for the error change callback from this device.
1896 fprintf(stderr, "vrpn_ForceDevice_Remote:can't register handler\n");
1897 d_connection = NULL;
1898 }
1899
1900 // Find out what time it is and put this into the timestamp
1902}
1903
1904// virtual
1906
1908{ // Encode the plane if there is a connection
1909 char *msgbuf;
1910 vrpn_int32 len;
1911 struct timeval current_time;
1912
1913 vrpn_gettimeofday(&current_time, NULL);
1914 timestamp.tv_sec = current_time.tv_sec;
1915 timestamp.tv_usec = current_time.tv_usec;
1916
1917 if (d_connection) {
1920 numRecCycles);
1922 d_sender_id, msgbuf,
1924 fprintf(stderr, "Phantom: cannot write message: tossing\n");
1925 }
1926 try {
1927 delete[] msgbuf;
1928 } catch (...) {
1929 fprintf(stderr, "vrpn_ForceDevice::sendSurface(): delete failed\n");
1930 return;
1931 }
1932
1933 msgbuf = encode_surface_effects(
1938 d_sender_id, msgbuf,
1940 fprintf(stderr, "Phantom: cannot write message: tossing\n");
1941 }
1942 try {
1943 delete[] msgbuf;
1944 } catch (...) {
1945 fprintf(stderr, "vrpn_ForceDevice::sendSurface(): delete failed\n");
1946 return;
1947 }
1948 }
1949}
1950
1952{ // Encode the plane if there is a connection
1953 char *msgbuf;
1954 vrpn_int32 len;
1955 struct timeval current_time;
1956
1957 vrpn_gettimeofday(&current_time, NULL);
1958 timestamp.tv_sec = current_time.tv_sec;
1959 timestamp.tv_usec = current_time.tv_usec;
1960
1961 if (d_connection) {
1964 numRecCycles);
1966 d_sender_id, msgbuf,
1968 fprintf(stderr, "Phantom: cannot write message: tossing\n");
1969 }
1970 try {
1971 delete[] msgbuf;
1972 } catch (...) {
1973 fprintf(stderr, "vrpn_ForceDevice::startSurface(): delete failed\n");
1974 return;
1975 }
1976 }
1977}
1978
1980{ // Encode the plane if there is a connection
1981 char *msgbuf;
1982 vrpn_int32 len;
1983 struct timeval current_time;
1984
1985 vrpn_gettimeofday(&current_time, NULL);
1986 timestamp.tv_sec = current_time.tv_sec;
1987 timestamp.tv_usec = current_time.tv_usec;
1988
1989 set_plane(0, 0, 0, 0);
1990
1991 if (d_connection) {
1994 numRecCycles);
1996 d_sender_id, msgbuf,
1998 fprintf(stderr, "Phantom: cannot write message: tossing\n");
1999 }
2000 try {
2001 delete[] msgbuf;
2002 } catch (...) {
2003 fprintf(stderr, "vrpn_ForceDevice::stopSurface(): delete failed\n");
2004 return;
2005 }
2006 }
2007}
2008
2009void vrpn_ForceDevice_Remote::setVertex(vrpn_int32 vertNum, vrpn_float32 x,
2010 vrpn_float32 y, vrpn_float32 z)
2011{
2012 setObjectVertex(0, vertNum, x, y, z);
2013}
2014
2015void vrpn_ForceDevice_Remote::setNormal(vrpn_int32 normNum, vrpn_float32 x,
2016 vrpn_float32 y, vrpn_float32 z)
2017{
2018 setObjectNormal(0, normNum, x, y, z);
2019}
2020
2021void vrpn_ForceDevice_Remote::setTriangle(vrpn_int32 triNum, vrpn_int32 vert0,
2022 vrpn_int32 vert1, vrpn_int32 vert2,
2023 vrpn_int32 norm0, vrpn_int32 norm1,
2024 vrpn_int32 norm2)
2025{
2026 setObjectTriangle(0, triNum, vert0, vert1, vert2, norm0, norm1, norm2);
2027}
2028
2030{
2031 removeObjectTriangle(0, triNum);
2032}
2033
2035{
2037}
2038
2039// set the trimesh's homogen transform matrix (in row major order)
2040void vrpn_ForceDevice_Remote::setTrimeshTransform(vrpn_float32 homMatrix[16])
2041{
2042 setObjectTrimeshTransform(0, homMatrix);
2043}
2044
2045// clear the triMesh if connection
2047
2050// Add an object to the haptic scene as root (parent -1 = default) or as child
2051// (ParentNum =the number of the parent)
2053 vrpn_int32 ParentNum /*=-1*/)
2054{
2055 char *msgbuf;
2056 vrpn_int32 len;
2057 struct timeval current_time;
2058
2059 if (objNum > m_NextAvailableObjectID) m_NextAvailableObjectID = objNum + 1;
2060
2061 vrpn_gettimeofday(&current_time, NULL);
2062 timestamp.tv_sec = current_time.tv_sec;
2063 timestamp.tv_usec = current_time.tv_usec;
2064
2065 if (d_connection) {
2066 msgbuf = encode_addObject(len, objNum, ParentNum);
2068 d_sender_id, msgbuf,
2070 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2071 }
2072 try {
2073 delete[] msgbuf;
2074 } catch (...) {
2075 fprintf(stderr, "vrpn_ForceDevice::addObject(): delete failed\n");
2076 return;
2077 }
2078 }
2079}
2080
2081// Add an object next to the haptic scene as root
2083{
2084 char *msgbuf;
2085 vrpn_int32 len;
2086 struct timeval current_time;
2087
2088 if (objNum > m_NextAvailableObjectID) m_NextAvailableObjectID = objNum + 1;
2089
2090 vrpn_gettimeofday(&current_time, NULL);
2091 timestamp.tv_sec = current_time.tv_sec;
2092 timestamp.tv_usec = current_time.tv_usec;
2093
2094 if (d_connection) {
2095 msgbuf = encode_addObjectExScene(len, objNum);
2098 msgbuf, vrpn_CONNECTION_RELIABLE)) {
2099 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2100 }
2101 try {
2102 delete[] msgbuf;
2103 } catch (...) {
2104 fprintf(stderr, "vrpn_ForceDevice::addObectExScene(): delete failed\n");
2105 return;
2106 }
2107 }
2108}
2109
2110// vertNum normNum and triNum start at 0
2112 vrpn_int32 vertNum,
2113 vrpn_float32 x, vrpn_float32 y,
2114 vrpn_float32 z)
2115{
2116 char *msgbuf;
2117 vrpn_int32 len;
2118 struct timeval current_time;
2119
2120 vrpn_gettimeofday(&current_time, NULL);
2121 timestamp.tv_sec = current_time.tv_sec;
2122 timestamp.tv_usec = current_time.tv_usec;
2123
2124 if (d_connection) {
2125 msgbuf = encode_vertex(len, objNum, vertNum, x, y, z);
2127 d_sender_id, msgbuf,
2129 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2130 }
2131 try {
2132 delete[] msgbuf;
2133 } catch (...) {
2134 fprintf(stderr, "vrpn_ForceDevice::setObjVert(): delete failed\n");
2135 return;
2136 }
2137 }
2138}
2139
2140// NOTE: ghost doesn't take normals,
2141// and normals still aren't implemented for Hcollide
2143 vrpn_int32 normNum,
2144 vrpn_float32 x, vrpn_float32 y,
2145 vrpn_float32 z)
2146{
2147 char *msgbuf;
2148 vrpn_int32 len;
2149 struct timeval current_time;
2150
2151 vrpn_gettimeofday(&current_time, NULL);
2152 timestamp.tv_sec = current_time.tv_sec;
2153 timestamp.tv_usec = current_time.tv_usec;
2154
2155 if (d_connection) {
2156 msgbuf = encode_normal(len, objNum, normNum, x, y, z);
2158 d_sender_id, msgbuf,
2160 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2161 }
2162 try {
2163 delete[] msgbuf;
2164 } catch (...) {
2165 fprintf(stderr, "vrpn_ForceDevice::setObjectNormal(): delete failed\n");
2166 return;
2167 }
2168 }
2169}
2170
2172 vrpn_int32 objNum, vrpn_int32 triNum, vrpn_int32 vert0, vrpn_int32 vert1,
2173 vrpn_int32 vert2, vrpn_int32 norm0 /*=-1*/, vrpn_int32 norm1 /*=-1*/,
2174 vrpn_int32 norm2 /*=-1*/)
2175{
2176 char *msgbuf;
2177 vrpn_int32 len;
2178 struct timeval current_time;
2179
2180 vrpn_gettimeofday(&current_time, NULL);
2181 timestamp.tv_sec = current_time.tv_sec;
2182 timestamp.tv_usec = current_time.tv_usec;
2183
2184 if (d_connection) {
2185 msgbuf = encode_triangle(len, objNum, triNum, vert0, vert1, vert2,
2186 norm0, norm1, norm2);
2188 d_sender_id, msgbuf,
2190 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2191 }
2192 try {
2193 delete[] msgbuf;
2194 } catch (...) {
2195 fprintf(stderr, "vrpn_ForceDevice::setObjectTriangle(): delete failed\n");
2196 return;
2197 }
2198 }
2199}
2200
2202 vrpn_int32 triNum)
2203{
2204 char *msgbuf;
2205 vrpn_int32 len;
2206 struct timeval current_time;
2207
2208 vrpn_gettimeofday(&current_time, NULL);
2209 timestamp.tv_sec = current_time.tv_sec;
2210 timestamp.tv_usec = current_time.tv_usec;
2211
2212 if (d_connection) {
2213 msgbuf = encode_removeTriangle(len, objNum, triNum);
2216 msgbuf, vrpn_CONNECTION_RELIABLE)) {
2217 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2218 }
2219 try {
2220 delete[] msgbuf;
2221 } catch (...) {
2222 fprintf(stderr, "vrpn_ForceDevice::removeObjectTriangle(): delete failed\n");
2223 return;
2224 }
2225 }
2226}
2227
2228// should be called to incorporate the above changes into the
2229// displayed trimesh
2231{
2232 char *msgbuf;
2233 vrpn_int32 len;
2234 struct timeval current_time;
2235
2236 vrpn_gettimeofday(&current_time, NULL);
2237 timestamp.tv_sec = current_time.tv_sec;
2238 timestamp.tv_usec = current_time.tv_usec;
2239
2240 if (d_connection) {
2241 msgbuf = encode_updateTrimeshChanges(len, objNum, SurfaceKspring,
2246 msgbuf, vrpn_CONNECTION_RELIABLE)) {
2247 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2248 }
2249 try {
2250 delete[] msgbuf;
2251 } catch (...) {
2252 fprintf(stderr, "vrpn_ForceDevice::updateObjectTrimeshChanges(): delete failed\n");
2253 return;
2254 }
2255 }
2256}
2257
2258// set the trimesh's homogen transform matrix (in row major order)
2260 vrpn_int32 objNum, vrpn_float32 homMatrix[16])
2261{
2262 char *msgbuf;
2263 vrpn_int32 len;
2264 struct timeval current_time;
2265
2266 vrpn_gettimeofday(&current_time, NULL);
2267 timestamp.tv_sec = current_time.tv_sec;
2268 timestamp.tv_usec = current_time.tv_usec;
2269
2270 if (d_connection) {
2271 msgbuf = encode_trimeshTransform(len, objNum, homMatrix);
2274 msgbuf, vrpn_CONNECTION_RELIABLE)) {
2275 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2276 }
2277 try {
2278 delete[] msgbuf;
2279 } catch (...) {
2280 fprintf(stderr, "vrpn_ForceDevice::setObjectTrimeshTransform(): delete failed\n");
2281 return;
2282 }
2283 }
2284}
2285
2286// set position of an object
2288 vrpn_float32 Pos[3])
2289{
2290 char *msgbuf;
2291 vrpn_int32 len;
2292 struct timeval current_time;
2293
2294 vrpn_gettimeofday(&current_time, NULL);
2295 timestamp.tv_sec = current_time.tv_sec;
2296 timestamp.tv_usec = current_time.tv_usec;
2297
2298 if (d_connection) {
2299 msgbuf = encode_objectPosition(len, objNum, Pos);
2302 msgbuf, vrpn_CONNECTION_RELIABLE)) {
2303 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2304 }
2305 try {
2306 delete[] msgbuf;
2307 } catch (...) {
2308 fprintf(stderr, "vrpn_ForceDevice::setObjectPosition(): delete failed\n");
2309 return;
2310 }
2311 }
2312}
2313
2314// set orientation of an object
2316 vrpn_float32 axis[3],
2317 vrpn_float32 angle)
2318{
2319 char *msgbuf;
2320 vrpn_int32 len;
2321 struct timeval current_time;
2322
2323 vrpn_gettimeofday(&current_time, NULL);
2324 timestamp.tv_sec = current_time.tv_sec;
2325 timestamp.tv_usec = current_time.tv_usec;
2326
2327 if (d_connection) {
2328 msgbuf = encode_objectOrientation(len, objNum, axis, angle);
2331 msgbuf, vrpn_CONNECTION_RELIABLE)) {
2332 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2333 }
2334 try {
2335 delete[] msgbuf;
2336 } catch (...) {
2337 fprintf(stderr, "vrpn_ForceDevice::setObjectOrientation(): delete failed\n");
2338 return;
2339 }
2340 }
2341}
2342
2343// set Scale of an object
2345 vrpn_float32 Scale[3])
2346{
2347 char *msgbuf;
2348 vrpn_int32 len;
2349 struct timeval current_time;
2350
2351 vrpn_gettimeofday(&current_time, NULL);
2352 timestamp.tv_sec = current_time.tv_sec;
2353 timestamp.tv_usec = current_time.tv_usec;
2354
2355 if (d_connection) {
2356 msgbuf = encode_objectScale(len, objNum, Scale);
2359 msgbuf, vrpn_CONNECTION_RELIABLE)) {
2360 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2361 }
2362 try {
2363 delete[] msgbuf;
2364 } catch (...) {
2365 fprintf(stderr, "vrpn_ForceDevice::setObjectScale(): delete failed\n");
2366 return;
2367 }
2368 }
2369}
2370
2371// remove an object from the scene
2373{
2374 char *msgbuf;
2375 vrpn_int32 len;
2376 struct timeval current_time;
2377
2378 vrpn_gettimeofday(&current_time, NULL);
2379 timestamp.tv_sec = current_time.tv_sec;
2380 timestamp.tv_usec = current_time.tv_usec;
2381
2382 if (d_connection) {
2383 msgbuf = encode_removeObject(len, objNum);
2385 d_sender_id, msgbuf,
2387 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2388 }
2389 try {
2390 delete[] msgbuf;
2391 } catch (...) {
2392 fprintf(stderr, "vrpn_ForceDevice::removeObject(): delete failed\n");
2393 return;
2394 }
2395 }
2396}
2397
2399{
2400 char *msgbuf = NULL;
2401 vrpn_int32 len = 0;
2402 struct timeval current_time;
2403
2404 vrpn_gettimeofday(&current_time, NULL);
2405 timestamp.tv_sec = current_time.tv_sec;
2406 timestamp.tv_usec = current_time.tv_usec;
2407
2408 if (d_connection) {
2409 msgbuf = encode_clearTrimesh(len, objNum);
2411 d_sender_id, msgbuf,
2413 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2414 }
2415 try {
2416 delete[] msgbuf;
2417 } catch (...) {
2418 fprintf(stderr, "vrpn_ForceDevice::clearObjectTrimesh(): delete failed\n");
2419 return;
2420 }
2421 }
2422}
2423
2426// Change The parent of an object
2428 vrpn_int32 ParentNum)
2429{
2430 char *msgbuf;
2431 vrpn_int32 len;
2432 struct timeval current_time;
2433
2434 vrpn_gettimeofday(&current_time, NULL);
2435 timestamp.tv_sec = current_time.tv_sec;
2436 timestamp.tv_usec = current_time.tv_usec;
2437
2438 if (d_connection) {
2439 msgbuf = encode_moveToParent(len, objNum, ParentNum);
2441 d_sender_id, msgbuf,
2443 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2444 }
2445 try {
2446 delete[] msgbuf;
2447 } catch (...) {
2448 fprintf(stderr, "vrpn_ForceDevice::moveToParent(): delete failed\n");
2449 return;
2450 }
2451 }
2452}
2453
2454// Set the Origin of the haptic scene
2456 vrpn_float32 axis[3],
2457 vrpn_float32 angle)
2458{
2459 char *msgbuf;
2460 vrpn_int32 len;
2461 struct timeval current_time;
2462
2463 vrpn_gettimeofday(&current_time, NULL);
2464 timestamp.tv_sec = current_time.tv_sec;
2465 timestamp.tv_usec = current_time.tv_usec;
2466
2467 if (d_connection) {
2468 msgbuf = encode_setHapticOrigin(len, Pos, axis, angle);
2471 msgbuf, vrpn_CONNECTION_RELIABLE)) {
2472 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2473 }
2474 try {
2475 delete[] msgbuf;
2476 } catch (...) {
2477 fprintf(stderr, "vrpn_ForceDevice::setHapticOrigin(): delete failed\n");
2478 return;
2479 }
2480 }
2481}
2482
2483// Set the scale of the haptic scene
2485{
2486 char *msgbuf;
2487 vrpn_int32 len;
2488 struct timeval current_time;
2489
2490 vrpn_gettimeofday(&current_time, NULL);
2491 timestamp.tv_sec = current_time.tv_sec;
2492 timestamp.tv_usec = current_time.tv_usec;
2493
2494 if (d_connection) {
2495 msgbuf = encode_setHapticScale(len, Scale);
2498 msgbuf, vrpn_CONNECTION_RELIABLE)) {
2499 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2500 }
2501 try {
2502 delete[] msgbuf;
2503 } catch (...) {
2504 fprintf(stderr, "vrpn_ForceDevice::setHapticScale(): delete failed\n");
2505 return;
2506 }
2507 }
2508}
2509
2511 vrpn_float32 axis[3],
2512 vrpn_float32 angle)
2513{
2514 char *msgbuf;
2515 vrpn_int32 len;
2516 struct timeval current_time;
2517
2518 vrpn_gettimeofday(&current_time, NULL);
2519 timestamp.tv_sec = current_time.tv_sec;
2520 timestamp.tv_usec = current_time.tv_usec;
2521
2522 if (d_connection) {
2523 msgbuf = encode_setSceneOrigin(len, Pos, axis, angle);
2526 msgbuf, vrpn_CONNECTION_RELIABLE)) {
2527 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2528 }
2529 try {
2530 delete[] msgbuf;
2531 } catch (...) {
2532 fprintf(stderr, "vrpn_ForceDevice::setSceneOrigin(): delete failed\n");
2533 return;
2534 }
2535 }
2536}
2537
2538// get new ID, use only if wish to use vrpn ids and do not want to manage them
2539// yourself: ids need to be unique
2541{
2542 return m_NextAvailableObjectID++;
2543}
2544
2545// make an object touchable or not
2547 vrpn_int32 objNum, vrpn_bool IsTouchable /*=true*/)
2548{
2549 char *msgbuf;
2550 vrpn_int32 len;
2551 struct timeval current_time;
2552
2553 vrpn_gettimeofday(&current_time, NULL);
2554 timestamp.tv_sec = current_time.tv_sec;
2555 timestamp.tv_usec = current_time.tv_usec;
2556
2557 if (d_connection) {
2558 msgbuf = encode_setObjectIsTouchable(len, objNum, IsTouchable);
2561 msgbuf, vrpn_CONNECTION_RELIABLE)) {
2562 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2563 }
2564 try {
2565 delete[] msgbuf;
2566 } catch (...) {
2567 fprintf(stderr, "vrpn_ForceDevice::setObjectIsTouchable(): delete failed\n");
2568 return;
2569 }
2570 }
2571}
2572
2573// the next time we send a trimesh we will use the following type
2575{
2576 char *msgbuf;
2577 vrpn_int32 len;
2578 struct timeval current_time;
2579
2580 vrpn_gettimeofday(&current_time, NULL);
2581 timestamp.tv_sec = current_time.tv_sec;
2582 timestamp.tv_usec = current_time.tv_usec;
2583
2584 if (d_connection) {
2585 msgbuf = encode_setTrimeshType(len, -1, HCOLLIDE);
2588 msgbuf, vrpn_CONNECTION_RELIABLE)) {
2589 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2590 }
2591 try {
2592 delete[] msgbuf;
2593 } catch (...) {
2594 fprintf(stderr, "vrpn_ForceDevice::useHcollide(): delete failed\n");
2595 return;
2596 }
2597 }
2598}
2599
2601{
2602 char *msgbuf;
2603 vrpn_int32 len;
2604 struct timeval current_time;
2605
2606 vrpn_gettimeofday(&current_time, NULL);
2607 timestamp.tv_sec = current_time.tv_sec;
2608 timestamp.tv_usec = current_time.tv_usec;
2609
2610 if (d_connection) {
2611 msgbuf = encode_setTrimeshType(len, -1, GHOST);
2614 msgbuf, vrpn_CONNECTION_RELIABLE)) {
2615 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2616 }
2617 try {
2618 delete[] msgbuf;
2619 } catch (...) {
2620 fprintf(stderr, "vrpn_ForceDevice::useGhost(): delete failed\n");
2621 return;
2622 }
2623 }
2624}
2625
2626// ajout ONDIM
2628{
2629 char *msgbuf;
2630 vrpn_int32 len;
2631 struct timeval current_time;
2632
2633 vrpn_gettimeofday(&current_time, NULL);
2634 timestamp.tv_sec = current_time.tv_sec;
2635 timestamp.tv_usec = current_time.tv_usec;
2636
2637 if (d_connection) {
2641 d_sender_id, msgbuf,
2643 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2644 }
2645 try {
2646 delete[] msgbuf;
2647 } catch (...) {
2648 fprintf(stderr, "vrpn_ForceDevice::startEffect(): delete failed\n");
2649 return;
2650 }
2651 }
2652}
2653
2655{
2656 char *msgbuf;
2657 vrpn_int32 len;
2658 struct timeval current_time;
2659
2660 vrpn_gettimeofday(&current_time, NULL);
2661 timestamp.tv_sec = current_time.tv_sec;
2662 timestamp.tv_usec = current_time.tv_usec;
2663
2664 setCustomEffect(-1, NULL, 0);
2665
2666 if (d_connection) {
2670 d_sender_id, msgbuf,
2672 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2673 }
2674 try {
2675 delete[] msgbuf;
2676 } catch (...) {
2677 fprintf(stderr, "vrpn_ForceDevice::stopEffect(): delete failed\n");
2678 return;
2679 }
2680 }
2681}
2682// fin ajout ONDIM
2683
2684//
2685// constraint methods
2686//
2687
2688#ifndef FD_SPRINGS_AS_FIELDS
2689
2690#if 0
2691void vrpn_ForceDevice_Remote::enableConstraint (vrpn_int32 enable) {
2692}
2693
2694void vrpn_ForceDevice_Remote::setConstraintMode (ConstraintGeometry mode) {
2695}
2696
2698}
2699
2701}
2702
2704}
2705
2707}
2708
2710}
2711
2713}
2714#endif // 0
2715
2716#else
2717
2719{
2720 if (enable == d_conEnabled) return;
2721 d_conEnabled = enable;
2722
2723 switch (d_conEnabled) {
2724 case 0:
2726 break;
2727 case 1:
2730 break;
2731 default:
2732 fprintf(stderr, "vrpn_ForceDevice_Remote::enableConstraint: "
2733 "Illegal value of enable (%d).\n",
2734 enable);
2735 break;
2736 }
2737}
2738
2740{
2741 d_conMode = mode;
2743 if (d_conEnabled) {
2745 }
2746}
2747
2749{
2750 d_conPoint[0] = point[0];
2751 d_conPoint[1] = point[1];
2752 d_conPoint[2] = point[2];
2754 if (d_conEnabled) {
2756 }
2757}
2758
2760{
2761 d_conLinePoint[0] = point[0];
2762 d_conLinePoint[1] = point[1];
2763 d_conLinePoint[2] = point[2];
2765 if (d_conEnabled) {
2767 }
2768}
2769
2771 vrpn_float32 direction[3])
2772{
2773 d_conLineDirection[0] = direction[0];
2774 d_conLineDirection[1] = direction[1];
2775 d_conLineDirection[2] = direction[2];
2777 if (d_conEnabled) {
2779 }
2780}
2781
2783{
2784 d_conPlanePoint[0] = point[0];
2785 d_conPlanePoint[1] = point[1];
2786 d_conPlanePoint[2] = point[2];
2788 if (d_conEnabled) {
2790 }
2791}
2792
2794{
2795 d_conPlaneNormal[0] = normal[0];
2796 d_conPlaneNormal[1] = normal[1];
2797 d_conPlaneNormal[2] = normal[2];
2799 if (d_conEnabled) {
2801 }
2802}
2803
2805{
2806 d_conKSpring = k;
2808 if (d_conEnabled) {
2810 }
2811}
2812
2813#endif // FD_SPRINGS_AS_FIELDS
2814
2816{
2818}
2819
2821 vrpn_float32 force[3],
2822 vrpn_float32 jacobian[3][3],
2823 vrpn_float32 radius)
2824{
2825 char *msgbuf;
2826 vrpn_int32 len;
2827 struct timeval current_time;
2828
2829 vrpn_gettimeofday(&current_time, NULL);
2830 timestamp.tv_sec = current_time.tv_sec;
2831 timestamp.tv_usec = current_time.tv_usec;
2832
2833 if (d_connection) {
2834 msgbuf = encode_forcefield(len, origin, force, jacobian, radius);
2836 d_sender_id, msgbuf,
2838 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2839 }
2840 try {
2841 delete[] msgbuf;
2842 } catch (...) {
2843 fprintf(stderr, "vrpn_ForceDevice::sendForceField(): delete failed\n");
2844 return;
2845 }
2846 }
2847}
2848
2849// same as sendForceField but sets force to 0 and sends RELIABLY
2851{
2852 vrpn_float32 origin[3] = {0, 0, 0};
2853 vrpn_float32 force[3] = {0, 0, 0};
2854 vrpn_float32 jacobian[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
2855 vrpn_float32 radius = 0;
2856
2857 char *msgbuf;
2858 vrpn_int32 len;
2859 struct timeval current_time;
2860
2861 vrpn_gettimeofday(&current_time, NULL);
2862 timestamp.tv_sec = current_time.tv_sec;
2863 timestamp.tv_usec = current_time.tv_usec;
2864
2865 if (d_connection) {
2866 msgbuf = encode_forcefield(len, origin, force, jacobian, radius);
2868 d_sender_id, msgbuf,
2870 fprintf(stderr, "Phantom: cannot write message: tossing\n");
2871 }
2872 try {
2873 delete[] msgbuf;
2874 } catch (...) {
2875 fprintf(stderr, "vrpn_ForceDevice::stopForceField(): delete failed\n");
2876 return;
2877 }
2878 }
2879}
2880
2882{
2883 if (d_connection) {
2885 }
2887}
2888
2891{
2893 vrpn_FORCECB tp;
2894
2895 tp.msg_time = p.msg_time;
2898
2899 return 0;
2900}
2901
2904{
2906 vrpn_FORCESCPCB tp;
2907
2908 tp.msg_time = p.msg_time;
2909 decode_scp(p.buffer, p.payload_len, tp.pos, tp.quat);
2911
2912 return 0;
2913}
2914
2917{
2920
2921 if (p.payload_len != sizeof(vrpn_int32)) {
2922 fprintf(stderr, "vrpn_ForceDevice: error message payload"
2923 " error\n(got %d, expected %lud)\n",
2924 p.payload_len, static_cast<unsigned long>(sizeof(vrpn_int32)));
2925 return -1;
2926 }
2927 tp.msg_time = p.msg_time;
2930 return 0;
2931}
2932
2933void vrpn_ForceDevice_Remote::send(const char *msgbuf, vrpn_int32 len,
2934 vrpn_int32 type)
2935{
2936 struct timeval now;
2937
2938 vrpn_gettimeofday(&now, NULL);
2939 timestamp.tv_sec = now.tv_sec;
2940 timestamp.tv_usec = now.tv_usec;
2941
2942 if (d_connection) {
2943 if (d_connection->pack_message(len, now, type, d_sender_id, msgbuf,
2945 fprintf(stderr,
2946 "vrpn_ForceDevice_Remote::send: Can't pack message.\n");
2947 }
2948 }
2949
2950 try {
2951 delete[] msgbuf;
2952 } catch (...) {
2953 fprintf(stderr, "vrpn_ForceDevice_Remote::send(): delete failed\n");
2954 return;
2955 }
2956}
2957
2958#ifdef FD_SPRINGS_AS_FIELDS
2959
2961{
2962
2963 vrpn_float32 c[9]; // scratch matrix
2964 int i, j;
2965
2966 // quatlib wants 64-bit reals; the forcefield code wants 32-bit
2967 // reals. We do most of our math in 64 bits, then copy into 32
2968 // for output to force field.
2969
2970 const float largeRadius = 100.0f; // infinity
2971
2972 switch (d_conMode) {
2973
2974 case NO_CONSTRAINT:
2975 break;
2976
2977 case POINT_CONSTRAINT:
2979 setFF_Force(0.0f, 0.0f, 0.0f);
2980 setFF_Jacobian(-d_conKSpring, 0.0f, 0.0f, 0.0f, -d_conKSpring, 0.0f,
2981 0.0f, 0.0f, -d_conKSpring);
2982 setFF_Radius(largeRadius);
2983 break;
2984
2985 case LINE_CONSTRAINT: {
2987 setFF_Force(0.0f, 0.0f, 0.0f);
2988
2989 // Paul Grayson (pdg@mit.edu) points out that rotating the Jacobian
2990 // won't work and we should use something simpler here.
2991 // Unfortunately, it's because of the apparent difficulty of this
2992 // case that we'd tried rotating a Jacobian in the first place.
2993 // Time to hit the books again looking for something that'll work.
2994
2995 //------------------------------------------------------------------
2996 // We want to generate a force that is in the opposite direction
2997 // of the offset between where the pen is and where the line is
2998 // defined to be. Because we are going to multiply the jacobian by
2999 // this offset vector, we want it to hold values that produce a
3000 // force that is in the direction of -OFFSET, but we want the
3001 // force to be scaled by the amount by which OFFSET is perpendicular
3002 // to the line direction (it should be zero along the line). So,
3003 // along the line direction it should always evaluate to (0,0,0)
3004 // independent of OFFSET, and perpendicular to this it should
3005 // always be OFFSET in length in direction -OFFSET,
3006 // which is just -OFFSET, which makes the matrix act like
3007 // -1 scaled by the spring constant. This means that we want a
3008 // matrix with Eigenvalues (-1, -1, 0) whose 0 Eigenvector lies
3009 // along the line direction. We get this by compositing a matrix
3010 // that rotates this vector to lie along Z, then applying the diagonal
3011 // (-1, -1, 0) matrix, then a matrix that rotates Z back to the
3012 // line direction. Remember to scale all of this by the spring
3013 // constant;
3014 // we do this during the diagonal matrix construction.
3015
3016 // Normalize the direction to avoid having its length scale the force
3017 q_vec_type norm_line_dir;
3018 vrpn_float64 norm_len =
3019 sqrt((d_conLineDirection[0] * d_conLineDirection[0]) +
3022 if (norm_len == 0) {
3023 norm_len = 1;
3024 }
3025 for (i = 0; i < 3; i++) {
3026 norm_line_dir[i] = d_conLineDirection[i] / norm_len;
3027 }
3028
3029 // Construct the rotation from the normalized direction to +Z
3030 // and the rotation back.
3031 q_vec_type z_dir = {0, 0, 1};
3032 q_type q_forward;
3033 q_matrix_type forward;
3034 q_type q_reverse;
3035 q_matrix_type reverse;
3036 q_from_two_vecs(q_forward, norm_line_dir, z_dir);
3037 q_to_row_matrix(forward, q_forward);
3038 q_invert(q_reverse, q_forward);
3039 q_to_row_matrix(reverse, q_reverse);
3040
3041 // Construct the (-d_conKSpring, -d_conKSpring, 0) matrix and catenate
3042 // the
3043 // matrices to form the final jacobian.
3044 q_matrix_type diagonal, temp, jacobian;
3045 for (i = 0; i < 4; i++) {
3046 for (j = 0; j < 4; j++) {
3047 if ((i == j) && (i < 2)) {
3048 diagonal[i][j] = -d_conKSpring;
3049 }
3050 else {
3051 diagonal[i][j] = 0.0;
3052 }
3053 }
3054 }
3055 q_matrix_mult(temp, diagonal, forward);
3056 q_matrix_mult(jacobian, reverse, temp);
3057
3058 // Grab the upper-left 3x3 portion of the jacobian and put it into
3059 // the coefficients.
3060 for (i = 0; i < 3; i++) {
3061 for (j = 0; j < 3; j++) {
3062 c[i + j * 3] = (vrpn_float32)jacobian[i][j];
3063 }
3064 }
3065
3066 setFF_Jacobian(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8]);
3067
3068 setFF_Radius(largeRadius);
3069 }; break;
3070
3071 case PLANE_CONSTRAINT: {
3073 setFF_Force(0.0f, 0.0f, 0.0f);
3074
3075 // Normalize the direction to avoid having its length scale the force
3076 vrpn_float64 norm_plane_dir[3];
3077 vrpn_float64 norm_len =
3078 sqrt((d_conPlaneNormal[0] * d_conPlaneNormal[0]) +
3081 if (norm_len == 0) {
3082 norm_len = 1;
3083 }
3084 for (i = 0; i < 3; i++) {
3085 norm_plane_dir[i] = d_conPlaneNormal[i] / norm_len;
3086 }
3087
3088 // Paul Grayson (pdg@mit.edu) points out that rotating the Jacobian
3089 // won't work and we should use something simpler here. The below
3090 // is his code.
3091
3092 for (i = 0; i < 3; i++)
3093 for (j = 0; j < 3; j++)
3094 c[i + j * 3] = (vrpn_float32)(
3095 -d_conKSpring * norm_plane_dir[i] * norm_plane_dir[j]);
3096
3097 setFF_Jacobian(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8]);
3098
3099 setFF_Radius(largeRadius);
3100 }; break;
3101 }
3102}
3103
3104#endif // FD_SPRINGS_AS_FIELDS
int register_autodeleted_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Registers a handler with the connection, and remembers to delete at destruction.
vrpn_Connection * d_connection
Connection that this object talks to.
void client_mainloop(void)
Handles functions that all clients should provide in their mainloop() (warning of no server,...
vrpn_int32 d_sender_id
Sender ID registered with the connection.
Class from which all user-level (and other) classes that communicate with vrpn_Connections should der...
virtual int init(void)
Initialize things that the constructor can't. Returns 0 on success, -1 on failure.
void call_handlers(const CALLBACK_STRUCT &info)
This will pass the referenced parameter as a const to all the callbacks.
Generic connection class not specific to the transport mechanism.
virtual vrpn_int32 register_message_type(const char *name)
virtual int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)
Pack a message that will be sent the next time mainloop() is called. Turn off the RELIABLE flag if yo...
virtual int mainloop(const struct timeval *timeout=NULL)=0
Call each time through program main loop to handle receiving any incoming messages and sending any pa...
void setSceneOrigin(vrpn_float32 Pos[3], vrpn_float32 axis[3], vrpn_float32 angle)
void removeTriangle(vrpn_int32 triNum)
void removeObject(vrpn_int32 objNum)
void setObjectOrientation(vrpn_int32 objNum, vrpn_float32 axis[3], vrpn_float32 angle)
void setConstraintMode(ConstraintGeometry mode)
void setConstraintLinePoint(vrpn_float32 point[3])
void setVertex(vrpn_int32 vertNum, vrpn_float32 x, vrpn_float32 y, vrpn_float32 z)
functions for a single object
vrpn_float64 d_conPlaneNormal[3]
void setObjectIsTouchable(vrpn_int32 objNum, vrpn_bool IsTouchable=true)
void setObjectPosition(vrpn_int32 objNum, vrpn_float32 Pos[3])
void moveToParent(vrpn_int32 objNum, vrpn_int32 ParentNum)
Functions to organize the scene.
void removeObjectTriangle(vrpn_int32 objNum, vrpn_int32 triNum)
void setConstraintPlanePoint(vrpn_float32 point[3])
static int VRPN_CALLBACK handle_scp_change_message(void *userdata, vrpn_HANDLERPARAM p)
void updateObjectTrimeshChanges(vrpn_int32 objNum)
void setHapticScale(vrpn_float32 Scale)
void setTrimeshTransform(vrpn_float32 homMatrix[16])
void setConstraintKSpring(vrpn_float32 k)
void clearObjectTrimesh(vrpn_int32 objNum)
void setObjectVertex(vrpn_int32 objNum, vrpn_int32 vertNum, vrpn_float32 x, vrpn_float32 y, vrpn_float32 z)
void setConstraintPlaneNormal(vrpn_float32 normal[3])
void setObjectScale(vrpn_int32 objNum, vrpn_float32 Scale[3])
void addObjectExScene(vrpn_int32 objNum)
void setConstraintLineDirection(vrpn_float32 direction[3])
vrpn_float32 d_conPlanePoint[3]
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
ConstraintGeometry d_conMode
virtual ~vrpn_ForceDevice_Remote(void)
vrpn_ForceDevice_Remote(const char *name, vrpn_Connection *cn=NULL)
void setTriangle(vrpn_int32 triNum, vrpn_int32 vert0, vrpn_int32 vert1, vrpn_int32 vert2, vrpn_int32 norm0=-1, vrpn_int32 norm1=-1, vrpn_int32 norm2=-1)
void setHapticOrigin(vrpn_float32 Pos[3], vrpn_float32 axis[3], vrpn_float32 angle)
void addObject(vrpn_int32 objNum, vrpn_int32 ParentNum=-1)
functions for multiple objects in the haptic scene
void setObjectNormal(vrpn_int32 objNum, vrpn_int32 normNum, vrpn_float32 x, vrpn_float32 y, vrpn_float32 z)
void enableConstraint(vrpn_int32 enable)
void setConstraintPoint(vrpn_float32 point[3])
vrpn_Callback_List< vrpn_FORCESCPCB > d_scp_change_list
vrpn_Callback_List< vrpn_FORCEERRORCB > d_error_change_list
static int VRPN_CALLBACK handle_error_change_message(void *userdata, vrpn_HANDLERPARAM p)
void setObjectTriangle(vrpn_int32 objNum, vrpn_int32 triNum, vrpn_int32 vert0, vrpn_int32 vert1, vrpn_int32 vert2, vrpn_int32 norm0=-1, vrpn_int32 norm1=-1, vrpn_int32 norm2=-1)
static int VRPN_CALLBACK handle_force_change_message(void *userdata, vrpn_HANDLERPARAM p)
void send(const char *msgbuf, vrpn_int32 len, vrpn_int32 type)
vrpn_float32 d_conLinePoint[3]
void setNormal(vrpn_int32 normNum, vrpn_float32 x, vrpn_float32 y, vrpn_float32 z)
vrpn_Callback_List< vrpn_FORCECB > d_change_list
vrpn_float64 d_conLineDirection[3]
void setObjectTrimeshTransform(vrpn_int32 objNum, vrpn_float32 homMatrix[16])
vrpn_uint32 nbCustomEffectParams
static vrpn_int32 decode_objectScale(const char *buffer, vrpn_int32 len, vrpn_int32 *objNum, vrpn_float32 Scale[3])
static char * encode_setObjectIsTouchable(vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_bool isTouchable)
void setFF_Radius(vrpn_float32 r)
static vrpn_int32 decode_enableConstraint(const char *buffer, const vrpn_int32 len, vrpn_int32 *enable)
vrpn_int32 setConstraintLineDirection_message_id
vrpn_int32 setConstraintKSpring_message_id
static vrpn_int32 decode_trimeshTransform(const char *buffer, const vrpn_int32 len, vrpn_int32 *objNum, vrpn_float32 homMatrix[16])
static vrpn_int32 decode_setHapticOrigin(const char *buffer, vrpn_int32 len, vrpn_float32 Pos[3], vrpn_float32 axis[3], vrpn_float32 *angle)
vrpn_float32 SurfaceKspring
vrpn_int32 force_message_id
static vrpn_int32 decode_setConstraintPoint(const char *buffer, const vrpn_int32 len, vrpn_float32 *x, vrpn_float32 *y, vrpn_float32 *z)
static char * encode_setHapticOrigin(vrpn_int32 &len, const vrpn_float32 Pos[3], const vrpn_float32 axis[3], const vrpn_float32 angle)
static vrpn_int32 decode_setConstraintLineDirection(const char *buffer, const vrpn_int32 len, vrpn_float32 *x, vrpn_float32 *y, vrpn_float32 *z)
static vrpn_int32 decode_objectPosition(const char *buffer, vrpn_int32 len, vrpn_int32 *objNum, vrpn_float32 Pos[3])
static char * encode_plane(vrpn_int32 &length, const vrpn_float32 *plane, const vrpn_float32 kspring, const vrpn_float32 kdamp, const vrpn_float32 fdyn, const vrpn_float32 fstat, const vrpn_int32 plane_index, const vrpn_int32 n_rec_cycles)
static vrpn_int32 decode_normal(const char *buffer, const vrpn_int32 len, vrpn_int32 *objNum, vrpn_int32 *vertNum, vrpn_float32 *x, vrpn_float32 *y, vrpn_float32 *z)
static char * encode_clearTrimesh(vrpn_int32 &len, const vrpn_int32 objNum)
vrpn_int32 addObject_message_id
vrpn_int32 setConstraintMode_message_id
static vrpn_int32 decode_forcefield(const char *buffer, const vrpn_int32 len, vrpn_float32 origin[3], vrpn_float32 force[3], vrpn_float32 jacobian[3][3], vrpn_float32 *radius)
void set_plane(vrpn_float32 *p)
vrpn_int32 setObjectScale_message_id
vrpn_float32 SurfaceKdamping
vrpn_int32 setHapticOrigin_message_id
static char * encode_triangle(vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_int32 triNum, const vrpn_int32 vert0, const vrpn_int32 vert1, const vrpn_int32 vert2, const vrpn_int32 norm0, const vrpn_int32 norm1, const vrpn_int32 norm2)
vrpn_int32 moveToParent_message_id
vrpn_int32 setConstraintLinePoint_message_id
vrpn_float32 SurfaceBuzzFreq
vrpn_float32 SurfaceTextureWavelength
vrpn_float32 ff_origin[3]
static char * encode_setConstraintPoint(vrpn_int32 &len, vrpn_float32 x, vrpn_float32 y, vrpn_float32 z)
static vrpn_int32 decode_error(const char *buffer, const vrpn_int32 len, vrpn_int32 *error_code)
static vrpn_int32 decode_setConstraintKSpring(const char *buffer, const vrpn_int32 len, vrpn_float32 *k)
static char * encode_removeObject(vrpn_int32 &len, const vrpn_int32 objNum)
static vrpn_int32 decode_addObjectExScene(const char *buffer, vrpn_int32 len, vrpn_int32 *objNum)
static char * encode_normal(vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_int32 vertNum, const vrpn_float32 x, const vrpn_float32 y, const vrpn_float32 z)
vrpn_int32 setSceneOrigin_message_id
static char * encode_objectPosition(vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_float32 Pos[3])
static vrpn_int32 decode_setConstraintMode(const char *buffer, const vrpn_int32 len, ConstraintGeometry *mode)
static vrpn_int32 decode_setSceneOrigin(const char *buffer, vrpn_int32 len, vrpn_float32 Pos[3], vrpn_float32 axis[3], vrpn_float32 *angle)
static vrpn_int32 decode_removeTriangle(const char *buffer, const vrpn_int32 len, vrpn_int32 *objNum, vrpn_int32 *triNum)
static char * encode_updateTrimeshChanges(vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_float32 kspring, const vrpn_float32 kdamp, const vrpn_float32 fdyn, const vrpn_float32 fstat)
static char * encode_scp(vrpn_int32 &length, const vrpn_float64 *pos, const vrpn_float64 *quat)
static char * encode_setConstraintMode(vrpn_int32 &len, ConstraintGeometry mode)
vrpn_int32 enableConstraint_message_id
static char * encode_removeTriangle(vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_int32 triNum)
struct timeval timestamp
vrpn_int32 scp_message_id
static char * encodePoint(vrpn_int32 &len, vrpn_float32 x, vrpn_float32 y, vrpn_float32 z)
vrpn_float32 SurfaceBuzzAmp
static vrpn_int32 decode_updateTrimeshChanges(const char *buffer, const vrpn_int32 len, vrpn_int32 *objNum, vrpn_float32 *kspring, vrpn_float32 *kdamp, vrpn_float32 *fdyn, vrpn_float32 *fstat)
static char * encode_addObject(vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_int32 ParentNum)
static char * encode_setTrimeshType(vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_int32 type)
virtual int register_types(void)
Register the types of messages this device sends/receives. Return 0 on success, -1 on fail.
vrpn_int32 error_message_id
vrpn_int32 setObjectPosition_message_id
vrpn_int32 setConstraintPlaneNormal_message_id
static char * encode_setHapticScale(vrpn_int32 &len, const vrpn_float32 Scale)
static char * encode_forcefield(vrpn_int32 &len, const vrpn_float32 origin[3], const vrpn_float32 force[3], const vrpn_float32 jacobian[3][3], const vrpn_float32 radius)
static vrpn_int32 decode_setConstraintPlaneNormal(const char *buffer, const vrpn_int32 len, vrpn_float32 *x, vrpn_float32 *y, vrpn_float32 *z)
vrpn_int32 clearTrimesh_message_id
static char * encode_objectScale(vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_float32 Scale[3])
static vrpn_int32 decode_setConstraintPlanePoint(const char *buffer, const vrpn_int32 len, vrpn_float32 *x, vrpn_float32 *y, vrpn_float32 *z)
static vrpn_int32 decode_scp(const char *buffer, const vrpn_int32 len, vrpn_float64 *pos, vrpn_float64 *quat)
static char * encode_vertex(vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_int32 vertNum, const vrpn_float32 x, const vrpn_float32 y, const vrpn_float32 z)
void setFF_Origin(vrpn_float32 x, vrpn_float32 y, vrpn_float32 z)
static char * encode_error(vrpn_int32 &len, const vrpn_int32 error_code)
static vrpn_int32 decode_setConstraintLinePoint(const char *buffer, const vrpn_int32 len, vrpn_float32 *x, vrpn_float32 *y, vrpn_float32 *z)
static char * encode_trimeshTransform(vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_float32 homMatrix[16])
vrpn_int32 setTriangle_message_id
static vrpn_int32 decode_surface_effects(const char *buffer, const vrpn_int32 len, vrpn_float32 *k_adhesion_norm, vrpn_float32 *k_adhesion_lat, vrpn_float32 *tex_amp, vrpn_float32 *tex_wl, vrpn_float32 *buzz_amp, vrpn_float32 *buzz_freq)
vrpn_int32 customEffectId
void setFF_Force(vrpn_float32 fx, vrpn_float32 fy, vrpn_float32 fz)
vrpn_float32 plane[4]
static char * encode_setConstraintKSpring(vrpn_int32 &len, vrpn_float32 k)
static char * encode_setConstraintLineDirection(vrpn_int32 &len, vrpn_float32 x, vrpn_float32 y, vrpn_float32 z)
vrpn_int32 plane_message_id
static char * encode_setConstraintPlaneNormal(vrpn_int32 &len, vrpn_float32 x, vrpn_float32 y, vrpn_float32 z)
static char * encode_custom_effect(vrpn_int32 &len, vrpn_uint32 effectId, const vrpn_float32 *params, vrpn_uint32 nbParams)
static vrpn_int32 decode_addObject(const char *buffer, vrpn_int32 len, vrpn_int32 *objNum, vrpn_int32 *ParentNum)
static vrpn_int32 decode_setTrimeshType(const char *buffer, const vrpn_int32 len, vrpn_int32 *objNum, vrpn_int32 *type)
static char * encode_setConstraintLinePoint(vrpn_int32 &len, vrpn_float32 x, vrpn_float32 y, vrpn_float32 z)
virtual ~vrpn_ForceDevice(void)
static vrpn_int32 decode_setObjectIsTouchable(const char *buffer, vrpn_int32 len, vrpn_int32 *objNum, vrpn_bool *isTouchable)
vrpn_float32 SurfaceKadhesionNormal
vrpn_int32 setConstraintPoint_message_id
vrpn_float32 SurfaceTextureAmplitude
vrpn_int32 updateTrimeshChanges_message_id
static vrpn_int32 decode_custom_effect(const char *buffer, const vrpn_int32 len, vrpn_uint32 *effectId, vrpn_float32 **params, vrpn_uint32 *nbParams)
vrpn_int32 setConstraintPlanePoint_message_id
static vrpn_int32 decode_objectOrientation(const char *buffer, vrpn_int32 len, vrpn_int32 *objNum, vrpn_float32 axis[3], vrpn_float32 *angle)
vrpn_float32 ff_force[3]
static vrpn_int32 decode_clearTrimesh(const char *buffer, vrpn_int32 len, vrpn_int32 *objNum)
vrpn_ForceDevice(const char *name, vrpn_Connection *c)
vrpn_int32 setHapticScale_message_id
static vrpn_int32 decode_triangle(const char *buffer, const vrpn_int32 len, vrpn_int32 *objNum, vrpn_int32 *triNum, vrpn_int32 *vert0, vrpn_int32 *vert1, vrpn_int32 *vert2, vrpn_int32 *norm0, vrpn_int32 *norm1, vrpn_int32 *norm2)
vrpn_int32 addObjectExScene_message_id
static vrpn_int32 decode_force(const char *buffer, const vrpn_int32 len, vrpn_float64 *force)
void sendError(int error_code)
static char * encode_objectOrientation(vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_float32 axis[3], const vrpn_float32 angle)
vrpn_int32 transformTrimesh_message_id
vrpn_int32 setObjectOrientation_message_id
vrpn_int32 getNewObjectID_message_id
void setCustomEffect(vrpn_int32 effectId, vrpn_float32 *params=NULL, vrpn_uint32 nbParams=0)
static char * encode_addObjectExScene(vrpn_int32 &len, const vrpn_int32 objNum)
vrpn_int32 removeTriangle_message_id
static vrpn_int32 decode_moveToParent(const char *buffer, vrpn_int32 len, vrpn_int32 *objNum, vrpn_int32 *parentNum)
vrpn_int32 setNormal_message_id
vrpn_int32 setTrimeshType_message_id
static char * encode_surface_effects(vrpn_int32 &len, const vrpn_float32 k_adhesion_norm, const vrpn_float32 k_adhesion_lat, const vrpn_float32 tex_amp, const vrpn_float32 tex_wl, const vrpn_float32 buzz_amp, const vrpn_float32 buzz_freq)
vrpn_int32 custom_effect_message_id
vrpn_int32 forcefield_message_id
static vrpn_int32 decodePoint(const char *buffer, const vrpn_int32 len, vrpn_float32 *x, vrpn_float32 *y, vrpn_float32 *z)
static char * encode_setConstraintPlanePoint(vrpn_int32 &len, vrpn_float32 x, vrpn_float32 y, vrpn_float32 z)
vrpn_float32 SurfaceFdynamic
static char * encode_enableConstraint(vrpn_int32 &len, vrpn_int32 enable)
vrpn_float32 SurfaceFstatic
static char * encode_force(vrpn_int32 &length, const vrpn_float64 *force)
static char * encode_moveToParent(vrpn_int32 &len, const vrpn_int32 objNum, const vrpn_int32 parentNum)
vrpn_int32 removeObject_message_id
static vrpn_int32 decode_vertex(const char *buffer, const vrpn_int32 len, vrpn_int32 *objNum, vrpn_int32 *vertNum, vrpn_float32 *x, vrpn_float32 *y, vrpn_float32 *z)
vrpn_int32 setVertex_message_id
vrpn_float32 ff_radius
static char * encode_setSceneOrigin(vrpn_int32 &len, const vrpn_float32 Pos[3], const vrpn_float32 axis[3], const vrpn_float32 angle)
static vrpn_int32 decode_removeObject(const char *buffer, vrpn_int32 len, vrpn_int32 *objNum)
static vrpn_int32 decode_setHapticScale(const char *buffer, vrpn_int32 len, vrpn_float32 *Scale)
vrpn_float32 * customEffectParams
void setFF_Jacobian(vrpn_float32 dfxdx, vrpn_float32 dfxdy, vrpn_float32 dfxdz, vrpn_float32 dfydx, vrpn_float32 dfydy, vrpn_float32 dfydz, vrpn_float32 dfzdx, vrpn_float32 dfzdy, vrpn_float32 dfzdz)
vrpn_int32 plane_effects_message_id
vrpn_float32 SurfaceKadhesionLateral
vrpn_float32 ff_jacobian[3][3]
vrpn_int32 setObjectIsTouchable_message_id
static vrpn_int32 decode_plane(const char *buffer, const vrpn_int32 len, vrpn_float32 *plane, vrpn_float32 *kspring, vrpn_float32 *kdamp, vrpn_float32 *fdyn, vrpn_float32 *fstat, vrpn_int32 *plane_index, vrpn_int32 *n_rec_cycles)
vrpn_float64 force[3]
struct timeval msg_time
struct timeval msg_time
vrpn_float64 quat[4]
struct timeval msg_time
vrpn_float64 pos[3]
This structure is what is passed to a vrpn_Connection message callback.
const char * buffer
struct timeval msg_time
const vrpn_uint32 vrpn_CONNECTION_RELIABLE
Classes of service for messages, specify multiple by ORing them together Priority of satisfying these...
const vrpn_uint32 vrpn_CONNECTION_LOW_LATENCY
#define CHECK(x)
TrimeshType
@ HCOLLIDE
@ GHOST
#define FD_OK
VRPN_API int vrpn_unbuffer(const char **buffer, timeval *t)
Utility routine for taking a struct timeval from a buffer that was sent as a message.
VRPN_API int vrpn_buffer(char **insertPt, vrpn_int32 *buflen, const timeval t)
Utility routine for placing a timeval struct into a buffer that is to be sent as a message.
#define vrpn_gettimeofday
Definition vrpn_Shared.h:99