5DT Data Glove plugin  1.0
GlovePlugin.cpp
1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OpenSpace3D
4 For the latest info, see http://www.openspace3d.com
5 
6 Copyright (c) 2012 I-maginer
7 
8 This program is free software; you can redistribute it and/or modify it under
9 the terms of the GNU Lesser General Public License as published by the Free Software
10 Foundation; either version 2 of the License, or (at your option) any later
11 version.
12 
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public License along with
18 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20 http://www.gnu.org/copyleft/lesser.txt
21 
22 -----------------------------------------------------------------------------
23 */
24 
25 /*
26  5DT Data Glove library based on fglove library
27  First version : april 2011
28  Author : Aymeric Suteau
29 */
30 
38 // Include Header File
39 #include "GlovePlugin.h"
40 
42 cbmachine ww;
43 HWND HScol = NULL;
44 
46 int OBJGLOVESCOL;
47 
49 //===== CB New data ===
50 int SCOL_GLOVE_NEWDATA_CB = 0;
51 int GLOVE_NEWDATA_CB;
52 
53 //===== CB New hand gesture ===
54 int SCOL_GLOVE_GESTURE_CB = 1;
55 int GLOVE_HAND_CB;
56 
57 //===== CB Start of calibration process ===
58 int SCOL_GLOVE_CALIBRATION_START_CB = 2;
59 int GLOVE_CALIBRATION_START_CB;
60 
61 //===== CB End of calibration process ===
62 int SCOL_GLOVE_CALIBRATION_END_CB = 3;
63 int GLOVE_CALIBRATION_END_CB;
64 
65 
76 
77 int destroyGloveObj(mmachine m, int handsys, int gloveTab)
78 {
79  // Read the first element of a TAB element (table of objects)
80  GloveObject* GloveObj = (GloveObject*) MMfetch(m, MTOP(gloveTab), 0);
81  if (GloveObj == NULL)
82  {
83  // Write the first element in the stack, without pulling it
84  MMset(m, 0, NIL);
85  return 0;
86  }
87 
88  // Safely dispose of "GloveObj" pointer
89  SAFE_DELETE(GloveObj);
90  // Write the first element of a TAB element
91  MMstore(m, MTOP(gloveTab), 0, NULL);
92 
93  // Display debug message
94  MMechostr(MSKDEBUG, "GloveObj destroyed.\n");
95  return 0;
96 }
97 
98 
107 int _DTGloveOpenDevice(mmachine m)
108 {
109  #ifdef _SCOL_DEBUG_
110  MMechostr(MSKDEBUG,"_DTGloveOpenDevice\n");
111  #endif
112 
113  // Declare local variables
114  int k = 0;
115 
116  // Test channel
117  if (MMget(m, 0) == NIL) // NOTE: Channel is the first parameter, so on the top of the stack...
118  {
119  MMechostr(MSKDEBUG,"_OpenFusionDevice : channel NIL\n");
120  return 0;
121  }
122 
123  // Create glove instance
124  GloveObject* glove = new GloveObject();
125  MMechostr(MSKDEBUG, "_DTGloveOpenDevice ...new glove instance created !\n");
126 
127  // Open glove on USB port
128  if (!glove->Init())
129  {
130  MMechostr(MSKDEBUG, "_DTGloveOpenDevice ...initialization failed\n");
131  SAFE_DELETE(glove);
132  MMset(m, 0, NIL);
133  return 0;
134  }
135  // Start data glove initialization procedure (for the sensors values)
136  MMechostr(MSKDEBUG, "_DTGloveOpenDevice ...initialization successful\n");
137 
138  // TEST : Display data glove serial number and USB index port
139  MMechostr(MSKDEBUG, "_DTGloveOpenDevice ...serial number : %s\tUSB index : %d\n", glove->GetSerialNumber(), glove->GetUSBPortIndex());
140 
141  // Allocate a block in the stack for a table of glove objects
142  int gloveTab = MMmalloc(m, 1, TYPETAB);
143  if (gloveTab == NIL)
144  {
145  MMechostr(MSKDEBUG, "_DTGloveOpenDevice ...MMmalloc failed\n");
146  SAFE_DELETE(glove);
147  MMset(m, 0, NIL);
148  return 0;
149  }
150  MMechostr(MSKDEBUG, "_DTGloveOpenDevice ...MMmalloc successful\n");
151 
152  // Push the TAB glove object into the stack
153  MMstore(m, gloveTab, 0, (int)glove);
154  MMpush(m, PTOM(gloveTab));
155 
156  // Create a new glove object
157  k = OBJcreate(m, OBJGLOVESCOL, (int)glove, NIL, 0);
158  MMechostr(MSKDEBUG, "_DTGloveOpenDevice ...object creation successful\n");
159 
160  #ifdef _SCOL_DEBUG_
161  MMechostr(MSKDEBUG,"ok\n");
162  #endif
163 
164  // Return glove object
165  return k;
166 }
167 
168 
177 int _DTGloveCloseDevice(mmachine m)
178 {
179  #ifdef _SCOL_DEBUG_
180  MMechostr(MSKDEBUG,"_DTGloveCloseDevice\n");
181  #endif
182 
183  // Get the table of glove objects into the stack (without pulling it)
184  int gloveTab = MMget(m, 0);
185  MMechostr(MSKDEBUG, "\n_DTGloveCloseDevice\n");
186  if (gloveTab == NIL)
187  {
188  MMechostr(MSKDEBUG, "_DTGloveCloseDevice ...ObjGlove NIL\n");
189  MMset(m, 0, NIL);
190  return 0;
191  }
192 
193  // Destroy glove object according to its type and magma object
194  OBJdelTM(m, OBJGLOVESCOL, gloveTab);
195 
196  // Reinitialize the stack
197  MMset(m, 0, 0);
198 
199  #ifdef _SCOL_DEBUG_
200  MMechostr(MSKDEBUG,"ok\n");
201  #endif
202 
203  return 0;
204 }
205 
206 
215 int _DTGloveGetSerialNumber(mmachine m)
216 {
217  #ifdef _SCOL_DEBUG_
218  MMechostr(MSKDEBUG,"_DTGloveGetSerialNumber\n");
219  #endif
220 
221  // Get the table of glove objects into the stack (without pulling it)
222  int gloveTab = MMget(m, 0);
223  MMechostr(MSKDEBUG, "_DTGloveGetSerialNumber\n");
224  if (gloveTab == NIL)
225  {
226  MMechostr(MSKDEBUG, "_DTGloveGetSerialNumber ...ObjGlove NIL\n");
227  MMset(m, 0, NIL);
228  return 0;
229  }
230 
231  // Read the first element of a TAB element (table of objects)
232  GloveObject* GloveObj = (GloveObject*) MMfetch(m, MTOP(gloveTab), 0);
233  if (GloveObj == NULL)
234  {
235  // Write the first element in the stack, without pulling it
236  MMset(m, 0, NIL);
237  return 0;
238  }
239 
240  // Remove param from stack
241  MMpull(m);
242 
243  // Put in the stack the return of the function call
244  Mpushstrbloc(m, (char*)(GloveObj->GetSerialNumber().c_str()));
245 
246  #ifdef _SCOL_DEBUG_
247  MMechostr(0,"ok\n");
248  #endif
249 
250  return 0;
251 }
252 
253 
262 int _DTGloveGetType(mmachine m)
263 {
264  #ifdef _SCOL_DEBUG_
265  MMechostr(MSKDEBUG,"_DTGloveGetType\n");
266  #endif
267 
268  // Get the table of glove objects into the stack (without pulling it)
269  int gloveTab = MMget(m, 0);
270  MMechostr(MSKDEBUG, "_DTGloveGetType\n");
271  if (gloveTab == NIL)
272  {
273  MMechostr(MSKDEBUG, "_DTGloveGetType ...ObjGlove NIL\n");
274  MMset(m, 0, NIL);
275  return 0;
276  }
277 
278  // Read the first element of a TAB element (table of objects)
279  GloveObject* GloveObj = (GloveObject*) MMfetch(m, MTOP(gloveTab), 0);
280  if (GloveObj == NULL)
281  {
282  // Write the first element in the stack, without pulling it
283  MMset(m, 0, NIL);
284  return 0;
285  }
286 
287  // Remove param from stack
288  MMpull(m);
289 
290  // Put in the stack the return of the function call
291  Mpushstrbloc(m, const_cast<char*>(GloveObj->GetTypeName().c_str()));
292 
293  #ifdef _SCOL_DEBUG_
294  MMechostr(0,"ok\n");
295  #endif
296 
297  return 0;
298 }
299 
300 
309 int _DTGloveGetUSBIndex(mmachine m)
310 {
311  #ifdef _SCOL_DEBUG_
312  MMechostr(MSKDEBUG,"_DTGloveGetUSBIndex\n");
313  #endif
314 
315  // Get the table of glove objects into the stack (without pulling it)
316  int gloveTab = MMget(m, 0);
317  MMechostr(MSKDEBUG, "_DTGloveGetUSBIndex\n");
318  if (gloveTab == NIL)
319  {
320  MMechostr(MSKDEBUG, "_DTGloveGetUSBIndex ...ObjGlove NIL\n");
321  MMset(m, 0, NIL);
322  return 0;
323  }
324 
325  // Read the first element of a TAB element (table of objects)
326  GloveObject* GloveObj = (GloveObject*) MMfetch(m, MTOP(gloveTab), 0);
327  if (GloveObj == NULL)
328  {
329  // Write the first element in the stack, without pulling it
330  MMset(m, 0, NIL);
331  return 0;
332  }
333 
334  // Put USB index into the stack
335  MMset(m, 0, ITOM(GloveObj->GetUSBPortIndex()));
336 
337  #ifdef _SCOL_DEBUG_
338  MMechostr(0,"ok\n");
339  #endif
340 
341  return 0;
342 }
343 
344 
353 int _DTGloveCalibrate(mmachine m)
354 {
355  #ifdef _SCOL_DEBUG_
356  MMechostr(MSKDEBUG,"_DTGloveCalibrate\n");
357  #endif
358 
359  // Get the table of glove objects into the stack (without pulling it)
360  int gloveTab = MMget(m, 0);
361  MMechostr(MSKDEBUG, "_DTGloveCalibrate\n");
362  if (gloveTab == NIL)
363  {
364  MMechostr(MSKDEBUG, "_DTGloveCalibrate ...ObjGlove NIL\n");
365  MMset(m, 0, NIL);
366  return 0;
367  }
368 
369  // Read the first element of a TAB element (table of objects)
370  GloveObject* GloveObj = (GloveObject*) MMfetch(m, MTOP(gloveTab), 0);
371  if (GloveObj == NULL)
372  {
373  // Write the first element in the stack, without pulling it
374  MMset(m, 0, NIL);
375  return 0;
376  }
377 
378  // Calibrate the data glove
379  GloveObj->StartCalibration();
380  MMset(m, 0, ITOM(0));
381 
382  #ifdef _SCOL_DEBUG_
383  MMechostr(0,"ok\n");
384  #endif
385 
386  return 0;
387 }
388 
389 
400 int _CBDTGloveRawData(mmachine m)
401 {
402  // Add a reflex
403  //MMechostr(MSKDEBUG, "_CBDTGloveRawData ...adding reflex\n");
404  return OBJaddreflex(m, OBJGLOVESCOL, SCOL_GLOVE_NEWDATA_CB);
405 }
406 
407 int getGloveRawDataCb(mmachine m, UINT id, LONG msg_ptr)
408 {
409  // Cast id parameter to GloveObj type
410  GloveObject* GloveObj = (GloveObject*) id;
411  float* data = (float*) msg_ptr;
412 
413  // Use : OBJbeginreflex(mmachine, type of object, ptr object, callback type)
414  if (OBJbeginreflex(m, OBJGLOVESCOL, (int)GloveObj, SCOL_GLOVE_NEWDATA_CB))
415  {
416  //MMechostr(MSKDEBUG, "getGloveRawDataCb ...ObjGlove not found\n");
417  return 0;
418  }
419  // Store finger sensor values
420  for (int i = 0; i < 5; i++)
421  {
422  int tupleFinger = MMmalloc(m, 2, TYPETAB);
423  if (tupleFinger == NIL)
424  {
425  return MERRMEM; // Return an error code (-1)
426  }
427  MMstore(m, tupleFinger, 0, FTOM(data[3*i]));
428  MMstore(m, tupleFinger, 1, FTOM(data[3*i+2]));
429  MMpush(m, PTOM(tupleFinger));
430  }
431 
432  // Store abduction values
433  int tupleAbduction = MMmalloc(m, 4, TYPETAB);
434  for (int i = 0; i < 4; i++)
435  {
436  if (tupleAbduction == NIL)
437  {
438  return MERRMEM; // Return an error code (-1)
439  }
440  MMstore(m, tupleAbduction, i, FTOM(data[3*i+2]));
441  }
442  MMpush(m, PTOM(tupleAbduction));
443 
444  // Store Thumbpalm and wristbend values
445  int tuplePW = MMmalloc(m, 2, TYPETAB);
446  if (tuplePW == NIL)
447  return MERRMEM; // Return an error code (-1)
448 
449  MMstore(m, tuplePW, 0, FTOM(data[14]));
450  MMstore(m, tuplePW, 1, FTOM(data[15]));
451  MMpush(m, PTOM(tuplePW));
452 
453  // Store Pitch and Roll values
454  int tuplePR = MMmalloc(m, 2, TYPETAB);
455  if (tuplePR == NIL)
456  {
457  return MERRMEM; // Return an error code (-1)
458  }
459  MMstore(m, tuplePR, 0, FTOM(data[16]));
460  MMstore(m, tuplePR, 1, FTOM(data[17]));
461  MMpush(m, PTOM(tuplePR));
462 
463  //free msg memory
464  delete data;
465 
466  // Call reflex previously defined (second parameter = number of user parameters)
467  return OBJcallreflex(m, 8);
468 }
469 
480 int _CBDTGloveGesture(mmachine m)
481 {
482  // Add a reflex
483  MMechostr(MSKDEBUG, "_CBDTGloveGesture ...adding reflex\n");
484  return OBJaddreflex(m, OBJGLOVESCOL, SCOL_GLOVE_GESTURE_CB);
485 }
486 
487 
488 int getGloveGestureCb(mmachine m, UINT id, LONG gesture)
489 {
490  // Cast id parameter to GloveObj type
491  GloveObject * GloveObj = (GloveObject*) id;
492 
493  // Use : OBJbeginreflex(mmachine, type of object, ptr object, callback type)
494  if (OBJbeginreflex(m, OBJGLOVESCOL, (int)GloveObj, SCOL_GLOVE_GESTURE_CB))
495  {
496  //MMechostr(MSKDEBUG, "getGloveGestureCb ...ObjGlove not found\n");
497  return 0;
498  }
499 
500  MMpush(m, ITOM(gesture));
501 
502  // Call reflex previously defined
503  return OBJcallreflex(m, 1);
504 }
505 
506 
518 {
519  // Add a reflex
520  MMechostr(MSKDEBUG, "_CBDTGloveCalibrationStart ...adding reflex\n");
521  return OBJaddreflex(m, OBJGLOVESCOL, SCOL_GLOVE_CALIBRATION_START_CB);
522 }
523 
524 
525 int getCalibrationStartCb(mmachine m, UINT id, LONG param)
526 {
527  int k = 0;
528 
529  // Cast id parameter to GloveObj type
530  GloveObject * GloveObj = (GloveObject*) id;
531 
532  // Use : OBJbeginreflex(mmachine, type of object, ptr object, callback type)
533  if (OBJbeginreflex(m, OBJGLOVESCOL, (int)GloveObj, SCOL_GLOVE_CALIBRATION_START_CB))
534  {
535  MMechostr(MSKDEBUG, "getCalibrationStartCb ...ObjGlove not found\n");
536  return 0;
537  }
538 
539  // Call reflex previously defined
540  k = OBJcallreflex(m, 0);
541  return k;
542 }
543 
544 
555 int _CBDTGloveCalibrationEnd(mmachine m)
556 {
557  // Add a reflex
558  MMechostr(MSKDEBUG, "_CBDTGloveCalibrationEnd ...adding reflex\n");
559  return OBJaddreflex(m, OBJGLOVESCOL, SCOL_GLOVE_CALIBRATION_END_CB);
560 }
561 
562 int getCalibrationEndCb(mmachine m, UINT id, LONG param)
563 {
564  int k = 0;
565 
566  // Cast id parameter to GloveObj type
567  GloveObject * GloveObj = (GloveObject*) id;
568 
569  // Use : OBJbeginreflex(mmachine, type of object, ptr object, callback type)
570  if (OBJbeginreflex(m, OBJGLOVESCOL, (int)GloveObj, SCOL_GLOVE_CALIBRATION_END_CB))
571  {
572  MMechostr(MSKDEBUG, "getCalibrationEndCb ...ObjGlove not found\n");
573  return 0;
574  }
575 
576  // Call reflex previously defined
577  k = OBJcallreflex(m, 0);
578  return k;
579 }
580 
581 
582 
590 
591 
593 #define NbTplPKG 11
594 
595 
599 char *TplName[NbTplPKG] =
600 {
601  "ObjDTGlove",
602  "_DTGloveOpenDevice",
603  "_DTGloveCloseDevice",
604  "_CBDTGloveRawData",
605  "_CBDTGloveGesture",
606  "_CBDTGloveCalibrationStart",
607  "_CBDTGloveCalibrationEnd",
608  "_DTGloveGetSerialNumber",
609  "_DTGloveGetType",
610  "_DTGloveGetUSBIndex",
611  "_DTGloveCalibrate"
612 };
613 
614 
618 int (*TplFunc[NbTplPKG])(mmachine m)=
619 {
620  NULL, // ObjDTGlove
621  _DTGloveOpenDevice, // _DTGloveOpenDevice
622  _DTGloveCloseDevice, // _DTGloveCloseDevice
623  _CBDTGloveRawData, // _CBDTGloveRawData
624  _CBDTGloveGesture, // _CBDTGloveGesture
625  _CBDTGloveCalibrationStart, // _CBDTGloveCalibrationStart
626  _CBDTGloveCalibrationEnd, // _CBDTGloveCalibrationEnd
627  _DTGloveGetSerialNumber, // _DTGloveGetSerialNumber
628  _DTGloveGetType, // _DTGloveGetType
629  _DTGloveGetUSBIndex, // _DTGloveGetUSBIndex
630  _DTGloveCalibrate // _DTGloveCalibrate
631 };
632 
633 
637 int TplNArg[NbTplPKG]=
638 {
639  TYPTYPE, // ObjGlove
640  1, // _DTGloveOpenDevice
641  1, // _DTGloveCloseDevice
642  3, // _CBDTGloveRawData
643  3, // _CBDTGloveGesture
644  3, // _CBDTGloveCalibrationStart
645  3, // _CBDTGloveCalibrationEnd
646  1, // _DTGloveGetSerialNumber
647  1, // _DTGloveGetType
648  1, // _DTGloveGetUSBIndex
649  1 // _DTGloveCalibrate
650 };
651 
652 
656 char* TplType[NbTplPKG]=
657 {
658  NULL, // ObjGlove
659  "fun [Chn] ObjGlove", // _DTGloveOpenDevice
660  "fun [ObjGlove] I", // _DTGloveCloseDevice
661  "fun [ObjGlove fun [ObjGlove u0 [F F] [F F] [F F] [F F] [F F] [F F F F] [F F] [F F]] u1 u0] ObjGlove", // _CBDTGloveRawData
662  "fun [ObjGlove fun [ObjGlove u0 I] u1 u0] ObjGlove", // _CBDTGloveGesture
663  "fun [ObjGlove fun [ObjGlove u0] u1 u0] ObjGlove", // _CBDTGloveCalibrationStart
664  "fun [ObjGlove fun [ObjGlove u0] u1 u0] ObjGlove", // _CBDTGloveCalibrationEnd
665  "fun [ObjGlove] S", // _DTGloveGetSerialNumber
666  "fun [ObjGlove] S", // _DTGloveGetType
667  "fun [ObjGlove] I", // _DTGloveGetUSBIndex
668  "fun [ObjGlove] I" // _DTGloveCalibrate
669 };
670 
671 
679 // Everything inside _cond and _endcond is ignored by doxygen
681 
686 int LoadGlove(mmachine m)
687 {
688  // Return variable for PKhardpak function
689  int k;
690 
691  // Declare a new type of object ("OBJGLOVESCOL")
692  OBJGLOVESCOL = OBJregister(4, 1, destroyGloveObj, "OBJGLOVESCOL");
693 
694  // Get new user events and associate these events with a callback
695  GLOVE_NEWDATA_CB = OBJgetUserEvent();
696  OBJdefEvent(GLOVE_NEWDATA_CB, (int (__cdecl *)(struct Mmachine *, UINT, LONG))getGloveRawDataCb);
697 
698  GLOVE_HAND_CB = OBJgetUserEvent();
699  OBJdefEvent(GLOVE_HAND_CB, (int (__cdecl *)(struct Mmachine *, UINT, LONG))getGloveGestureCb);
700 
701  GLOVE_CALIBRATION_START_CB = OBJgetUserEvent();
702  OBJdefEvent(GLOVE_CALIBRATION_START_CB, (int (__cdecl *)(struct Mmachine *, UINT, LONG))getCalibrationStartCb);
703 
704  GLOVE_CALIBRATION_END_CB = OBJgetUserEvent();
705  OBJdefEvent(GLOVE_CALIBRATION_END_CB, (int (__cdecl *)(struct Mmachine *, UINT, LONG))getCalibrationEndCb);
706 
707  // Load package
708  k = PKhardpak(m, "GloveEngine", NbTplPKG, TplName, TplFunc, TplNArg, TplType);
709  return k;
710 }
712 
713 
718 extern "C"
719 #if SCOL_PLATFORM == SCOL_PLATFORM_WINDOWS
720 __declspec (dllexport)
721 #endif
722 int ScolLoadPlugin(mmachine m, cbmachine w)
723 {
724  SCOLinitplugin(w);
725 
726  // Get Scol window handle (for message callback)
727  HScol = (HWND)SCgetExtra("hscol");
728  LoadGlove(m);
729  return 0;
730 }
731 
732 
737 extern "C"
738 #if SCOL_PLATFORM == SCOL_PLATFORM_WINDOWS
739 __declspec (dllexport)
740 #endif
741 int ScolUnloadPlugin()
742 {
743  return 0;
744 }