本文介绍了在UNITY3D中调用WISEGLOVE数据手套的方法。 通过该方法可以读取手套的传感器角度值和传感器原始值,可以根据需求执行进一步应用。本程序调用了WISEGLOVE SDK, 并对SDK的主要函数作了调用声明。
在UNITY3D中使用WISEGLOVE虚拟现实数据手套可分为三步:
1. 在Start ()中 初始化手套
2. 在Updata()中循环读取传感器数据(数值或者角度)
3. 关闭手套调用端口
// 声明:本范例程序适合WiseGlove数据手套,如需了解WiseGlove数据手套,请访问www.wiseglove.com
// 北京鑫天视景科技有限公司编制
// 2014/6/20
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
using System.Threading;
public class WiseGloveData_sample : MonoBehaviour {
//声明数据手套调用函数
// bool wgInit(); 自动初始化数据手套函数
[DllImport("WiseGloveU3D",EntryPoint = "wgInit")]
extern static int wgInit();
//bool wgInitManu(int comport); 指定端口的初始化函数
[DllImport("WiseGloveU3D",EntryPoint = "wgInitManu")]
extern static int wgInitManu(int comport);
//int wgGetGetNumOfSensor(); 获取手套的传感器的数量
[DllImport("WiseGloveU3D",EntryPoint = "wgGetGetNumOfSensor")]
extern static int wgGetGetNumOfSensor();
//void wgClose(); //关闭手套调用端口
[DllImport("WiseGloveU3D",EntryPoint = "wgClose")]
extern static int wgClose();
//bool wgGetData(unsigned short *data); //读取手套传感器值,该值在数组里按照sensor0, sensor1,..., sensor(n)的方式排列
[DllImport("WiseGloveU3D",EntryPoint = "wgGetData")]
extern static void wgGetData([MarshalAs(UnmanagedType.LPArray,SizeParamIndex=1)]int[] retData);
//bool wgGetScaledData(unsigned short *data);//读取手套传感器归一化值,该值在数组里按照sensor0, sensor1,..., sensor(n)的方式排列
[DllImport("WiseGloveU3D",EntryPoint = "wgGetScaledData")]
extern static void wgGetScaledData([MarshalAs(UnmanagedType.LPArray,SizeParamIndex=1)]int[] retData);
//bool wgGetAngle(float *data); //读取手套传感器角度值,该值在数组里按照sensor0, sensor1,..., sensor(n)的方式排列
[DllImport("WiseGloveU3D",EntryPoint = "wgGetAngle")]
extern static void wgGetAngle([MarshalAs(UnmanagedType.LPArray,SizeParamIndex=1)]float[] retAngle);
//int wgLoadCalib(char *filename);//加载标定数据, 如果需要人工干预标定的情况下
[DllImport("WiseGloveU3D",EntryPoint = "wgLoadCalib")]
extern static void wgLoadCalib([MarshalAs(UnmanagedType.LPArray,SizeParamIndex=1)]char[] filename);
//int wgSaveCalib(char *filename);//保存标定数据
[DllImport("WiseGloveU3D",EntryPoint = "wgSaveCalib")]
extern static void wgSaveCalib([MarshalAs(UnmanagedType.LPArray,SizeParamIndex=1)]char[] filename);
//void wgSetCalibMode(int mode); 设置标定模式是自动还是人工干预
[DllImport("WiseGloveU3D",EntryPoint = "wgSetCalibMode")]
extern static int wgSetCalibMode(int mode);
//void wgSetCalib(int index, unsigned short min, unsigned short max,float angle); 为指定传感器设置标定值
[DllImport("WiseGloveU3D",EntryPoint = "wgSetCalib")]
extern static int wgSetCalib(int index, ushort min, ushort max, float angle);
//void wgSetMin_adj(int index, float min_adj); //为指定传感器指定逻辑最小值
[DllImport("WiseGloveU3D",EntryPoint = "wgSetMin_adj")]
extern static int wgSetMin_adj(int index, float min_adj);
//void wgSetMax_adj(int index, float max_adj);//为指定传感器指定逻辑最大值
[DllImport("WiseGloveU3D",EntryPoint = "wgSetMax_adj")]
extern static int wgSetMax_adj(int index, float max_adj);
//void wgResetCalib(); 复位标定数据
[DllImport("WiseGloveU3D",EntryPoint = "wgResetCalib")]
extern static int wgResetCalib();
//声明外部变量,以便把手套角度和模型绑定
public Transform Thumb = null; //大拇指
public Transform Index = null; //食指
public Transform Middle = null; //中指
public Transform Ring = null; //无名指
public Transform Little = null; //小指
float[] ret_angle;
int openstate;
void Start ()
{
openstate=wgInit(); //自动扫描系统中的手套 并且初始化
//openstate=wgInitManu(comport); //确定手套端口的情况下,可以使用本函数指定端口,可以提高初始化效率
ret_angle=new float[14]; //存储传感器角度值,当然5传感器手套,只取数组前5个值即可,适合5 14 15 18 19传感器手套
Debug.Log("open state:"+ openstate.ToString());
}
void Update () {
if (openstate == 1) {//读取手套角度值
wgGetAngle (ret_angle); //获取角度值,保存到ret_angle数组里
//在三维模型中 让物体均绕X轴旋转
Thumb.localRotation = Quaternion.Euler (ret_angle [0], 0, 0);
Index.localRotation = Quaternion.Euler (ret_angle [1], 0, 0);
Middle.localRotation = Quaternion.Euler (ret_angle [2], 0, 0);
Ring.localRotation = Quaternion.Euler (ret_angle [3], 0, 0);
Little.localRotation = Quaternion.Euler (ret_angle [4], 0, 0);
}
//按下R键,开始重新标定
if (Input.GetKey (KeyCode.R)) {
wgResetCalib();
}
//如果前面标定好了, 按下C键则禁止自动标定,保持前面标定好的结果
if (Input.GetKey (KeyCode.C)) {
wgSetCalibMode(1); //禁止自动标定 //0 - 自动标定
}
if (Input.GetKey (KeyCode.Q)) {
Application.Quit(); //禁止自动标定 //0 - 自动标定
}
}
//显示各传感器的当前角度值
void OnGUI()
{
string s;
int offset = 20;
s = "WiseGlove demo for Unity3D, please visit www.wiseglove.com for more!";
GUI.Label(new Rect(200,offset,700,30+offset), s);
offset += 30;
s = "Press 'R' to recalib 'C' to manu calib, and 'Q' to exit program";
GUI.Label(new Rect(20,offset,500,30+offset), s);
offset += 30;
for (int i = 0; i < 5; i++)
{
int temp = (int)ret_angle[i];
s = "Sensor " + i.ToString() + " angle = " + temp.ToString();
GUI.Label(new Rect(10,offset,400,20+offset), s);
offset += 20;
}
int ges = CheckGloveStatus ();
s = "Gesture:" + ges.ToString();
GUI.Label(new Rect(10,offset,400,20+offset), s);
}
void OnDestroy () {
if (openstate == 1) { //关闭手套调用端口
wgClose ();
Debug.Log ("Glove is closed!");
}
else
Debug.Log ("Glove is NOT closed!");
}
//获取数据手套当前的手势,例如:0x1f-石头 0x17-剪子, 0x00-布, 0x1c-OK
int CheckGloveStatus()
{
int gesture = 0; //0x1f; // b1 1111
//大拇指第0位,。。。小指第4位
if (ret_angle [0] > 150 / 2)
gesture += 0x01; //
if (ret_angle [1] > 270 / 2)
gesture += 0x02; //
if (ret_angle [2] > 270 / 2)
gesture += 0x04; //
if (ret_angle [3] > 270 / 2)
gesture += 0x08; //
if (ret_angle [4] > 270 / 2)
gesture += 0x10; //
return gesture;
}
}