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. [Oracle] - 性能优化工具(4) - AWRDD

    AWRDD是用于比較两个AWR快照,从而获得不同一时候期的性能. 运行例如以下语句获得AWRDD: @?/rdbms/admin/awrddrpt.sql 2025 23 2月 2014 07:12 ...

  2. WPF弹性模拟动画

    原文:WPF弹性模拟动画 我们此次将要制作模拟物理中的弹性现象的交互动画,我们让一个小球向鼠标点击位置移动,这个移动的轨迹不是简单的位移,而是根据胡克定律计算得出的. 胡克定律:F=-kd F代表弹性 ...

  3. 官网下载qt-opensource-windows-x86-mingw482_opengl-5.3.1.exe。封装好了Qt libraries、Qt Creator。只需要这一个可执行程序就好了。

    官网下载qt-opensource-windows-x86-mingw482_opengl-5.3.1.exe( http://qt-project.org/downloads).这个可执行程序已经为 ...

  4. POJ 1696 Space Ant(点积的应用)

    Space Ant 大意:有一仅仅蚂蚁,每次都仅仅向当前方向的左边走,问蚂蚁走遍全部的点的顺序输出.開始的点是纵坐标最小的那个点,開始的方向是開始点的x轴正方向. 思路:从開始点開始,每次找剩下的点中 ...

  5. FZUOJ Problem 2178 礼品配送

    Problem 2178 礼物分配 题目链接: Click Here~ Problem Description 在双胞胎兄弟Eric与R.W的生日会上,他们共收到了N个礼物,生日过后他们决定分配这N个 ...

  6. Android定位功能(二)

    在前文Android定位功能(一)中,已经大致介绍了一下在Android平台中,和定位功能相关的类,并举例获取了位置信息.但是前文是基于Criteria定制了一个标准,通过getBestProvide ...

  7. Outlook将收到邮件的附件保存在磁盘

    1. 新建一个宏 1)文件->选项->自定义功能区, 把主选项卡的 开发工具勾选上. 2)开发工具->宏,输入宏名,创建. 加入以下代码 Public Sub SaveAttach( ...

  8. 【夸QT在十五】ctkPluginFrameWork插件系统Windows编译器

    采用ctkPluginFramework作为一个插件系统开发框架确实有很多优点. 有些车站最近收到的一封信,每个人都想用ctkPluginFramework但我不知道如何建立,本教程对谈ctkPlug ...

  9. extjs的相关属性

    通用属性: labelSeparator:''//表示fieldLabel后不会显示冒号":" readOnly:true//仅仅读 focusCls: 'txtHalfInput ...

  10. Git使用总结-so easy

    一.Git的特性 Speed 速度(git是用c语言写的.一般都是提交到本地) Simple design Strong support for non-linear development (tho ...