/
LowApi.cs
1143 lines (1017 loc) · 60.1 KB
/
LowApi.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
using System;
using System.Text;
using System.Linq;
using System.Runtime.InteropServices;
namespace Baku.Quma.Low.Api
{
/// <summary>
/// <para>ネイティブAPIで"QmLow"から始まっているAPI関数のラッパをまとめたクラスです。</para>
/// <para>全ての関数は接頭辞"QmLow"を省略したそれっぽい名前でラップされ、入れ子クラスのいずれかに配置されています。</para>
/// <para>このクラスは拡張性のためアセンブリ外部にも公開されていますが、基本的にはユーザが直接使うことは想定されていません。</para>
/// </summary>
public static class QmLow
{
private const string DllName86 = DllImportSetting.DllName86;
private const string DllName64 = DllImportSetting.DllName64;
private static readonly bool Is64bit = DllImportSetting.Is64bit;
/// <summary>APIで使われている定数</summary>
public static class ApiConstants
{
/// <summary>APIが接続できるデバイス数の上限です。</summary>
public const int DEVICE_ID_LENGTH = 12;
/// <summary>APIバージョンを表す文字列のバッファ長です。</summary>
public const int API_VERSION_STR_MAX_LENGTH = 64;
/// <summary>デバイスIDの文字列バッファ長です。</summary>
public const int ID_BUFFER_SIZE = 256;
/// <summary>デバイス名の文字列バッファ長です。</summary>
public const int QUMAHANDLE_NAME_SIZE = 128;
/// <summary>ボーン名の文字列バッファ長です。</summary>
public const int QUMABONE_NAME_NAX_SIZE = 128;
/// <summary>タイムアウトを無効化する数値の一つです。</summary>
public static readonly uint TIMEOUT_DISABLE_0 = 0;
/// <summary>タイムアウトを無効化する数値の一つです。</summary>
public static readonly uint TIMEOUT_DISABLE_1 = 0x7fffffff;
/// <summary>タイムアウトを無効化する数値の一つです。</summary>
public static readonly uint TIMEOUT_DISABLE_2 = 0xffffffff;
}
/// <summary>初期化、設定、終了のAPI</summary>
public static class BaseOperation
{
#region privateなDllImport
#region _Initialize
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowInitialize@@YAHXZ")]
private static extern QumaLowResponse _Initialize86();
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowInitialize@@YAHXZ")]
private static extern QumaLowResponse _Initialize64();
private static QumaLowResponse _Initialize() => Is64bit ? _Initialize64() : _Initialize86();
#endregion
#region GetVersion
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetVersion@@YAXPA_W@Z")]
private static extern void GetVersion86([MarshalAs(UnmanagedType.LPWStr, SizeConst = ApiConstants.API_VERSION_STR_MAX_LENGTH)]StringBuilder res);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetVersion@@YAXPEA_W@Z")]
private static extern void GetVersion64([MarshalAs(UnmanagedType.LPWStr, SizeConst = ApiConstants.API_VERSION_STR_MAX_LENGTH)]StringBuilder res);
private static void GetVersion(StringBuilder res)
{
if (Is64bit)
{
GetVersion64(res);
} else
{
GetVersion86(res);
}
}
#endregion
#region GetDeviceID
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetDeviceID@@YAXPAXPAE@Z")]
private static extern void GetDeviceID86(IntPtr qumaHandle, IntPtr result);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetDeviceID@@YAXPEAXPEAE@Z")]
private static extern void GetDeviceID64(IntPtr qumaHandle, IntPtr result);
private static void GetDeviceID(IntPtr qumaHandle, IntPtr result)
{
if(Is64bit)
{
GetDeviceID64(qumaHandle, result);
}
else
{
GetDeviceID86(qumaHandle, result);
}
}
#endregion
#region GetDeviceName
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetDeviceName@@YAXPAXPA_W@Z")]
private static extern void GetDeviceName86(IntPtr qumaHandle, [MarshalAs(UnmanagedType.LPWStr, SizeConst = ApiConstants.QUMAHANDLE_NAME_SIZE)]StringBuilder result);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetDeviceName@@YAXPEAXPEA_W@Z")]
private static extern void GetDeviceName64(IntPtr qumaHandle, [MarshalAs(UnmanagedType.LPWStr, SizeConst = ApiConstants.QUMAHANDLE_NAME_SIZE)]StringBuilder result);
private static void GetDeviceName(IntPtr qumaHandle, StringBuilder result)
{
if (Is64bit)
{
GetDeviceName64(qumaHandle, result);
}
else
{
GetDeviceName86(qumaHandle, result);
}
}
#endregion
#region SetTimeout
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowSetTimeout@@YAHPAXI@Z")]
private static extern QumaLowResponse SetTimeout86(IntPtr qumaHandle, uint timeout);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowSetTimeout@@YAHPEAXI@Z")]
private static extern QumaLowResponse SetTimeout64(IntPtr qumaHandle, uint timeout);
private static QumaLowResponse SetTimeout(IntPtr qumaHandle, uint timeout)
=> Is64bit ? SetTimeout64(qumaHandle, timeout) : SetTimeout86(qumaHandle, timeout);
#endregion
#region SetDebugWrite
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowSetDebugWrite@@YAX_N@Z")]
private static extern void SetDebugWrite86(bool isEnable);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowSetDebugWrite@@YAX_N@Z")]
private static extern void SetDebugWrite64(bool isEnable);
#endregion
#region SetCoordinateSystem
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowSetCoordinateSystem@@YAXW4QMLOW_COORDINATE_SYSTEM@@@Z")]
private static extern void SetCoordinateSystem86(CoordinateSystem coordinateSystem);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowSetCoordinateSystem@@YAXW4QMLOW_COORDINATE_SYSTEM@@@Z")]
private static extern void SetCoordinateSystem64(CoordinateSystem coordinateSystem);
#endregion
#region SetRotateDirection
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowSetRotateDirection@@YAXW4QMLOW_ROTATE_DIRECTION@@@Z")]
private static extern void SetRotateDirection86(RotateDirection direction);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowSetRotateDirection@@YAXW4QMLOW_ROTATE_DIRECTION@@@Z")]
private static extern void SetRotateDirection64(RotateDirection direction);
#endregion
#region Exit
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowExit@@YAHXZ")]
private static extern QumaLowResponse Exit86();
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowExit@@YAHXZ")]
private static extern QumaLowResponse Exit64();
#endregion
#endregion
#region publicなラップ済関数
private static object _initializedLock = new object();
private static bool _initialized = false;
/// <summary><see cref="Initialize"/>関数が一度以上呼ばれているかどうかを取得します。このプロパティはスレッドセーフです。</summary>
public static bool Initialized
{
get
{
lock (_initializedLock)
{
return _initialized;
}
}
set
{
lock (_initializedLock)
{
_initialized = value;
}
}
}
/// <summary>
/// Quma APIライブラリを初期化します。ライブラリの使用前に必ず呼び出してください。
/// この関数は本来のAPIをプロセス中で1度しか呼ばないよう状態管理を行います。
/// </summary>
/// <returns>起動に成功した場合と2回目以降の呼び出しでは<see cref="QumaLowResponse.OK"/></returns>
public static QumaLowResponse Initialize()
{
if (!Initialized)
{
Initialized = true;
return _Initialize();
}
else
{
return QumaLowResponse.OK;
}
}
/// <summary>APIを終了します。ライブラリを使い終わったら呼び出してください。</summary>
/// <returns>終了に成功するとOKを返します。</returns>
public static QumaLowResponse Exit() => Is64bit ? Exit64() : Exit86();
/// <summary>
/// Quma Driverのバージョン情報を取得します。
/// </summary>
/// <returns>バージョン情報</returns>
public static string GetVersion()
{
var result = new StringBuilder(ApiConstants.API_VERSION_STR_MAX_LENGTH);
GetVersion(result);
return result.ToString();
}
/// <summary>QumaのデバイスIDと呼ばれるバイト列を取得します.</summary>
/// <param name="qumaHandle">デバイスIDを取得するQumaのハンドル</param>
/// <returns>デバイスID</returns>
public static byte[] GetDeviceID(QumaHandle qumaHandle)
{
var result = new byte[ApiConstants.DEVICE_ID_LENGTH];
var resultPtr = Marshal.AllocHGlobal(sizeof(byte) * ApiConstants.DEVICE_ID_LENGTH);
GetDeviceID(qumaHandle.Handle, resultPtr);
Marshal.Copy(resultPtr, result, 0, ApiConstants.DEVICE_ID_LENGTH);
Marshal.FreeHGlobal(resultPtr);
return result;
}
/// <summary>Qumaのデバイス名を取得します.</summary>
/// <param name="qumaHandle">デバイス名を取得するQumaのハンドル</param>
/// <returns>デバイス名</returns>
public static string GetDeviceName(QumaHandle qumaHandle)
{
var result = new StringBuilder(ApiConstants.QUMAHANDLE_NAME_SIZE);
GetDeviceName(qumaHandle.Handle, result);
return result.ToString();
}
/// <summary>
/// デバッグ出力のオン/オフを設定します。
/// </summary>
/// <param name="isEnable">デバッグ出力を行う場合true</param>
public static void SetDebugWrite(bool isEnable)
{
if (Is64bit)
{
SetDebugWrite64(isEnable);
}
else
{
SetDebugWrite86(isEnable);
}
}
/// <summary>ライブラリ内で使う座標系を設定します。</summary>
/// <param name="coordinateSystem">座標系。デフォルトでは左手系が使用されます。</param>
public static void SetCoordinateSystem(CoordinateSystem coordinateSystem)
{
if (Is64bit)
{
SetCoordinateSystem64(coordinateSystem);
}
else
{
SetCoordinateSystem86(coordinateSystem);
}
}
/// <summary>回転正方向を設定します。</summary>
/// <param name="direction">回転方向。デフォルトでは右回転が正です。</param>
public static void SetRotateDirection(RotateDirection direction)
{
if (Is64bit)
{
SetRotateDirection64(direction);
}
else
{
SetRotateDirection86(direction);
}
}
/// <summary>
/// <para>ミリ秒単位でタイムアウトを設定します。デフォルトではタイムアウトは無効化されています。</para>
/// <para>API仕様上引数に0, 0x7fffffff, 0xffffffffのいずれかを指定すると例外が発生します。</para>
/// <para>タイムアウトを無効化する場合<see cref="DisableTimeout(QumaHandle)"/>を用いてください。</para>
/// </summary>
/// <param name="qumaHandle">Qumaデバイスのハンドル</param>
/// <param name="timeout">指定する秒数(ミリ秒単位)</param>
/// <returns>設定に成功: OK</returns>
/// <exception cref="ArgumentException" />
/// <exception cref="QmLowException" />
public static void SetTimeout(QumaHandle qumaHandle, uint timeout)
{
if(timeout == ApiConstants.TIMEOUT_DISABLE_0 ||
timeout == ApiConstants.TIMEOUT_DISABLE_1 ||
timeout == ApiConstants.TIMEOUT_DISABLE_2)
{
throw new ArgumentException("given timeout value is invalid magic number: use DisableTimeout method instead");
}
var res = SetTimeout(qumaHandle.Handle, timeout);
if (res != QumaLowResponse.OK)
{
throw new QmLowException(res);
}
}
/// <summary>タイムアウトを無効化します。</summary>
/// <param name="qumaHandle">Qumaデバイスのハンドル</param>
/// <returns>設定に成功: OK</returns>
/// <exception cref="QmLowException">関数呼び出しに失敗した場合に発生します。</exception>
public static void DisableTimeout(QumaHandle qumaHandle)
{
var res = SetTimeout(qumaHandle.Handle, ApiConstants.TIMEOUT_DISABLE_0);
if (res != QumaLowResponse.OK)
{
throw new QmLowException(res);
}
}
#endregion
}
/// <summary>デバイスの列挙、取得、破棄API</summary>
public static class Device
{
#region privateなDllImport
#region EnumerateQumaIDs
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowEnumlateQumaIDs@@YAHPAUt_QmLowQumaID@@PAH@Z")]
private static extern QumaLowResponse EnumlateQumaIDs86(IntPtr arrayHeadPtr, ref int outIdCount);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowEnumlateQumaIDs@@YAHPEAUt_QmLowQumaID@@PEAH@Z")]
private static extern QumaLowResponse EnumlateQumaIDs64(IntPtr arrayHeadPtr, ref int outIdCount);
private static QumaLowResponse EnumlateQumaIDs(IntPtr arrayHeadPtr, ref int outIdCount)
=> Is64bit ? EnumlateQumaIDs64(arrayHeadPtr, ref outIdCount) : EnumlateQumaIDs86(arrayHeadPtr, ref outIdCount);
#endregion
#region GetQumaHandle
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetQumaHandle@@YAHUt_QmLowQumaID@@PAPAX@Z")]
private static extern QumaLowResponse GetQumaHandle86(QumaId qumaId, ref IntPtr resultHandle);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetQumaHandle@@YAHUt_QmLowQumaID@@PEAPEAX@Z")]
private static extern QumaLowResponse GetQumaHandle64(QumaId qumaId, ref IntPtr resultHandle);
private static QumaLowResponse GetQumaHandle(QumaId qumaId, ref IntPtr resultHandle)
=> Is64bit ? GetQumaHandle64(qumaId, ref resultHandle) : GetQumaHandle86(qumaId, ref resultHandle);
#endregion
//NOTE: 元のC/C++ヘッダによると、コイツの第二引数は普通NULLで良いらしい
#region ActivateQuma
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowActivateQuma@@YAHPAXPAUt_QmLowActivateInfo@@@Z")]
private static extern QumaLowResponse ActivateQuma86(IntPtr qumaHandle, IntPtr activeInfo);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowActivateQuma@@YAHPEAXPEAUt_QmLowActivateInfo@@@Z")]
private static extern QumaLowResponse ActivateQuma64(IntPtr qumaHandle, IntPtr activeInfo);
private static QumaLowResponse ActivateQuma(IntPtr qumaHandle, IntPtr activeInfo)
=> Is64bit ? ActivateQuma64(qumaHandle, activeInfo) : ActivateQuma86(qumaHandle, activeInfo);
#endregion
#region DeleteQumaHandle
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowDeleteQumaHandle@@YAHPAX@Z")]
private static extern QumaLowResponse DeleteQumaHandle86(IntPtr qumaHandle);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowDeleteQumaHandle@@YAHPEAX@Z")]
private static extern QumaLowResponse DeleteQumaHandle64(IntPtr qumaHandle);
private static QumaLowResponse DeleteQumaHandle(IntPtr qumaHandle)
=> Is64bit ? DeleteQumaHandle64(qumaHandle) : DeleteQumaHandle86(qumaHandle);
#endregion
#endregion
#region 公開ラッパー関数
/// <summary>Qumaのハンドル一覧を取得します。</summary>
/// <returns>IDとハンドルが組になったQumaデバイスの一覧</returns>
public static QumaId[] EnumerateQumaIDs()
{
//配列相当の領域を確保: 当然解放が必須
IntPtr qumaIdsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(QumaIds)));
int idCount = 0;
var res = EnumlateQumaIDs(qumaIdsPtr, ref idCount);
if (res == QumaLowResponse.OK)
{
QumaIds testIds = (QumaIds)Marshal.PtrToStructure(qumaIdsPtr, typeof(QumaIds));
Marshal.FreeHGlobal(qumaIdsPtr);
if(testIds.Ids != null)
{
return testIds.Ids.Take(idCount).ToArray();
}
else
{
return new QumaId[0];
}
}
else
{
Marshal.FreeHGlobal(qumaIdsPtr);
throw new QmLowException(res);
}
}
/// <summary>
/// IDを指定してデバイスのハンドルを取得します。
/// </summary>
/// <param name="qumaId">ハンドルを取得するためのID</param>
/// <returns>デバイスハンドル</returns>
/// <exception cref="QmLowException">ハンドルの取得に失敗した場合に発生します。</exception>
public static QumaHandle GetQumaHandle(QumaId qumaId)
{
IntPtr handle = IntPtr.Zero;
var response = GetQumaHandle(qumaId, ref handle);
if (response != QumaLowResponse.OK)
{
throw new QmLowException(response);
}
return new QumaHandle(handle);
}
/// <summary>Qumaを有効化します。</summary>
/// <param name="qumaHandle">有効化するQumaのハンドル</param>
/// <returns>成功した場合: OK</returns>
public static void ActivateQuma(QumaHandle qumaHandle)
{
var res = ActivateQuma(qumaHandle.Handle, IntPtr.Zero);
if (res != QumaLowResponse.OK)
{
throw new QmLowException(res);
}
}
/// <summary>
/// 指定したハンドルのデバイスを削除します。
/// この関数を呼び出さなくとも<see cref="BaseOperation.Exit"/>を使っていれば
/// 適切にリソース解放が行われるため、この関数を必ず呼び出す必要はありません。
/// 逆に、解放予定でないデバイスに対してこの関数を呼び出すと想定外の動作をする危険があります。
/// </summary>
/// <param name="qumaHandle">対象のデバイス</param>
public static void DeleteQumaHandle(QumaHandle qumaHandle)
{
var res = DeleteQumaHandle(qumaHandle.Handle);
if(res != QumaLowResponse.OK)
{
throw new QmLowException(res);
}
}
#endregion
}
/// <summary>ボーン関連のAPI</summary>
public static class Bone
{
#region privateなDllImport
#region GetRootBone
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetRootBone@@YAPAXPAX@Z")]
private static extern IntPtr GetRootBone86(IntPtr qumaHandle);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetRootBone@@YAPEAXPEAX@Z")]
private static extern IntPtr GetRootBone64(IntPtr qumaHandle);
private static IntPtr GetRootBone(IntPtr qumaHandle)
=> Is64bit ? GetRootBone64(qumaHandle) : GetRootBone86(qumaHandle);
#endregion
#region GetBoneByName
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetBoneByName@@YAPAXPAXPB_W@Z")]
private static extern IntPtr GetBoneByName86(IntPtr rootBone, [MarshalAs(UnmanagedType.LPWStr)]string name);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetBoneByName@@YAPEAXPEAXPEB_W@Z")]
private static extern IntPtr GetBoneByName64(IntPtr rootBone, [MarshalAs(UnmanagedType.LPWStr)]string name);
private static IntPtr GetBoneByName(IntPtr rootBone, string name)
=> Is64bit ? GetBoneByName64(rootBone, name) : GetBoneByName86(rootBone, name);
#endregion
#region GetBoneName
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetBoneName@@YAXPAXPA_W@Z")]
private static extern void GetBoneName86(IntPtr bone, [MarshalAs(UnmanagedType.LPWStr, SizeConst = ApiConstants.QUMABONE_NAME_NAX_SIZE)]StringBuilder result);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetBoneName@@YAXPEAXPEA_W@Z")]
private static extern void GetBoneName64(IntPtr bone, [MarshalAs(UnmanagedType.LPWStr, SizeConst = ApiConstants.QUMABONE_NAME_NAX_SIZE)]StringBuilder result);
private static void GetBoneName(IntPtr bone, StringBuilder result)
{
if(Is64bit)
{
GetBoneName64(bone, result);
}
else
{
GetBoneName86(bone, result);
}
}
#endregion
#region GetChildCount
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetChildCount@@YAHPAX@Z")]
private static extern int GetChildCount86(IntPtr bone);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetChildCount@@YAHPEAX@Z")]
private static extern int GetChildCount64(IntPtr bone);
private static int GetChildCount(IntPtr bone)
=> Is64bit ? GetChildCount64(bone) : GetChildCount86(bone);
#endregion
#region GetChildBone
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetChildBone@@YAPAXPAXH@Z")]
private static extern IntPtr GetChildBone86(IntPtr bone, int index);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetChildBone@@YAPEAXPEAXH@Z")]
private static extern IntPtr GetChildBone64(IntPtr bone, int index);
private static IntPtr GetChildBone(IntPtr bone, int index)
=> Is64bit ? GetChildBone64(bone, index) : GetChildBone86(bone, index);
#endregion
#region GetBonePosition
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetBonePosition@@YAXPAXPAM@Z")]
private static extern void GetBonePosition86(IntPtr boneHandle, IntPtr result);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetBonePosition@@YAXPEAXPEAM@Z")]
private static extern void GetBonePosition64(IntPtr boneHandle, IntPtr result);
private static void GetBonePosition(IntPtr boneHandle, IntPtr result)
{
if(Is64bit)
{
GetBonePosition64(boneHandle, result);
}
else
{
GetBonePosition86(boneHandle, result);
}
}
#endregion
#region ComputeBoneMatrix
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowComputeBoneMatrix@@YAHPAX0PAM@Z")]
private static extern QumaLowResponse ComputeBoneMatrix86(IntPtr qumaHandle, IntPtr bone, IntPtr result);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowComputeBoneMatrix@@YAHPEAX0PEAM@Z")]
private static extern QumaLowResponse ComputeBoneMatrix64(IntPtr qumaHandle, IntPtr bone, IntPtr result);
private static QumaLowResponse ComputeBoneMatrix(IntPtr qumaHandle, IntPtr bone, IntPtr result)
=> Is64bit ? ComputeBoneMatrix64(qumaHandle, bone, result) : ComputeBoneMatrix86(qumaHandle, bone, result);
#endregion
#endregion
#region 公開ラッパー関数
/// <summary>ルート要素となるボーンを取得します。</summary>
/// <param name="qumaHandle">Qumaのハンドル</param>
/// <returns>ルートボーンのハンドル</returns>
public static BoneHandle GetRootBone(QumaHandle qumaHandle)
{
IntPtr boneHandlePtr = GetRootBone(qumaHandle.Handle);
return new BoneHandle(boneHandlePtr);
}
/// <summary>
/// ルートボーンとボーン名を指定して子ボーンを取得します。
/// </summary>
/// <param name="rootBone">ルートボーンのハンドル</param>
/// <param name="name">子ボーンの名前</param>
/// <param name="result">成功した場合は指定した子ボーン、失敗した場合はnull</param>
/// <returns>ボーンの取得に成功したか否か</returns>
public static bool TryGetBoneByName(BoneHandle rootBone, string name, out BoneHandle result)
{
IntPtr resultHandle = GetBoneByName(rootBone.Handle, name);
if (resultHandle != IntPtr.Zero)
{
result = new BoneHandle(resultHandle);
return true;
}
else
{
result = null;
return false;
}
}
/// <summary>
/// ルートボーンとボーン名を指定して子ボーンを取得します。
/// </summary>
/// <param name="rootBone">ルートボーンのハンドル</param>
/// <param name="name">子ボーンの名前</param>
/// <returns>指定した子ボーン</returns>
/// <exception cref="InvalidOperationException">
/// 指定した子ボーンが見つからない場合に発生。
/// 例外を起こしたくない場合は<see cref="TryGetBoneByName(BoneHandle, string, out BoneHandle)"/>を使ってください。
/// </exception>
public static BoneHandle GetBoneByName(BoneHandle rootBone, string name)
{
IntPtr result = GetBoneByName(rootBone.Handle, name);
if (result == IntPtr.Zero)
{
throw new InvalidOperationException("Bone was not found");
}
return new BoneHandle(result);
}
/// <summary>
/// ボーンを指定してボーンの名前を取得します。
/// </summary>
/// <param name="boneHandle">対象ボーン</param>
/// <returns>ボーンの名称</returns>
public static string GetBoneName(BoneHandle boneHandle)
{
var result = new StringBuilder(ApiConstants.QUMABONE_NAME_NAX_SIZE);
GetBoneName(boneHandle.Handle, result);
return result.ToString();
}
/// <summary>
/// ボーンを指定して子ボーンの数を取得します。
/// </summary>
/// <param name="boneHandle">子ボーンの数を調べたいボーン</param>
/// <returns>子ボーンの数</returns>
public static int GetChildCount(BoneHandle boneHandle)
{
return GetChildCount(boneHandle.Handle);
}
/// <summary>
/// ボーンの子ボーンをインデクスの指定によって取得します。
/// </summary>
/// <param name="boneHandle">対象ボーン</param>
/// <param name="index">子ボーンのインデックス</param>
/// <returns>結果を収納したボーン。取得に失敗した場合、IntPtr.Zeroを持ったハンドルになります。</returns>
public static BoneHandle GetChildBone(BoneHandle boneHandle, int index)
{
return new BoneHandle(GetChildBone(boneHandle.Handle, index));
}
/// <summary>親ボーンを指定して子ボーンの一覧を取得します。</summary>
/// <param name="bone">親となるボーン</param>
/// <returns>子となるボーンの一覧。子が無い場合は要素数0の配列を返します。</returns>
public static BoneHandle[] GetChildBones(BoneHandle boneHandle)
{
int childCount = GetChildCount(boneHandle.Handle);
var result = new BoneHandle[childCount];
for (int i = 0; i < childCount; i++)
{
result[i] = new BoneHandle(GetChildBone(boneHandle.Handle, i));
}
return result;
}
/// <summary>
/// デバイスとボーンを指定してボーンの位置を取得します。
/// </summary>
/// <param name="qumaHandle">対象デバイス</param>
/// <param name="boneHandle">対象ボーン</param>
/// <returns>ボーンの位置</returns>
public static Vector3 GetBonePosition(BoneHandle boneHandle)
{
var vectorArray = new float[3];
var vectorPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(float)) * 3);
GetBonePosition(boneHandle.Handle, vectorPtr);
Marshal.Copy(vectorPtr, vectorArray, 0, 3);
Marshal.FreeHGlobal(vectorPtr);
return new Vector3(vectorArray);
}
/// <summary>
/// デバイスとボーンを指定して、ボーンに関連づけられた行列を取得します。
/// </summary>
/// <param name="qumaHandle">デバイスのハンドル</param>
/// <param name="boneHandle">ボーンのハンドル</param>
/// <returns>ボーンに関連づけられた行列</returns>
public static Matrix4 ComputeBoneMatrix(QumaHandle qumaHandle, BoneHandle boneHandle)
{
var matrixPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(float)) * 16);
var response = ComputeBoneMatrix(qumaHandle.Handle, boneHandle.Handle, matrixPtr);
if (response == QumaLowResponse.OK)
{
var matrixArray = new float[16];
Marshal.Copy(matrixPtr, matrixArray, 0, 16);
Marshal.FreeHGlobal(matrixPtr);
return new Matrix4(matrixArray);
}
else
{
Marshal.FreeHGlobal(matrixPtr);
throw new QmLowException(response);
}
}
#endregion
}
/// <summary>各ボーンのセンサーと加速度計のAPI</summary>
public static class Sensors
{
#region privateなDllImport
#region GetSensorCount
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetSensorCount@@YAHPAX@Z")]
private static extern int GetSensorCount86(IntPtr bone);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetSensorCount@@YAHPEAX@Z")]
private static extern int GetSensorCount64(IntPtr bone);
private static int GetSensorCount(IntPtr bone)
=> Is64bit ? GetSensorCount64(bone) : GetSensorCount86(bone);
#endregion
#region GetSensor
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetSensor@@YAPAXPAXH@Z")]
private static extern IntPtr GetSensor86(IntPtr bone, int index);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetSensor@@YAPEAXPEAXH@Z")]
private static extern IntPtr GetSensor64(IntPtr bone, int index);
private static IntPtr GetSensor(IntPtr bone, int index) => Is64bit ? GetSensor64(bone, index) : GetSensor86(bone, index);
#endregion
#region GetSensorAxis
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetSensorAxis@@YAXPAXPAM@Z")]
private static extern void GetSensorAxis86(IntPtr sensor, IntPtr result);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetSensorAxis@@YAXPEAXPEAM@Z")]
private static extern void GetSensorAxis64(IntPtr sensor, IntPtr result);
private static void GetSensorAxis(IntPtr sensor, IntPtr result)
{
if(Is64bit)
{
GetSensorAxis64(sensor, result);
}
else
{
GetSensorAxis86(sensor, result);
}
}
#endregion
#region GetSensorState
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetSensorState@@YA?AW4QMLOW_SENSOR_STATE@@PAX0@Z")]
private static extern SensorStates GetSensorState86(IntPtr qumaHandle, IntPtr sensor);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetSensorState@@YA?AW4QMLOW_SENSOR_STATE@@PEAX0@Z")]
private static extern SensorStates GetSensorState64(IntPtr qumaHandle, IntPtr sensor);
private static SensorStates GetSensorState(IntPtr qumaHandle, IntPtr sensor)
=> Is64bit ? GetSensorState64(qumaHandle, sensor) : GetSensorState86(qumaHandle, sensor);
#endregion
#region ComputeSensorAngle
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowComputeSensorAngle@@YAHPAX0PAM@Z")]
private static extern QumaLowResponse ComputeSensorAngle86(IntPtr qumaHandle, IntPtr sensor, ref float f);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowComputeSensorAngle@@YAHPEAX0PEAM@Z")]
private static extern QumaLowResponse ComputeSensorAngle64(IntPtr qumaHandle, IntPtr sensor, ref float f);
private static QumaLowResponse ComputeSensorAngle(IntPtr qumaHandle, IntPtr sensor, ref float f)
=> Is64bit ? ComputeSensorAngle64(qumaHandle, sensor, ref f) : ComputeSensorAngle86(qumaHandle, sensor, ref f);
#endregion
#region GetAccelerometer
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetAccelerometer@@YAHPAXPAM@Z")]
private static extern QumaLowResponse GetAccelerometer86(IntPtr qumaHandle, IntPtr result);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetAccelerometer@@YAHPEAXPEAM@Z")]
private static extern QumaLowResponse GetAccelerometer64(IntPtr qumaHandle, IntPtr result);
private static QumaLowResponse GetAccelerometer(IntPtr qumaHandle, IntPtr result)
=> Is64bit ? GetAccelerometer64(qumaHandle, result) : GetAccelerometer86(qumaHandle, result);
#endregion
#region GetAccelerometerPoseMatrix
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetAccelerometerPoseMatrix@@YAHPAXPAM@Z")]
private static extern QumaLowResponse GetAccelerometerPoseMatrix86(IntPtr qumaHandle, IntPtr result);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowGetAccelerometerPoseMatrix@@YAHPEAXPEAM@Z")]
private static extern QumaLowResponse GetAccelerometerPoseMatrix64(IntPtr qumaHandle, IntPtr result);
private static QumaLowResponse GetAccelerometerPoseMatrix(IntPtr qumaHandle, IntPtr result)
=> Is64bit ? GetAccelerometerPoseMatrix64(qumaHandle, result) : GetAccelerometerPoseMatrix86(qumaHandle, result);
#endregion
#endregion
#region 公開ラッパー関数
/// <summary>
/// ボーンを指定してセンサーの個数を取得します。
/// </summary>
/// <param name="boneHandle">確認対象のボーン</param>
/// <returns>ボーンに割り当てられたセンサーの個数</returns>
public static int GetSensorCount(BoneHandle boneHandle)
{
return GetSensorCount(boneHandle.Handle);
}
/// <summary>
/// ボーンとインデックスを指定してセンサーへのハンドルを取得します。
/// </summary>
/// <param name="boneHandle">対象のボーン</param>
/// <param name="index">
/// 取得するセンサのインデックス。インデックス範囲を調べるには
/// <see cref="GetSensorCount(BoneHandle)"/>を使います。
/// </param>
/// <returns></returns>
public static SensorHandle GetSensor(BoneHandle boneHandle, int index)
{
return new SensorHandle(GetSensor(boneHandle.Handle, index));
}
/// <summary>
/// ボーンを指定してボーンに関連づけられるセンサーの一覧を取得します。
/// </summary>
/// <param name="boneHandle">対象のボーン</param>
/// <returns>ボーンに関連づけられるセンサーの一覧</returns>
public static SensorHandle[] GetSensors(BoneHandle boneHandle)
{
int count = GetSensorCount(boneHandle);
var result = new SensorHandle[count];
for (int i = 0; i < count; i++)
{
result[i] = GetSensor(boneHandle, i);
}
return result;
}
/// <summary>
/// センサーを指定して3軸の値を読み取ります。
/// </summary>
/// <param name="sensorHandle">調べる対象のセンサー</param>
/// <returns>読みだされた3軸の値</returns>
public static Vector3 GetSensorAxis(SensorHandle sensorHandle)
{
var vectorPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(float)) * 3);
GetSensorAxis(sensorHandle.Handle, vectorPtr);
var result = new float[3];
Marshal.Copy(vectorPtr, result, 0, 3);
Marshal.FreeHGlobal(vectorPtr);
return new Vector3(result);
}
/// <summary>
/// デバイスとセンサーを指定してセンサーの状態を取得します。
/// </summary>
/// <param name="qumaHandle">対象のデバイス</param>
/// <param name="sensorHandle">対象のセンサー</param>
/// <returns>センサーの状態</returns>
public static SensorStates GetSensorState(QumaHandle qumaHandle, SensorHandle sensorHandle)
{
return GetSensorState(qumaHandle.Handle, sensorHandle.Handle);
}
/// <summary>
/// デバイスとセンサーを指定して角度を求めます。
/// </summary>
/// <param name="qumaHandle">対象のデバイス</param>
/// <param name="sensorHandle">対象のセンサー</param>
/// <returns>角度値</returns>
/// <exception cref="QmLowException">呼び出しが正常な場合以外に発生します。</exception>
public static float ComputeSensorAngle(QumaHandle qumaHandle, SensorHandle sensorHandle)
{
float result = 0.0f;
var response = ComputeSensorAngle(qumaHandle.Handle, sensorHandle.Handle, ref result);
if (response != QumaLowResponse.OK)
{
throw new QmLowException(response);
}
return result;
}
/// <summary>
/// デバイスとセンサーを指定して角度を求めます。このメソッドは例外を発生しません。
/// </summary>
/// <param name="qumaHandle">対象のデバイス</param>
/// <param name="sensorHandle">対象のセンサー</param>
/// <param name="result">結果を収納する値。関数の呼び出しに失敗した場合は何も代入されません。</param>
/// <returns>関数呼び出しの結果。OKが返ってきた場合は正しく値が取得出来ており、他の場合では失敗しています。</returns>
public static QumaLowResponse TryComputeSensorAngle(QumaHandle qumaHandle, SensorHandle sensorHandle, ref float result)
{
return ComputeSensorAngle(qumaHandle.Handle, sensorHandle.Handle, ref result);
}
/// <summary>
/// <para>フィルタ処理をおこなっていない加速度センサの状態を取得します。</para>
/// <para>この値は、加速度センサの設置状態に対するセンサ値です。</para>
/// <para>Qumarionから値を取得する場合、加速度センサは、QUMARION本体グリップ内に設置されているため、胸を正面に向けた場合、25度傾いています。</para>
/// </summary>
/// <param name="qumaHandle">デバイスのハンドル</param>
/// <returns>加速度計の読み</returns>
/// <exception cref="QmLowException" />
public static Vector3 GetAccelerometer(QumaHandle qumaHandle)
{
var vectorPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(float)) * 3);
var response = GetAccelerometer(qumaHandle.Handle, vectorPtr);
if (response == QumaLowResponse.OK)
{
var vectorArray = new float[3];
Marshal.Copy(vectorPtr, vectorArray, 0, 3);
Marshal.FreeHGlobal(vectorPtr);
return new Vector3(vectorArray);
}
else
{
Marshal.FreeHGlobal(vectorPtr);
throw new QmLowException(response);
}
}
/// <summary>
/// <para>フィルタ処理をおこなっていない加速度センサの状態を取得します。</para>
/// <para>この値は、加速度センサの設置状態に対するセンサ値です。</para>
/// <para>Qumarionから値を取得する場合、加速度センサは、QUMARION本体グリップ内に設置されているため、胸を正面に向けた場合、25度傾いています。</para>
/// </summary>
/// <param name="qumaHandle">デバイスのハンドル</param>
/// <param name="result">成功した場合結果を受け取るベクトル</param>
/// <returns>処理が成功した場合OK、失敗の場合はそれ以外</returns>
public static QumaLowResponse TryGetAccelerometer(QumaHandle qumaHandle, out Vector3 result)
{
var vectorPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(float)) * 3);
var response = GetAccelerometer(qumaHandle.Handle, vectorPtr);
if (response == QumaLowResponse.OK)
{
var vectorArray = new float[3];
Marshal.Copy(vectorPtr, vectorArray, 0, 3);
result = new Vector3(vectorArray);
}
else
{
result = new Vector3(new float[3]);
}
Marshal.FreeHGlobal(vectorPtr);
return response;
}
/// <summary>
/// <para>デバイスを指定して加速度計から求まる姿勢行列を取得します。</para>
/// <para>Qumarionから値を取得する場合、加速度センサは、QUMARION本体グリップ内に設置されていっるため、胸を正面に向けた場合、25度傾いています。</para>
/// <para>この関数は、加速度センサ値にローパスフィルタ処理を施した後、25度の傾きを補正し、胸を正面に向けた状態からの回転角度を行列を取得することができます。</para>
/// </summary>
/// <param name="qumaHandle">対象のデバイス</param>
/// <returns>加速度計に関する姿勢行列</returns>
/// <exception cref="QmLowException" />
public static Matrix4 GetAccelerometerPoseMatrix(QumaHandle qumaHandle)
{
var matrixPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(float)) * 16);
var response = GetAccelerometerPoseMatrix(qumaHandle.Handle, matrixPtr);
if (response == QumaLowResponse.OK)
{
var matrixArray = new float[16];
Marshal.Copy(matrixPtr, matrixArray, 0, 16);
Marshal.FreeHGlobal(matrixPtr);
return new Matrix4(matrixArray);
}
else
{
Marshal.FreeHGlobal(matrixPtr);
throw new QmLowException(response);
}
}
/// <summary>
/// <para>デバイスを指定して加速度計から求まる姿勢行列を取得します。</para>
/// <para>Qumarionから値を取得する場合、加速度センサは、QUMARION本体グリップ内に設置されていっるため、胸を正面に向けた場合、25度傾いています。</para>
/// <para>この関数は、加速度センサ値にローパスフィルタ処理を施した後、25度の傾きを補正し、胸を正面に向けた状態からの回転角度を行列を取得することができます。</para>
/// </summary>
/// <param name="qumaHandle">対象のデバイス</param>
/// <param name="result">成功した場合、姿勢を表す行列が格納される</param>
/// <returns>処理が成功した場合OK、失敗の場合はそれ以外</returns>
public static QumaLowResponse TryGetAccelerometerPoseMatrix(QumaHandle qumaHandle, out Matrix4 result)
{
var matrixPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(float)) * 16);
var response = GetAccelerometerPoseMatrix(qumaHandle.Handle, matrixPtr);
if (response == QumaLowResponse.OK)
{
var matrixArray = new float[16];
Marshal.Copy(matrixPtr, matrixArray, 0, 16);
result = new Matrix4(matrixArray);
}
else
{
result = new Matrix4(new float[16]);
}
Marshal.FreeHGlobal(matrixPtr);
return response;
}
#endregion
}
/// <summary>更新処理のAPI</summary>
public static class Update
{
#region privateなDllImport
#region UpdateBuffer
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowUpdateBuffer@@YAHPAX@Z")]
private static extern QumaLowResponse UpdateBuffer86(IntPtr qumaHandle);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowUpdateBuffer@@YAHPEAX@Z")]
private static extern QumaLowResponse UpdateBuffer64(IntPtr qumaHandle);
private static QumaLowResponse UpdateBuffer(IntPtr qumaHandle)
=> Is64bit ? UpdateBuffer64(qumaHandle) : UpdateBuffer86(qumaHandle);
#endregion
#region UpdateQumaHandle
[DllImport(DllName86, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowUpdateQumaHandle@@YAHPAX@Z")]
private static extern QumaLowResponse UpdateQumaHandle86(IntPtr qumaHandle);
[DllImport(DllName64, CallingConvention = CallingConvention.Cdecl, EntryPoint = @"?QmLowUpdateQumaHandle@@YAHPEAX@Z")]
private static extern QumaLowResponse UpdateQumaHandle64(IntPtr qumaHandle);
private static QumaLowResponse UpdateQumaHandle(IntPtr qumaHandle)
=> Is64bit ? UpdateQumaHandle64(qumaHandle) : UpdateQumaHandle86(qumaHandle);
#endregion
#endregion
#region 公開ラッパー関数
/// <summary>
/// デバイスのセンサ情報を更新します。このメソッドは例外を投げません。
/// </summary>
/// <param name="qumaHandle">対象のデバイス。</param>