孙陪你,了解它的权力--Kinect结合的发展Unity3D游戏应用开发
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游戏应用开发的更多相关文章
- 孙陪你,了解它的力量——unity3d流程暂停
干unity3dproject什么时候,有时需要对进程暂停一段时间. 有人建议使用yield return new WaitForSeconds(value);使用的方法如以下: IEnumerato ...
- Kinect for Windows V2和V1对照开发___深度数据获取并用OpenCV2.4.10显示
V1深度分辨率:320x240 V2深度分辨率:512x424 1. 打开深度图像帧的方式 对于V1: hr = m_PNuiSensor->NuiImageStreamOpen( NUI_I ...
- Kinect for Windows V2和V1对照开发___彩色数据获取并用OpenCV2.4.10显示
V1彩色分辨率:640x480 V2彩色分辨率:1920x1080 1,打开彩色图像帧的方式 对于V1: 使用NuiImageStreamOpen方法打开 hr = m_PNuiSensor-> ...
- Kinect一代学习(一):开发环境搭建
https://blog.csdn.net/hongbin_xu/article/details/80722749 我用的是kinect一代(Xbox 360)的所以选择了v1.x的SDK,如果是ki ...
- 使用HTML5开发Kinect体感游戏
一.简介 我们要做的是怎样一款游戏? 在前不久成都TGC2016展会上,我们开发了一款<火影忍者手游>的体感游戏,主要模拟手游章节<九尾袭来 >,用户化身四代,与九尾进行对决, ...
- Kinect for Windows SDK开发入门(一):开发环境配置
[译]Kinect for Windows SDK开发入门(一):开发环境配置 前几天无意中看到微软发布了Kinect for windows sensor,进去看了一下Kinect应用的例子,发现K ...
- Kinect开发学习笔记之(一)Kinect介绍和应用
Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
- kinect for windows - 初认识
kinect是微软开发的一种计算机输入设备,原来只是用于xbox,kinect负责捕捉用户的动作,让xbox游戏做出相应的反应.很快大家对此非常有兴趣,因此有些geek和组织为kinect开发了驱动和 ...
- Kinect的学习笔记发展(一)Kinect引进和应用
Kinect的学习笔记发展(一)Kinect引进和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
随机推荐
- SpringMVC @ResponseBody 415错误处理
在查看下面部分内容之前,请先检查你的请求蚕食是否正确,如果全部正确,请继续往下看 刚开始用SpringMVC, 页面要使用jQuery的ajax请求Controller. 但总是失败,主要表现为以下两 ...
- httpcomponents-client-ga(4.5)
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/ Chapter 1. Fundamentals Prev Next ...
- Maven--403权限问题解决方式(求解决)
我的程序配置方案例如以下(大牛们相信你们不仅仅是一个传说): 目的:实现maven公布项目到tomcat以下.用eclipse一步到位调试. pom.xml配置: <plugin> < ...
- PDF数据防扩散系统方案
在企业信息化过程中.大量的企业重要图纸和资料都是以电子文件的方式存在.为了避免内部关键数据的外泄,採取了多种方式:设计部门的门禁管制.防火墙.禁止计算机的USB接口等等. 可是泄密问题还是时有发生,原 ...
- mysql主键设置成auto_increment时,进行并发性能測试出现主键反复Duplicate entry 'xxx' for key 'PRIMARY'
mysql主键设置成auto_increment时,进行并发性能測试出现主键反复Duplicate entry 'xxx' for key 'PRIMARY' 解决方法: 在my.cnf的[mysql ...
- 【教你zencart仿站 文章1至6教训 高清1280x900视频下载】[支持手机端]
[教你zencart仿站 第1至6课 高清晰1280x900视频下载][支持移动端] 经过筹备, 我们的课件最终出来了- 我们 zencart联盟合伙人 项目推出的 在线yy同步演示zencart仿站 ...
- python学习笔记之六:更加抽象
Python被称为面向对象的语言,创建自己的对象是python非常核心的概念.这里会介绍如何创建对象,以及多态,封装,方法,特性,超类以及继承的概念. 一. 对象的魔力 面向对象程序设计中的术语 对象 ...
- java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory
Myeclipse 8.6使用tomcat7时间.执行javaweb如报告了以下错误项: java.lang.NoClassDefFoundError: org/apache/juli/logging ...
- poj1364(差分约束系统)
poj1364 设s[i] 表示a1 + a2 + ... + a(i-1)的和 给我们n个点,m条约束 如果是a b gt c 那么表示 s[a+b+1] - s[a] > c ...
- cocos2d-x笔记(十一)Lua发展飞机战争-5-
让飞机动
然后在飞机上已被添加到游戏,下一步是让它动起来.主要是为了应对触摸事件. 在C++通过重写ccTouchBegan().ccTouchMoved().ccTouchEnded()三个函数来响应触摸事件 ...