unity3d正在使用kinect三维模型数据控制(它切成脚本)

博主在做项目时须要利用kinect数据控制三维模型中人物的动作。但不是实时控制,而是利用之前获得的骨骼数据,直接控制。无需再利用脚本打开kinect设备。

在博主转载的一篇博客中有一个unity3d的project包,特别适合。实现unity与kinect的交互。

http://blog.csdn.net/a350203223/article/details/22040119

该project中有多个脚本,之间联系复杂。本人使用此project中的脚本。经过分析。去除了当中冗余的脚本,能够实现直接传入数据就可以控制三维模型动作,不须要实时打开kinect,能够直接读取之前存录的骨骼点数据。

Kinect

KinectModelControllerV2 - 你须要将这个脚本拖放到你想要应用Kinect控制的模型上。为了让模型可以跟上人的节奏。你须要将模型上控制模型动作的关键骨骼拖放到这个脚本暴漏的合适的变量中 ,也就是将模型中的骨骼与kincet识别到的人的骨骼绑定起来。

另外这个脚本暴漏的变量中。另一个变量时标识模型是受哪个玩家控制。

KinectPointController - 你也须要将这个脚本拖放到场景中的游戏物体上。

可是这个游戏物体不是模型,而是由一系列分别代表头部、肩部、手等人体部位的点组成。你须要将游戏物体中的这些关键点都拖放到这个脚本暴漏的外部变量中。

这样就能够使用Kinect控制游戏物体了,游戏物体是由一系列的点组成的人体。

DisplayDepth - 这个脚本得到深度图像。

DisplayColor - 这个脚本得到RGB图像。

KinectRecorder - 这个脚本用于记录你的动作。并为Kinect模拟器(emulator)产生回放文件。

KinectEmulator - 这个脚本模拟Kinect设备.和KinectRecorder产生的回放文件一起工作。

KinectSensor - 这个脚本从Kinect设备中取得数据。须要替换这个文件使用特用版本号的SDK.

DeviceOrEmulator - 这个脚本设置使用Kinect物理设备还是Kinect模拟设备.

SkeletonWrapper - 这个脚本抓取骨骼数据.

DepthWrapper - 这个脚本抓取深度图像数据.

KinectInterop - 这个脚本从Microsoft Kinect SDK中抓取数据.

Recordings/playbackDefault - 这是为Kinect模拟设备准备的默认的回放文件.

可是我仅仅想找到控制模型的机制,传入数据直接控制模型。于是我分析了全部的脚本。找到当中的 Matrix4x4矩阵变换的关键,kinect坐标转化为世界坐标。删减了冗余的脚本。

整合到KinectModelControllerV2一个脚本中。

/*

 * KinectModelController.cs - Handles rotating the bones of a model to match 

 * rotations derived from the bone positions given by the kinect

 * 

 * Developed by Peter Kinney -- 6/30/2011

 * 

 */





using UnityEngine;

using System;

using System.Collections;





public class KinectModelControllerV2 : MonoBehaviour {



//Assignments for a bitmask to control which bones to look at and which to ignore

public enum BoneMask

{

None = 0x0,

//EMPTY = 0x1,

Spine = 0x2,

Shoulder_Center = 0x4,

Head = 0x8,

Shoulder_Left = 0x10,

Elbow_Left = 0x20,

Wrist_Left = 0x40,

Hand_Left = 0x80,

Shoulder_Right = 0x100,

Elbow_Right = 0x200,

Wrist_Right = 0x400,

Hand_Right = 0x800,

Hips = 0x1000,

Knee_Left = 0x2000,

Ankle_Left = 0x4000,

Foot_Left = 0x8000,

//EMPTY = 0x10000,

Knee_Right = 0x20000,

Ankle_Right = 0x40000,

Foot_Right = 0x80000,

All = 0xEFFFE,

Torso = 0x1000000 | Spine | Shoulder_Center | Head, //the leading bit is used to force the ordering in the editor

Left_Arm = 0x1000000 | Shoulder_Left | Elbow_Left | Wrist_Left | Hand_Left,

Right_Arm = 0x1000000 |  Shoulder_Right | Elbow_Right | Wrist_Right | Hand_Right,

Left_Leg = 0x1000000 | Hips | Knee_Left | Ankle_Left | Foot_Left,

Right_Leg = 0x1000000 | Hips | Knee_Right | Ankle_Right | Foot_Right,

R_Arm_Chest = Right_Arm | Spine,

No_Feet = All & ~(Foot_Left | Foot_Right),

Upper_Body = Torso | Left_Arm | Right_Arm

}







public GameObject Hip_Center;

public GameObject Spine;

public GameObject Shoulder_Center;

public GameObject Head;

public GameObject Collar_Left;

public GameObject Shoulder_Left;

public GameObject Elbow_Left;

public GameObject Wrist_Left;

public GameObject Hand_Left;

public GameObject Fingers_Left; //unused

public GameObject Collar_Right;

public GameObject Shoulder_Right;

public GameObject Elbow_Right;

public GameObject Wrist_Right;

public GameObject Hand_Right;

public GameObject Fingers_Right; //unused

public GameObject Hip_Override;

public GameObject Hip_Left;

public GameObject Knee_Left;

public GameObject Ankle_Left;

public GameObject Foot_Left;

public GameObject Hip_Right;

public GameObject Knee_Right;

public GameObject Ankle_Right;

public GameObject Foot_Right;



public int player;

public BoneMask Mask = BoneMask.All;

public bool animated;

public float blendWeight = 1;



private GameObject[] _bones; //internal handle for the bones of the model

private uint _nullMask = 0x0;



private Quaternion[] _baseRotation; //starting orientation of the joints

private Vector3[] _boneDir; //in the bone's local space, the direction of the bones

private Vector3[] _boneUp; //in the bone's local space, the up vector of the bone

private Vector3 _hipRight; //right vector of the hips

private Vector3 _chestRight; //right vectory of the chest





[HideInInspector]

public Vector3[,] bonePos;



private float[]   stion=new float[80] {0.2f,-0.6f,1.7f,1.0f,-0.1f,-0.2f,1.9f,1.0f,-0.2f,0.2f,2.0f,1.0f,-0.3f, 0.4f, 2.0f, 1.0f,-0.3f, 0.1f, 2.1f, 1.0f,

-0.3f, -0.2f, 2.0f, 1.0f,-0.2f, -0.3f, 1.8f, 1.0f,-0.3f, -0.3f, 1.7f, 1.0f,-0.1f, 0.1f, 1.9f, 1.0f,

-0.1f, 0.0f, 1.6f, 1.0f,-0.3f, 0.0f, 1.5f, 1.0f,-0.4f, 0.0f, 1.5f, 1.0f,-0.2f, -0.3f, 1.8f, 1.0f,-0.3f, -0.6f, 1.9f, 1.0f,

-0.4f, -0.8f, 2.1f, 1.0f,-0.4f, -0.8f, 2.1f, 1.0f,-0.1f, -0.3f, 1.9f, 1.0f,-0.2f, -0.4f, 1.5f, 1.0f,0.1f, -0.6f, 1.7f, 1.0f

,0.0f, -0.6f, 1.7f, 1.0f};//手动加载的20个骨骼点的数据,以后能够需改传入数据

private Vector4 dfds; 

private Matrix4x4 kinectToWorld  ;

// Use this for initialization

void Start () {

//store bones in a list for easier access, everything except Hip_Center will be one

//higher than the corresponding Kinect.NuiSkeletonPositionIndex (because of the hip_override)

_bones = new GameObject[25] {

null, Hip_Center, Spine, Shoulder_Center,

Collar_Left, Shoulder_Left, Elbow_Left, Wrist_Left,

Collar_Right, Shoulder_Right, Elbow_Right, Wrist_Right,

Hip_Override, Hip_Left, Knee_Left, Ankle_Left,

null, Hip_Right, Knee_Right, Ankle_Right,

//extra joints to determine the direction of some bones

Head, Hand_Left, Hand_Right, Foot_Left, Foot_Right};



//determine which bones are not available

for(int ii = 0; ii < _bones.Length; ii++)

{

if(_bones[ii] == null)

{

_nullMask |= (uint)(1 << ii);

}

}



//store the base rotations and bone directions (in bone-local space)

_baseRotation = new Quaternion[20];

_boneDir = new Vector3[20];



//first save the special rotations for the hip and spine

_hipRight = Hip_Right.transform.position - Hip_Left.transform.position;

_hipRight = Hip_Override.transform.InverseTransformDirection(_hipRight);



_chestRight = Shoulder_Right.transform.position - Shoulder_Left.transform.position;

_chestRight = Spine.transform.InverseTransformDirection(_chestRight);



//get direction of all other bones

for( int ii = 0; ii < 20; ii++)

{

if((_nullMask & (uint)(1 << ii)) <= 0)

{

//save initial rotation

_baseRotation[ii] = _bones[ii].transform.localRotation;



//if the bone is the end of a limb, get direction from this bone to one of the extras (hand or foot).

if(ii % 4 == 3 && ((_nullMask & (uint)(1 << (ii/4) + 20)) <= 0))

{

_boneDir[ii] = _bones[(ii/4) + 20].transform.position - _bones[ii].transform.position;

}

//if the bone is the hip_override (at boneindex Hip_Left, get direction from average of left and right hips

else if(ii == 12)

{

_boneDir[ii] = ((Hip_Right.transform.position + Hip_Left.transform.position) / 2F) - Hip_Override.transform.position;

}

//otherwise, get the vector from this bone to the next.

else if((_nullMask & (uint)(1 << ii+1)) <= 0)

{

_boneDir[ii] = _bones[ii+1].transform.position - _bones[ii].transform.position;

}

else

{

continue;

}

//Since the spine of the kinect data is ~40 degrees back from the hip,

//check what angle the spine is at and rotate the saved direction back to match the data

if(ii == 1)

{

float angle = Vector3.Angle(transform.up,_boneDir[ii]);

_boneDir[ii] = Quaternion.AngleAxis(-40 + angle,transform.right) * _boneDir[ii];

}

//transform the direction into local space.

_boneDir[ii] = _bones[ii].transform.InverseTransformDirection(_boneDir[ii]);

}

}

//make _chestRight orthogonal to the direction of the spine.

_chestRight -= Vector3.Project(_chestRight, _boneDir[1]);

//make _hipRight orthogonal to the direction of the hip override

Vector3.OrthoNormalize(ref _boneDir[12],ref _hipRight);





bonePos = new Vector3[2,20];

kinectToWorld = Matrix4x4.zero;

kinectToWorld[0,0] = 1;

kinectToWorld[1,1] = 1;

kinectToWorld[1,3] = 1;

kinectToWorld [2, 2] = -1;

kinectToWorld [2, 3] = 2;

kinectToWorld [3, 3] = 1;

}



void Update () {

for (int bone = 0; bone < 20; bone++)

{

dfds = new Vector4 (stion[bone*4],stion[bone*4+1],stion[bone*4+2],stion[bone*4+3]);

bonePos[0,bone] = kinectToWorld.MultiplyPoint3x4(dfds);

}

//update the data from the kinect if necessary

//if(sw.pollSkeleton()){

for( int ii = 0; ii < 20; ii++)

{

if( ((uint)Mask & (uint)(1 << ii) ) > 0 && (_nullMask & (uint)(1 << ii)) <= 0 )

{

RotateJoint(ii);

}

// }

}

}



void RotateJoint(int bone) {

//if blendWeight is 0 there is no need to compute the rotations

if( blendWeight <= 0 ){ return; }

//if the model is not animated, reset rotations to fix twisted joints

if(!animated){_bones[bone].transform.localRotation = _baseRotation[bone];}

Vector3 dir = _boneDir[bone];

Vector3 target;



//if bone % 4 == 0 then it is either an outside shoulder or the hip override

if(bone % 4 == 0)

{

if(bone == 12)

{

target = ((bonePos[player,12] + bonePos[player,16]) / 2F) - bonePos[player,0];

}

else

{

//target = vector from shoulder_center to bone

target = bonePos[player,bone] - bonePos[player,2];

}

}

else

{

//target = vector from previous bone to bone

target = bonePos[player,bone] - bonePos[player,bone-1];

}

//transform it into bone-local space (independant of the transform of the controller)

target = transform.TransformDirection(target);

target = _bones[bone].transform.InverseTransformDirection(target);

//create a rotation that rotates dir into target

Quaternion quat = Quaternion.FromToRotation(dir,target);

//if bone is the spine, add in the rotation along the spine

if(bone == 12)

{

//rotate the chest so that it faces forward (determined by the shoulders)

dir = _chestRight;

target = bonePos[player,4] - bonePos[player,8];



target = transform.TransformDirection(target);

target = _bones[bone].transform.InverseTransformDirection(target);

target -= Vector3.Project(target,_boneDir[bone]);//Projects a vector onto another vector.



quat *= Quaternion.FromToRotation(dir,target);

//Creates a rotation which rotates from fromDirection to toDirection.



}

//if bone is the hip override, add in the rotation along the hips

else if(bone == 12)

{

//rotate the hips so they face forward (determined by the hips)

dir = _hipRight;

target = bonePos[player,16] - bonePos[player,12];



target = transform.TransformDirection(target);

target = _bones[bone].transform.InverseTransformDirection(target);

target -= Vector3.Project(target,_boneDir[bone]);



quat *= Quaternion.FromToRotation(dir,target);

}



//reduce the effect of the rotation using the blend parameter

quat = Quaternion.Lerp(Quaternion.identity, quat, blendWeight);

//apply the rotation to the local rotation of the bone

_bones[bone].transform.localRotation = _bones[bone].transform.localRotation  * quat;

return;

}

}



脚本Gameobject与骨骼关节相应









版权声明:本文博客原创文章,博客,未经同意,不得转载。

孙陪你,了解它的权力--Kinect结合的发展Unity3D游戏应用开发的更多相关文章

  1. 孙陪你,了解它的力量——unity3d流程暂停

    干unity3dproject什么时候,有时需要对进程暂停一段时间. 有人建议使用yield return new WaitForSeconds(value);使用的方法如以下: IEnumerato ...

  2. Kinect for Windows V2和V1对照开发___深度数据获取并用OpenCV2.4.10显示

    V1深度分辨率:320x240 V2深度分辨率:512x424 1.  打开深度图像帧的方式 对于V1: hr = m_PNuiSensor->NuiImageStreamOpen( NUI_I ...

  3. Kinect for Windows V2和V1对照开发___彩色数据获取并用OpenCV2.4.10显示

    V1彩色分辨率:640x480 V2彩色分辨率:1920x1080 1,打开彩色图像帧的方式 对于V1: 使用NuiImageStreamOpen方法打开 hr = m_PNuiSensor-> ...

  4. Kinect一代学习(一):开发环境搭建

    https://blog.csdn.net/hongbin_xu/article/details/80722749 我用的是kinect一代(Xbox 360)的所以选择了v1.x的SDK,如果是ki ...

  5. 使用HTML5开发Kinect体感游戏

    一.简介 我们要做的是怎样一款游戏? 在前不久成都TGC2016展会上,我们开发了一款<火影忍者手游>的体感游戏,主要模拟手游章节<九尾袭来 >,用户化身四代,与九尾进行对决, ...

  6. Kinect for Windows SDK开发入门(一):开发环境配置

    [译]Kinect for Windows SDK开发入门(一):开发环境配置 前几天无意中看到微软发布了Kinect for windows sensor,进去看了一下Kinect应用的例子,发现K ...

  7. Kinect开发学习笔记之(一)Kinect介绍和应用

    Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...

  8. kinect for windows - 初认识

    kinect是微软开发的一种计算机输入设备,原来只是用于xbox,kinect负责捕捉用户的动作,让xbox游戏做出相应的反应.很快大家对此非常有兴趣,因此有些geek和组织为kinect开发了驱动和 ...

  9. Kinect的学习笔记发展(一)Kinect引进和应用

    Kinect的学习笔记发展(一)Kinect引进和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...

随机推荐

  1. Android判断应用程序从后台回到前台

    MainActivity如下: package cc.testbackgroundtofront; import java.util.List; import android.app.Activity ...

  2. Knockout应用开发指南 第八章:简单应用举例(2)

    原文:Knockout应用开发指南 第八章:简单应用举例(2) 5   Control types 这个例子,对view model没有什么特殊的展示,只是展示如何绑定到各种元素上(例如,select ...

  3. pro-engineer&UG

    Pro/Engineer操作软件是美国参数技术公司(PTC)旗下的CAD/CAM/CAE一体化的三维软件.Pro/Engineer软件以参数化著称,是参数化技术的最早应用者,在目前的三维造型软件领域中 ...

  4. 查询oracle表字段信息

    表字段的信息咱们可以称之为元数据,今天有人问怎么把表字段的信息导出来,说实话我还不会用plsql develper把表的结构导出来,像下图所示: 在写数据库设计说明书的时候,想要把这个表格拷贝出来,这 ...

  5. mysql替换字段里数据内容部分字符串(亦可用于增加字段中的内容)

    mysql替换表的字段里面内容,如例子: mysql> select host,user from user  where user='testuser'; +----------------- ...

  6. vim ---- 自己主动的按钮indent该命令

    当使用vim一段代码的副本到一个程序时,有,经常indent会有一些问题. . 下面的这个强大的命令,使您可以一键码具有很好的格式. gg=G 样品:         

  7. UVA 11427 - Expect the Expected(概率递归预期)

    UVA 11427 - Expect the Expected 题目链接 题意:玩一个游戏.赢的概率p,一个晚上能玩n盘,假设n盘都没赢到总赢的盘数比例大于等于p.以后都不再玩了,假设有到p就结束 思 ...

  8. Apache Curator获得真正的

    Apache Curator获得真正的 Curator它是Netflix一家公司来源Zookeeper顾客,与Zookeeper相比于提供本地客户端,Curator的抽象层次更高,简化了Zookeep ...

  9. MQTT学习笔记——Yeelink MQTT维修 采用mqtt.js和paho-mqtt

    0 前言     2014年8月yeelink推出基于MQTT协议的开关类型设备控制API.相比于基于HTTP RESTful的轮训方式,通过订阅相关主题消息,能够远程控制类应用实时性更好. 本文使用 ...

  10. 802.11(wifi)的MAC层功能

    MAC层是802.11的主要功能部分.上层应用通过调用MAC层提供的接口原语调用MAC层的功能. MAC一共向上提供了2大类接口原语,共30种.数据(1)和管理(29).数据部分就是提供普通数据包的收 ...