Unity HTC vive VR虚拟环境中,kinect的模拟

在物理实验室模块,为了体现虚拟现实的特性,充实功能,打算实现kinect在VR环境中的模拟。通过用户的手势,动作;得到一个返回值,用来触发某些事件。即模拟kinect的运作方式,处理图像中人体的运动手势,触发相应的事件。

通过手柄的位置的位移来触发事件:

声明SteamVR_TrackedObject对象,根据Steam vr sdk中拓展代码,构造手柄按钮事件。调用这个类中的手柄对象的方法,来实现左右手柄的监听功能,获取手柄位置等信息。

通过VRTK_DeviceFinder类,寻找有手柄,返回位置等信息,具体实现:

RightController = VRTK_DeviceFinder.GetControllerRightHand ();  
var device = SteamVR_Controller.Input((int)trackedObjec.index); 

在start函数里面赋值手柄的位置。

在update中,当此模块运行,开始检测时。当按下手柄的trigger记录一个手柄的位置,当trigger抬起时,记录一个手柄的位置。得到两个vector3属性的值。可以计算这两个值分别在x,y,z方向上的分量。

通过在三个坐标轴方向上的分量,可以判断此次手柄的移动轨迹是朝向什么方向的,通过不同的方向触发事件。

void Start () {
		RightController = VRTK_DeviceFinder.GetControllerRightHand ();
		preConPosition = ConPosition = RightController.transform.position;
	}
	
	// Update is called once per frame
	void Update () {
		
		var device = SteamVR_Controller.Input((int)trackedObjec.index);

		while(sk.isRun == true){
			if(device.GetTouchDown(SteamVR_Controller.ButtonMask.Trigger)){
				IsSelect = true;
				preConPosition = RightController.transform.position;
			}

			if(device.GetTouchUp(SteamVR_Controller.ButtonMask.Trigger) && IsSelect){
				ConPosition = RightController.transform.position;
				IsSelect = false;
			}

			gesture = Calculate (preConPosition,ConPosition);

			preConPosition = ConPosition = new Vector3(0,0,0);
		}
	}

	int Calculate(Vector3 preC,Vector3 C){
		float ResultX = C.x - preC.x;
		float ResultY = C.y - preC.y;
		float ResultZ = C.z - preC.z;

	}

但这种方式有很大的局限性,只能将位移看作是一条直线,没办法处理更复杂的手势情况。


下面提出的模拟方法是通过设置在指定位置一定数量的trigger,通过手柄的移动,触发各个trigger。此时我们可以得到手柄移动的路径,通过这种路径的形式来记录用户的手势运动,触发事件。

目前做了一个demo,还没在VR中实现。demo中,我设置了六个cube作为trigger,给予相应的标签。并赋予不同的编号。

sphere作为手柄,通过OnTriggerEnter的方式检测碰撞事件。

public List<int> paths = new List<int> ();

sphere的脚本上,定义了一个动态数组,用来存储路径。每当sphere与一个trigger触发时,记录此trigger的标号。当按下某一个键位,输出数组中存储的trigger路径。

我是通过将路径值转化为string类型,通过if语句与实现定义的事件的出发路径做判断,以达到触发事件的目的。

string numListToString(List<int> temp){
		string str = "";
		foreach (int n in temp)
			str += n + " ";
		return str;
	}

此种方式,可以比较灵活的设置trigger的位置,根据精度设置数量;同时在交互的过程中,可以记录更复杂的路径信息,做更多的手势。

void Update () {
		if(Input.GetKeyDown(KeyCode.Space)){
			string path1 = numListToString (paths);
			Debug.Log (path1);
			int kind = compare (path1);
			if(kind == 1){
				Debug.Log ("触发事件1");
			}
			reset (paths);
		}
	}

猜你喜欢

转载自blog.csdn.net/qq_34272906/article/details/80302931