Sensor Scol plugin
Multi platform sensors for handled devices
scolplugin.cpp
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
25/*
26 Sensor (android/windows) interface for Scol
27
28 First version : JUNE 2015
29 Author : Rémi LAOT - I-Maginer
30*/
31
32#include <scolPlugin.h>
33#include "SSensor.h"
34
35#include "tools/Vector3d.h"
36#include "tools/Quaternion.h"
37
39#ifdef SCOL_STATIC
40extern cbmachine ww;
41extern mmachine mm;
42#else
43cbmachine ww;
44mmachine mm;
45#endif
46
47#include <scolMemoryHelper.hpp>
48
49#if !defined (ANDROID) && !defined(_WIN32)
50extern int(*CallMainThread)(void*, mmachine m);
51#endif
52
53int OBJSENSORSCOL;
54int SENSOR_DATA_CB;
55int SCOL_SENSOR_DATA_CB = 0;
56
57#define GD_semiMajorAxis 6378137.000000
58#define GD_TranMercB 6356752.314245
59#define GD_geocentF 0.003352810664
60
61void geodeticOffsetInv(double refLat, double refLon, double lat, double lon, double& xOffset, double& yOffset)
62{
63 double a = GD_semiMajorAxis;
64 double b = GD_TranMercB;
65 double f = GD_geocentF;
66
67 double L = lon - refLon;
68 double U1 = atan((1 - f) * tan(refLat));
69 double U2 = atan((1 - f) * tan(lat));
70 double sinU1 = sin(U1);
71 double cosU1 = cos(U1);
72 double sinU2 = sin(U2);
73 double cosU2 = cos(U2);
74
75 double lambda = L;
76 double lambdaP;
77 double sinSigma;
78 double sigma;
79 double cosSigma;
80 double cosSqAlpha;
81 double cos2SigmaM;
82 double sinLambda;
83 double cosLambda;
84 double sinAlpha;
85 int iterLimit = 100;
86 do {
87 sinLambda = sin(lambda);
88 cosLambda = cos(lambda);
89 sinSigma = sqrt((cosU2*sinLambda) * (cosU2*sinLambda) +
90 (cosU1*sinU2 - sinU1*cosU2*cosLambda) *
91 (cosU1*sinU2 - sinU1*cosU2*cosLambda));
92 if (sinSigma == 0)
93 {
94 xOffset = 0.0;
95 yOffset = 0.0;
96 return; // co-incident points
97 }
98 cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda;
99 sigma = atan2(sinSigma, cosSigma);
100 sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
101 cosSqAlpha = 1 - sinAlpha*sinAlpha;
102 cos2SigmaM = cosSigma - 2 * sinU1*sinU2 / cosSqAlpha;
103 if (cos2SigmaM != cos2SigmaM) //isNaN
104 {
105 cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (§6)
106 }
107 double C = f / 16 * cosSqAlpha*(4 + f*(4 - 3 * cosSqAlpha));
108 lambdaP = lambda;
109 lambda = L + (1 - C) * f * sinAlpha *
110 (sigma + C*sinSigma*(cos2SigmaM + C*cosSigma*(-1 + 2 * cos2SigmaM*cos2SigmaM)));
111 } while (fabs(lambda - lambdaP) > 1e-12 && --iterLimit > 0);
112
113 if (iterLimit == 0)
114 {
115 xOffset = 0.0;
116 yOffset = 0.0;
117 return; // formula failed to converge
118 }
119
120 double uSq = cosSqAlpha * (a*a - b*b) / (b*b);
121 double A = 1 + uSq / 16384 * (4096 + uSq*(-768 + uSq*(320 - 175 * uSq)));
122 double B = uSq / 1024 * (256 + uSq*(-128 + uSq*(74 - 47 * uSq)));
123 double deltaSigma = B*sinSigma*(cos2SigmaM + B / 4 * (cosSigma*(-1 + 2 * cos2SigmaM*cos2SigmaM) -
124 B / 6 * cos2SigmaM*(-3 + 4 * sinSigma*sinSigma)*(-3 + 4 * cos2SigmaM*cos2SigmaM)));
125 double s = b*A*(sigma - deltaSigma);
126
127 double bearing = atan2(cosU2*sinLambda, cosU1*sinU2 - sinU1*cosU2*cosLambda);
128 xOffset = sin(bearing)*s;
129 yOffset = cos(bearing)*s;
130}
131
154int _IsSensorAvailable(mmachine m)
155{
156#ifdef _SCOL_DEBUG_
157 MMechostr(MSKDEBUG, "_IsSensorAvailable\n");
158#endif
159
160 int itype = MMget(m, 0);
161 if (itype == NIL)
162 {
163 MMechostr(MSKRUNTIME, "_IsSensorAvailable : No Sensor Type Given\n");
164 MMset(m, 0, NIL);
165 return 0;
166 }
167
168 if (!SSensorManager::GetInstance())
169 {
170 MMechostr(MSKRUNTIME, "_IsSensorAvailable : No Sensor Manager Initialized\n");
171 MMset(m, 0, NIL);
172 return 0;
173 }
174
175 SSensorType type = (SSensorType)MTOI(itype);
176
177 bool isAvailable = SSensorManager::GetInstance()->IsAvailable(type);
178 MMset(m, 0, ITOM(isAvailable ? 1 : 0));
179
180#ifdef _SCOL_DEBUG_
181 MMechostr(MSKDEBUG, "ok\n");
182#endif
183 return 0;
184}
185
195int _IsSensorEnabled(mmachine m)
196{
197#ifdef _SCOL_DEBUG_
198 MMechostr(MSKDEBUG, "_IsSensorEnabled\n");
199#endif
200
201 int itype = MMget(m, 0);
202 if (itype == NIL)
203 {
204 MMechostr(MSKRUNTIME, "_IsSensorEnabled : No Sensor Type Given\n");
205 MMset(m, 0, NIL);
206 return 0;
207 }
208
209 if (!SSensorManager::GetInstance())
210 {
211 MMechostr(MSKRUNTIME, "_IsSensorEnabled : No Sensor Manager Initialized\n");
212 MMset(m, 0, NIL);
213 return 0;
214 }
215
216 SSensorType type = (SSensorType)MTOI(itype);
217 if (!SSensorManager::GetInstance()->IsAvailable(type))
218 {
219 MMechostr(MSKDEBUG, "_SetSensorEnable : invalid sensor\n");
220 MMset(m, 0, NIL);
221 return 0;
222 }
223
224 bool isEnabled = SSensorManager::GetInstance()->IsEnabled(type);
225 MMset(m, 0, ITOM(isEnabled ? 1 : 0));
226
227#ifdef _SCOL_DEBUG_
228 MMechostr(MSKDEBUG, "ok\n");
229#endif
230 return 0;
231}
232
244#if defined(ANDROID) || defined(_WIN32)
245int _SetSensorEnable(mmachine m)
246#else
247int _SetSensorEnableSync(mmachine m)
248#endif
249{
250#ifdef _SCOL_DEBUG_
251 MMechostr(MSKDEBUG, "_SetSensorEnable\n");
252#endif
253
254 int istate = MMpull(m);
255 int itype = MMget(m, 0);
256 if (itype == NIL)
257 {
258 MMechostr(MSKRUNTIME, "_SetSensorEnable : No Sensor Type Given\n");
259 MMset(m, 0, NIL);
260 return 0;
261 }
262
263 if (!SSensorManager::GetInstance())
264 {
265 MMechostr(MSKRUNTIME, "_SetSensorEnable : No Sensor Manager Initialized\n");
266 MMset(m, 0, NIL);
267 return 0;
268 }
269
270 SSensorType type = (SSensorType)MTOI(itype);
271 if (!SSensorManager::GetInstance()->IsAvailable(type))
272 {
273 MMechostr(MSKDEBUG, "_SetSensorEnable : invalid sensor\n");
274 MMset(m, 0, NIL);
275 return 0;
276 }
277
278 bool state = false;
279 if (istate != NIL && MTOI(istate) > 0)
280 state = true;
281
282 int success = SSensorManager::GetInstance()->SetSensorEnable(type, state);
283
284 MMset(m, 0, ITOM((success == 1) ? 1 : NIL));
285
286#ifdef _SCOL_DEBUG_
287 MMechostr(MSKDEBUG, "ok\n");
288#endif
289
290 return 0;
291}
292
293#if !defined(ANDROID) && !defined(_WIN32)
294int _SetSensorEnable(mmachine m)
295{
296 CallMainThread((void*)_SetSensorEnableSync, m);
297 return 0;
298}
299#endif
300
310int _GetVectorData(mmachine m)
311{
312#ifdef _SCOL_DEBUG_
313 MMechostr(MSKDEBUG, "_GetVectorData\n");
314#endif
315
316 int itype = MMget(m, 0);
317 if (itype == NIL)
318 {
319 MMechostr(MSKRUNTIME, "_GetVectorData : No Sensor Type Given\n");
320 MMset(m, 0, NIL);
321 return 0;
322 }
323
324 if (!SSensorManager::GetInstance())
325 {
326 MMechostr(MSKDEBUG, "_GetVectorData : No Sensor Manager Initialized\n");
327 MMset(m, 0, NIL);
328 return 0;
329 }
330
331 SSensorType type = (SSensorType)MTOI(itype);
332 if (!SSensorManager::GetInstance()->IsAvailable(type))
333 {
334 MMechostr(MSKDEBUG, "_SetSensorEnable : invalid sensor\n");
335 MMset(m, 0, NIL);
336 return 0;
337 }
338
339 SSensor* sensor = SSensorManager::GetInstance()->GetSensorByType(type);
340 if (!sensor)
341 {
342 MMechostr(MSKDEBUG, "_GetVectorData : invalid sensor\n");
343 MMset(m, 0, NIL);
344 return 0;
345 }
346
347 SSensorData sensorData = sensor->GetData();
348
349 int vectorData = MMmalloc(m, 3, TYPETAB);
350 if (vectorData == NIL)
351 {
352 MMset(m, 0, NIL);
353 return MERRMEM;
354 }
355
356 MMstore(m, vectorData, 0, FTOM((float)sensorData.vec3.x));
357 MMstore(m, vectorData, 1, FTOM((float)sensorData.vec3.y));
358 MMstore(m, vectorData, 2, FTOM((float)sensorData.vec3.z));
359 MMset(m, 0, PTOM(vectorData));
360
361#ifdef _SCOL_DEBUG_
362 MMechostr(MSKDEBUG, "ok\n");
363#endif
364
365 return 0;
366}
367
378{
379#ifdef _SCOL_DEBUG_
380 MMechostr(MSKDEBUG, "_GetDeviceQuaternionOrientation\n");
381#endif
382
383 double delayInSecond = 0;
384 int idelay = MMget(m, 0);
385 if (idelay != NIL)
386 delayInSecond = (double)(MTOI(idelay)) / 1000.0;
387
388 if (!SSensorManager::GetInstance())
389 {
390 MMechostr(MSKDEBUG, "_GetDeviceQuaternionOrientation : No Sensor Manager Initialized\n");
391 MMset(m, 0, NIL);
392 return 0;
393 }
394
395 if (!SSensorManager::GetInstance()->IsAvailable(SSENSOR_TYPE_ORIENTATION))
396 {
397 MMechostr(MSKDEBUG, "_GetDeviceQuaternionOrientation : sensor not available\n");
398 MMset(m, 0, NIL);
399 return 0;
400 }
401
402 Quaternion orientation = SSensorManager::GetInstance()->GetDeviceOrientation(delayInSecond);
403
404 int quatData = MMmalloc(m, 4, TYPETAB);
405 if (quatData == NIL)
406 {
407 MMechostr(MSKDEBUG, "_GetDeviceQuaternionOrientation : memory allocation error\n");
408 MMset(m, 0, NIL);
409 return MERRMEM;
410 }
411
412 MMstore(m, quatData, 0, FTOM(orientation.x));
413 MMstore(m, quatData, 1, FTOM(orientation.y));
414 MMstore(m, quatData, 2, FTOM(orientation.z));
415 MMstore(m, quatData, 3, FTOM(orientation.w));
416 MMset(m, 0, PTOM(quatData));
417
418#ifdef _SCOL_DEBUG_
419 MMechostr(MSKDEBUG, "ok\n");
420#endif
421
422 return 0;
423}
424
432/*int _GetDeviceEulerOrientation(mmachine m)
433{
434 #ifdef _SCOL_DEBUG_
435 MMechostr(MSKDEBUG,"_GetDeviceEulerOrientation\n");
436 #endif
437
438 if (!SSensorManager::GetInstance())
439 {
440 MMechostr(MSKDEBUG, "_GetDeviceEulerOrientation : No Sensor Manager Initialized");
441 MMpush(m, NIL);
442 return 0;
443 }
444
445 SSensor* sensor = SSensorManager::GetInstance()->GetSensorByType(SSENSOR_TYPE_ACCELEROMETER);
446 if (!sensor)
447 {
448 MMechostr(MSKDEBUG, "_GetVectorData : invalid sensor");
449 MMpush(m, NIL);
450 return 0;
451 }
452
453 Vector3d accel = sensor->GetData().vec3;
454 double yaw = 0.0;
455 double pitch = (atan2(-accel.y, accel.z)*180.0)/M_PI;
456 double roll = (atan2(accel.x, sqrt(accel.y*accel.y + accel.z*accel.z))*180.0)/M_PI;
457
458 int eulerData = MMmalloc(m, 3, TYPETAB);
459 if(eulerData==NIL)
460 {
461 MMechostr(MSKDEBUG, "_GetDeviceEulerOrientation : memory allocation error");
462 MMpush(m, NIL);
463 return MERRMEM;
464 }
465
466 MMstore(m, eulerData, 0, FTOM(pitch));
467 MMstore(m, eulerData, 1, FTOM(roll));
468 MMstore(m, eulerData, 2, FTOM(yaw));
469 MMpush(m, PTOM(eulerData));
470
471 #ifdef _SCOL_DEBUG_
472 MMechostr(MSKDEBUG,"ok\n");
473 #endif
474
475 return 0;
476}*/
477
487int _GetFloatData(mmachine m)
488{
489#ifdef _SCOL_DEBUG_
490 MMechostr(MSKDEBUG, "_GetFloatData\n");
491#endif
492
493 if (!SSensorManager::GetInstance())
494 {
495 MMechostr(MSKDEBUG, "_GetFloatData : No Sensor Manager Initialized\n");
496 MMset(m, 0, NIL);
497 return 0;
498 }
499
500 int itype = MMget(m, 0);
501 if (itype == NIL)
502 {
503 MMechostr(MSKRUNTIME, "_GetFloatData : No Sensor Type Given\n");
504 MMset(m, 0, NIL);
505 return 0;
506 }
507
508 SSensorType type = (SSensorType)MTOI(itype);
509 if (!SSensorManager::GetInstance()->IsAvailable(type))
510 {
511 MMechostr(MSKDEBUG, "_SetSensorEnable : invalid sensor\n");
512 MMset(m, 0, NIL);
513 return 0;
514 }
515
516 SSensor* sensor = SSensorManager::GetInstance()->GetSensorByType(type);
517 if (!sensor)
518 {
519 MMechostr(MSKDEBUG, "_GetFloatData : invalid sensor\n");
520 MMset(m, 0, NIL);
521 return 0;
522 }
523
524 SSensorData sensorData = sensor->GetData();
525
526 MMset(m, 0, FTOM(sensorData.fval));
527
528#ifdef _SCOL_DEBUG_
529 MMechostr(MSKDEBUG, "ok\n");
530#endif
531
532 return 0;
533}
534
544int _SetDeviceVibration(mmachine m)
545{
546#ifdef _SCOL_DEBUG_
547 MMechostr(MSKDEBUG, "_SetDeviceVibration\n");
548#endif
549
550 int itime = MMget(m, 0);
551 if (itime == NIL)
552 {
553 MMechostr(MSKRUNTIME, "_SetDeviceVibration : Define a time duration\n");
554 MMset(m, 0, NIL);
555 return 0;
556 }
557
558 if (MTOI(itime) <= 0)
559 {
560 MMechostr(MSKRUNTIME, "_SetDeviceVibration : Define a correct time duration\n");
561 MMset(m, 0, NIL);
562 return 0;
563 }
564
565 if (!SSensorManager::GetInstance())
566 {
567 MMechostr(MSKRUNTIME, "_SetDeviceVibration : No Sensor Manager Initialized\n");
568 MMset(m, 0, NIL);
569 return 0;
570 }
571
572 SSensorManager::GetInstance()->Vibrate(MTOI(itime));
573
574 MMset(m, 0, ITOM(1));
575
576#ifdef _SCOL_DEBUG_
577 MMechostr(MSKDEBUG, "ok\n");
578#endif
579 return 0;
580}
581
593{
594#ifdef _SCOL_DEBUG_
595 MMechostr(MSKDEBUG, "_SetDeviceVibrationPattern\n");
596#endif
597
598 int iloop = MMpull(m);
599 int ipattern = MMget(m, 0);
600 if (ipattern == NIL)
601 {
602 MMechostr(MSKRUNTIME, "_SetDeviceVibrationPattern : Define a pattern\n");
603 MMset(m, 0, NIL);
604 return 0;
605 }
606
607 if (!SSensorManager::GetInstance())
608 {
609 MMechostr(MSKRUNTIME, "_SetDeviceVibrationPattern : No Sensor Manager Initialized\n");
610 MMset(m, 0, NIL);
611 return 0;
612 }
613
614 bool loop = (MTOI(iloop) > 0) ? true : false;
615 ipattern = MTOP(ipattern);
616 std::vector<int> pattern;
617
618 int curptr = 0;
619 while (ipattern != NIL)
620 {
621 curptr = MTOI(MMfetch(m, ipattern, 0));
622 if (curptr != NIL)
623 {
624 pattern.push_back(curptr);
625
626 ipattern = MTOP(MMfetch(m, ipattern, 1));
627 }
628 }
629
630 SSensorManager::GetInstance()->VibratePattern(pattern, loop);
631
632 MMset(m, 0, ITOM(1));
633
634#ifdef _SCOL_DEBUG_
635 MMechostr(MSKDEBUG, "ok\n");
636#endif
637 return 0;
638}
639
648{
649#ifdef _SCOL_DEBUG_
650 MMechostr(MSKDEBUG, "_StartDeviceVibration\n");
651#endif
652
653 if (!SSensorManager::GetInstance())
654 {
655 MMechostr(MSKRUNTIME, "_StartDeviceVibration : No Sensor Manager Initialized\n");
656 MMpush(m, NIL);
657 return 0;
658 }
659
660 SSensorManager::GetInstance()->StartVibration();
661
662 MMpush(m, ITOM(1));
663
664#ifdef _SCOL_DEBUG_
665 MMechostr(MSKDEBUG, "ok\n");
666#endif
667 return 0;
668}
669
670
678int _StopDeviceVibration(mmachine m)
679{
680#ifdef _SCOL_DEBUG_
681 MMechostr(MSKDEBUG, "_StopDeviceVibration\n");
682#endif
683
684 if (!SSensorManager::GetInstance())
685 {
686 MMechostr(MSKRUNTIME, "_StopDeviceVibration : No Sensor Manager Initialized\n");
687 MMpush(m, NIL);
688 return 0;
689 }
690
691 SSensorManager::GetInstance()->StopVibration();
692
693 MMpush(m, ITOM(1));
694
695#ifdef _SCOL_DEBUG_
696 MMechostr(MSKDEBUG, "ok\n");
697#endif
698 return 0;
699}
700
701
709int _StartDeviceLocation(mmachine m)
710{
711#ifdef _SCOL_DEBUG_
712 MMechostr(MSKDEBUG, "_StartDeviceLocation\n");
713#endif
714
715#ifdef ANDROID
716 struct android_app* androidApp = (struct android_app*)SCgetExtra("this_inst");
717 if (androidApp)
718 {
719 JNIEnv* env = 0;
720 ANativeActivity* nativeActivity = androidApp->activity;
721 if (nativeActivity->vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK)
722 nativeActivity->vm->AttachCurrentThread(&env, NULL);
723
724 //wait for default authorization
725 jobject oActivity = nativeActivity->clazz;
726 jclass cActivity = env->GetObjectClass(oActivity);
727
728 bool authPassed = false;
729 while (!authPassed)
730 {
731 jfieldID reqBoolean = env->GetFieldID(cActivity, "mMinAuthPassed", "Z");
732 authPassed = (bool)env->GetBooleanField(oActivity, reqBoolean);
733 if (!authPassed)
734 boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
735 }
736
737 //check location permission
738 jmethodID location_permission = env->GetMethodID(cActivity, "RequestLocationPermission", "()V");
739 if (location_permission)
740 env->CallVoidMethod(oActivity, location_permission);
741
742 if (env->ExceptionCheck())
743 {
744 env->ExceptionClear();
745 MMechostr(MSKRUNTIME, "Android location exception : Check android.permission.FINE_LOCATION\n");
746 }
747
748 authPassed = false;
749 while (!authPassed)
750 {
751 jfieldID reqBoolean = env->GetFieldID(cActivity, "mLocationAuthPassed", "Z");
752 authPassed = (bool)env->GetBooleanField(oActivity, reqBoolean);
753 if (!authPassed)
754 boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
755 }
756 env->DeleteLocalRef(cActivity);
757 nativeActivity->vm->DetachCurrentThread();
758 }
759#endif
760
761 if (!SSensorManager::GetInstance())
762 {
763 MMechostr(MSKRUNTIME, "_StartDeviceLocation : No Sensor Manager Initialized\n");
764 MMpush(m, NIL);
765 return 0;
766 }
767
768 SSensorManager::GetInstance()->StartLocationService();
769
770 MMpush(m, ITOM(1));
771
772#ifdef _SCOL_DEBUG_
773 MMechostr(MSKDEBUG, "ok\n");
774#endif
775 return 0;
776}
777
778
786int _StopDeviceLocation(mmachine m)
787{
788#ifdef _SCOL_DEBUG_
789 MMechostr(MSKDEBUG, "_StopDeviceLocation\n");
790#endif
791
792 if (!SSensorManager::GetInstance())
793 {
794 MMechostr(MSKRUNTIME, "_StopDeviceLocation : No Sensor Manager Initialized\n");
795 MMpush(m, NIL);
796 return 0;
797 }
798
799 SSensorManager::GetInstance()->StopLocationService();
800
801 MMpush(m, ITOM(1));
802
803#ifdef _SCOL_DEBUG_
804 MMechostr(MSKDEBUG, "ok\n");
805#endif
806 return 0;
807}
808
809
817int _GetDeviceLocation(mmachine m)
818{
819#ifdef _SCOL_DEBUG_
820 MMechostr(MSKDEBUG, "_StopDeviceLocation\n");
821#endif
822
823 if (!SSensorManager::GetInstance())
824 {
825 MMechostr(MSKRUNTIME, "_GetDeviceLocation : No Sensor Manager Initialized\n");
826 MMpush(m, NIL);
827 return 0;
828 }
829
830 float lat, lon, alt = 0.0f;
831 if (!SSensorManager::GetInstance()->GetLocation(lon, lat, alt))
832 {
833 MMpush(m, NIL);
834 return 0;
835 }
836
837 int tuple = MMmalloc(m, 3, TYPETAB);
838 if (tuple == NIL)
839 {
840 MMset(m, 0, NIL);
841 return MERRMEM;
842 }
843 MMstore(m, tuple, 0, FTOM(lon));
844 MMstore(m, tuple, 1, FTOM(lat));
845 MMstore(m, tuple, 2, FTOM(alt));
846 MMpush(m, PTOM(tuple));
847
848#ifdef _SCOL_DEBUG_
849 MMechostr(MSKDEBUG, "ok\n");
850#endif
851 return 0;
852}
853
854
867int _GetLocationOffset(mmachine m)
868{
869#ifdef _SCOL_DEBUG_
870 MMechostr(MSKDEBUG, "_StopDeviceLocation\n");
871#endif
872 int lat = MMpull(m);
873 int lon = MMpull(m);
874 int rlat = MMpull(m);
875 int rlon = MMget(m, 0);
876
877 if ((lat == NIL) || (lon == NIL) || (rlat == NIL) || (rlon == NIL))
878 {
879 MMset(m, 0, NIL);
880 return 0;
881 }
882
883 double rolong = MTOF(rlon);
884 double rolat = MTOF(rlat);
885 double dlong = MTOF(lon);
886 double dlat = MTOF(lat);
887 double xoffset = 0.0;
888 double yoffset = 0.0;
889 geodeticOffsetInv(rolat, rolong, dlat, dlong, xoffset, yoffset);
890
891 int tuple = MMmalloc(m, 2, TYPETAB);
892 if (tuple == NIL)
893 {
894 MMset(m, 0, NIL);
895 return MERRMEM;
896 }
897 MMstore(m, tuple, 0, FTOM((float)xoffset));
898 MMstore(m, tuple, 1, FTOM((float)yoffset));
899 MMset(m, 0, PTOM(tuple));
900
901#ifdef _SCOL_DEBUG_
902 MMechostr(MSKDEBUG, "ok\n");
903#endif
904 return 0;
905}
906
907
923int _CrSensorCallBack(mmachine m)
924{
925#ifdef _SCOL_DEBUG_
926 MMechostr(0,"_CrSensorCallBack\n");
927#endif
928 // Declare local variables
929 int k = 0;
930
931 // Get the channel without pulling it (first element in the stack)
932 int pUser = MMget(m, 0);
933 int cbfun = MMget(m, 1);
934 int itype = MMget(m, 2);
935 int channel = MMget(m, 3);
936
937 // Test the channel
938 if (channel == NIL || cbfun == NIL)
939 {
940 MMechostr(MSKDEBUG, "Channel NIL\n");
941 SEDROP(m, 3); MMset(m, 0, NIL);
942 return 0;
943 }
944
945 SSensorType type = (SSensorType)MTOI(itype);
946 SSensorCb* sensorCb = SSensorManager::GetInstance()->AddSensorCallBack(type);
947 if (sensorCb == NULL)
948 {
949 MMechostr(MSKDEBUG,"Axis sensor failed\n");
950 SAFE_DELETE(sensorCb);
951 SEDROP(m, 3); MMset(m, 0, NIL);
952 return 0;
953 }
954
955 // re-push channel to create object
956 if ((k = MMpush(m, MMget(m, 3))))
957 return k; //channel
958
959 // Allocate a space in the stack for a table of axis sensor object
960 if ((MMpushPointer(m, sensorCb) != 0))
961 {
962 SAFE_DELETE(sensorCb);
963 MMset(m, 0, NIL);
964 return MERRMEM;
965 }
966
967 // Create a new scol joypad object
968 k = OBJcreate(m, OBJSENSORSCOL, SCOL_PTR sensorCb, NIL, 0);
969
970 /* add reflex */
971 if ((k = MMpush(m, MMget(m, 2))))
972 return k; /* reading callback */
973 if ((k = MMpush(m, MMget(m, 2))))
974 return k; /* user param */
975 if ((k = OBJaddreflex(m, OBJSENSORSCOL, SCOL_SENSOR_DATA_CB)))
976 return k;
977
978 k = MMpull(m); /* save object */
979 m->pp+=4;
980
981#ifdef _SCOL_DEBUG_
982 MMechostr(0,"ok\n");
983#endif
984
985 return MMpush(m, k);
986}
987
988
996int _DsSensorCallBack(mmachine m)
997{
998#ifdef _SCOL_DEBUG_
999 MMechostr(MSKDEBUG,"_DsSensorCallBack\n");
1000#endif
1001
1002 int sensorCb = MMget(m, 0);
1003 if (sensorCb == NIL)
1004 {
1005 MMset(m, 0, NIL);
1006 return 0;
1007 }
1008
1009 OBJdelTM(m, OBJSENSORSCOL, sensorCb);
1010 MMset(m, 0, ITOM(0));
1011
1012#ifdef _SCOL_DEBUG_
1013 MMechostr(MSKDEBUG,"ok\n");
1014#endif
1015 return 0;
1016}
1017
1018
1019
1023static NativeDefinition sSensorDef[] =
1024{
1025 { "ObjSensorCB", TYPTYPE, NULL, NULL},
1026 { "SENSOR_TYPE_UNKNOWN", TYPVAR, "I", SCOL_TYPTYPE(SSENSOR_TYPE_UNKNOWN) },
1027 { "SENSOR_TYPE_ACCELEROMETER", TYPVAR, "I", SCOL_TYPTYPE(SSENSOR_TYPE_ACCELEROMETER) },
1028 { "SENSOR_TYPE_MAGNETIC_FIELD", TYPVAR, "I", SCOL_TYPTYPE(SSENSOR_TYPE_MAGNETIC_FIELD) },
1029 { "SENSOR_TYPE_GYROSCOPE", TYPVAR, "I", SCOL_TYPTYPE(SSENSOR_TYPE_GYROSCOPE) },
1030 { "SENSOR_TYPE_LIGHT", TYPVAR, "I", SCOL_TYPTYPE(SSENSOR_TYPE_LIGHT) },
1031 { "SENSOR_TYPE_PROXIMITY", TYPVAR, "I", SCOL_TYPTYPE(SSENSOR_TYPE_PROXIMITY) },
1032 { "SENSOR_TYPE_ORIENTATION", TYPVAR, "I", SCOL_TYPTYPE(SSENSOR_TYPE_ORIENTATION) },
1033 { "_IsSensorAvailable", 1, "fun [I] I", _IsSensorAvailable },
1034 { "_IsSensorEnabled", 1, "fun [I] I", _IsSensorEnabled },
1035 { "_SetSensorEnable", 2, "fun [I I] I", _SetSensorEnable },
1036 { "_GetVectorData", 1, "fun [I] [F F F]", _GetVectorData },
1037 { "_GetFloatData", 1, "fun [I] F", _GetFloatData },
1038 { "_GetDeviceQuaternionOrientation", 1, "fun [I] [F F F F]", _GetDeviceQuaternionOrientation },
1039 { "_SetDeviceVibration", 1, "fun [I] I", _SetDeviceVibration },
1040 { "_SetDeviceVibrationPattern", 2, "fun [[I r1] I] I", _SetDeviceVibrationPattern },
1041 { "_StartDeviceVibration", 0, "fun [] I", _StartDeviceVibration },
1042 { "_StopDeviceVibration", 0, "fun [] I", _StopDeviceVibration },
1043 { "_StartDeviceLocation", 0, "fun [] I", _StartDeviceLocation },
1044 { "_StopDeviceLocation", 0, "fun [] I", _StopDeviceLocation },
1045 { "_GetDeviceLocation", 0, "fun [] [F F F]", _GetDeviceLocation },
1046 { "_GetLocationOffset", 4, "fun [F F F F] [F F]", _GetLocationOffset },
1047 { "_CrSensorCallBack", 4, "fun [Chn I fun [ObjSensorCB u0 [F F F] F F] u1 u0] ObjSensorCB", _CrSensorCallBack },
1048 { "_DsSensorCallBack", 1, "fun [ObjSensorCB] I", _DsSensorCallBack }
1049
1050};
1051
1052// Everything inside _cond and _endcond is ignored by doxygen
1054
1061int destroySensorObj(mmachine m, SCOL_PTR_TYPE handsys, int handscol)
1062{
1063 SSensorCb* sensorCb = MMgetPointer<SSensorCb*>(m, MTOP(handscol));
1064 SSensorManager::GetInstance()->RemoveSensorCallBack(sensorCb);
1065 MMsetPointer<SSensorCb*>(m, MTOP(handscol), 0);
1066
1067 // Display debug message
1068 MMechostr(MSKDEBUG,"Sensor object destroyed.\n");
1069 return 0;
1070}
1071
1078int getSensorData(mmachine m, SCOL_PTR_TYPE id, SCOL_PTR_TYPE param)
1079{
1080 int k = 0;
1081
1082 // Cast id parameter to axis sensor type
1083 SSensorCb* sensor = (SSensorCb*) id;
1084 SSensorData* ndata = (SSensorData*)param;
1085
1086 // Use : OBJbeginreflex(mmachine, type of object, ptr object, callback type)
1087 if (OBJbeginreflex(m, OBJSENSORSCOL, SCOL_PTR sensor, SCOL_SENSOR_DATA_CB))
1088 {
1089 MMechostr(MSKDEBUG,"Sensor not found\n");
1090 return 0;
1091 }
1092
1093 int tuple = MMmalloc(m, 3, TYPETAB);
1094 if(tuple==NIL)
1095 {
1096 MMpush(m,NIL);
1097 return MERRMEM;
1098 }
1099
1100 MMstore(m, tuple, 0, FTOM(ndata->vec3.x));
1101 MMstore(m, tuple, 1, FTOM(ndata->vec3.y));
1102 MMstore(m, tuple, 2, FTOM(ndata->vec3.z));
1103
1104 MMpush(m, PTOM(tuple));
1105 MMpush(m, FTOM(ndata->fval));
1106 MMpush(m, FTOM(ndata->delta));
1107
1108 // Call reflex previously defined
1109 k = OBJcallreflex(m, 3 /*nb param after obj and u0*/);
1110 delete ndata;
1111 return k;
1112}
1113
1114#if !defined(ANDROID) && !defined(_WIN32)
1115// For QT init in main thread
1116int _InitSensors(mmachine m)
1117{
1118 SSensorManager::GetInstance();
1119 return 0;
1120}
1121#endif
1122
1127int LoadSensor(mmachine m)
1128{
1129 int k = PKhardpak2(m, "SensorsEngine.pkg-1.0", sizeof(sSensorDef) / sizeof(sSensorDef[0]), sSensorDef);
1130
1131#if defined(ANDROID) || defined (_WIN32)
1132 SSensorManager::GetInstance();
1133#else
1134 CallMainThread = (int(__cdecl *)(void*, mmachine))SCgetExtra("callMainThread");
1135 CallMainThread((void*)_InitSensors, m);
1136#endif
1137
1138 return k;
1139}
1140
1141int CloseSensor()
1142{
1143 SSensorManager::GetInstance()->Kill();
1144 return 0;
1145}
1146
1148
1152#ifndef SCOL_STATIC
1153extern "C" SCOL_EXPORT void ScolPauseWindowPlugin(mmachine m)
1154#else
1155extern "C" SCOL_EXPORT void ScolSensorPauseWindowPlugin(mmachine m)
1156#endif
1157{
1158#ifdef ANDROID
1159 SSensorManager::GetInstance()->PauseSensorManager();
1160#endif
1161}
1162
1166#ifndef SCOL_STATIC
1167extern "C" SCOL_EXPORT void ScolResumeWindowPlugin(mmachine m)
1168#else
1169extern "C" SCOL_EXPORT void ScolSensorResumeWindowPlugin(mmachine m)
1170#endif
1171{
1172#ifdef ANDROID
1173 SSensorManager::GetInstance()->ResumeSensorManager();
1174#endif
1175}
1176
1181#ifndef SCOL_STATIC
1182extern "C" SCOL_EXPORT int ScolLoadPlugin(mmachine m, cbmachine w)
1183#else
1184extern "C" SCOL_EXPORT int ScolSensorLoadPlugin(mmachine m, cbmachine w)
1185#endif
1186{
1187 SCOLinitplugin(w);
1188 mm = m;
1189 OBJSENSORSCOL = OBJregister(1 /*nb of callback*/, 1, destroySensorObj, "OBJSENSORSCOL");
1190
1191 // ----- Define callbacks
1192 // Get a new user event
1193 SENSOR_DATA_CB = OBJgetUserEvent();
1194 // Associate this event with a callback
1195 OBJdefEvent(SENSOR_DATA_CB, getSensorData);
1196
1197 return LoadSensor(m);
1198}
1199
1204#ifndef SCOL_STATIC
1205extern "C" SCOL_EXPORT int ScolUnloadPlugin()
1206#else
1207extern "C" SCOL_EXPORT int ScolSensorUnloadPlugin()
1208#endif
1209{
1210 return CloseSensor();
1211}
int _GetVectorData(mmachine m)
_GetVectorData : get data from a sensor : get a 3D vector with float value
int _IsSensorAvailable(mmachine m)
_IsSensorAvailable : indicates if whether or not a sensor of the given type is available on the curre...
int _GetFloatData(mmachine m)
_GetDeviceEulerOrientation : get device orientation as euler angles
int _SetDeviceVibrationPattern(mmachine m)
_SetDeviceVibrationPattern : Set a vibration pattern from a time / pause list
int _GetDeviceLocation(mmachine m)
_GetDeviceLocation : Get the device location
int _StopDeviceLocation(mmachine m)
_StopDeviceLocation : Stop the device location service
int _StartDeviceLocation(mmachine m)
_StartDeviceLocation : Start the device location service
int _SetSensorEnableSync(mmachine m)
_SetSensorEnable : enable or disable a sensor of a given type.
int _DsSensorCallBack(mmachine m)
_DsSensorCallBack : Destroy sensor callback object
int _StopDeviceVibration(mmachine m)
_StopDeviceVibration : Stop the device vibration
int _StartDeviceVibration(mmachine m)
_StartDeviceVibration : Start the device vibration
int _GetLocationOffset(mmachine m)
_GetLocationOffset : Get the offset from a longitude / latitude reference in meters
int _GetDeviceQuaternionOrientation(mmachine m)
_GetDeviceQuaternionOrientation : get device orientation in x seconds (quaternion)
int _IsSensorEnabled(mmachine m)
_IsSensorEnabled : indicates if whether or not the sensor of the given type is enabled.
int _SetDeviceVibration(mmachine m)
_SetDeviceVibration : Set a vibration time duration on the device