프로젝트

일반

사용자정보

통계
| 개정판:

t1 / TFDContents / Assets / KinectDemos / FaceTrackingDemo / Scripts / SetFaceTexture.cs @ 3

이력 | 보기 | 이력해설 | 다운로드 (6.95 KB)

1
using UnityEngine;
2
using System.Collections;
3

    
4
public class SetFaceTexture : MonoBehaviour 
5
{
6
	[Tooltip("Index of the player, tracked by this component. 0 means the 1st player, 1 - the 2nd one, 2 - the 3rd one, etc.")]
7
	public int playerIndex = 0;
8

    
9
	[Tooltip("Whether to use the face-rectangle provided by the FacetrackingManager, or not.")]
10
	public bool useTrackedFaceRect = false;
11

    
12
	[Tooltip("Width of the rectangle around the head joint, in meters.")]
13
	public float faceWidth = 0.3f;
14
	[Tooltip("Height of the rectangle around the head joint, in meters.")]
15
	public float faceHeight = 0.3f;
16

    
17
	[Tooltip("Game object renderer, used to display the face image as 2D texture.")]
18
	public Renderer targetObject;
19

    
20

    
21
	//private Renderer targetRenderer;
22
	private Rect faceRect;
23
	private Texture2D colorTex, faceTex;
24
	private KinectManager kinectManager;
25
	private FacetrackingManager faceManager;
26

    
27
	private BackgroundRemovalManager backManager;
28
	private RenderTexture foregroundTex = null;
29

    
30
	//private const int pixelAlignment = -2;  // must be negative power of 2
31

    
32
	/// <summary>
33
	/// Determines whether the face rectange and face texture are valid.
34
	/// </summary>
35
	/// <returns><c>true</c> if the face rectangle is valid; otherwise, <c>false</c>.</returns>
36
	public bool IsFaceRectValid()
37
	{
38
		return faceRect.width > 0 && faceRect.height > 0;
39
	}
40

    
41

    
42
	/// <summary>
43
	/// Gets the face rectangle, in pixels.
44
	/// </summary>
45
	/// <returns>The face rectangle.</returns>
46
	public Rect GetFaceRect()
47
	{
48
		return faceRect;
49
	}
50

    
51
	/// <summary>
52
	/// Gets the tracked face texture.
53
	/// </summary>
54
	/// <returns>The face texture.</returns>
55
	public Texture GetFaceTex()
56
	{
57
		return faceTex;
58
	}
59

    
60

    
61
	void Start () 
62
	{
63
		kinectManager = KinectManager.Instance;
64
		faceTex = new Texture2D(100, 100, TextureFormat.ARGB32, false);
65

    
66
		if (!targetObject) 
67
		{
68
			targetObject = GetComponent<Renderer>();
69
		}
70

    
71
		if(targetObject && targetObject.material)
72
		{
73
			targetObject.material.SetTextureScale("_MainTex", new Vector2(1, -1));
74
		}
75
	}
76
	
77
	void Update () 
78
	{
79
		if(faceManager == null)
80
		{
81
			faceManager = FacetrackingManager.Instance;
82
		}
83

    
84
		if(!kinectManager || !kinectManager.IsInitialized())
85
			return;
86
		if(!faceManager || !faceManager.IsFaceTrackingInitialized())
87
			return;
88

    
89
		long userId = kinectManager.GetUserIdByIndex(playerIndex);
90
		if (userId == 0) 
91
		{
92
			if(targetObject && targetObject.material && targetObject.material.mainTexture != null)
93
			{
94
				targetObject.material.mainTexture = null;
95
			}
96

    
97
			return;
98
		}
99

    
100
		if (!backManager) 
101
		{
102
			backManager = BackgroundRemovalManager.Instance;
103

    
104
			if (backManager) 
105
			{
106
				// re-initialize the texture
107
				colorTex = null;
108
			}
109
		}
110

    
111
		if (!foregroundTex && backManager && backManager.IsBackgroundRemovalInitialized()) 
112
		{
113
			// use foreground image
114
			foregroundTex = (RenderTexture)backManager.GetForegroundTex ();
115

    
116
//			if (!colorTex) 
117
//			{
118
//				colorTex = new Texture2D(kinectManager.GetColorImageWidth(), kinectManager.GetColorImageHeight(), TextureFormat.ARGB32, false);
119
//			}
120
//
121
//			try 
122
//			{
123
//				foregroundTex = (RenderTexture)backManager.GetForegroundTex ();
124
//				//KinectInterop.RenderTex2Tex2D (foregroundTex, ref colorTex);
125
//			} 
126
//			catch (System.Exception) 
127
//			{
128
//				colorTex = (Texture2D)backManager.GetForegroundTex ();
129
//			}
130
		}
131
		else 
132
		{
133
			// use color camera image
134
			if (!colorTex) 
135
			{
136
				colorTex = kinectManager.GetUsersClrTex();
137
			}
138
		}
139

    
140
		//faceRect = faceManager.GetFaceColorRect(userId);
141
		faceRect = GetHeadJointFaceRect(userId);
142

    
143
		if (faceRect.width > 0 && faceRect.height > 0) 
144
		{
145
			int faceX = (int)faceRect.x;
146
			int faceY = (int)faceRect.y;
147
			int faceW = (int)faceRect.width;
148
			int faceH = (int)faceRect.height;
149

    
150
			if(faceX < 0) faceX = 0;
151
			if(faceY < 0) faceY = 0;
152
			if((faceX + faceW) > colorTex.width) faceW = colorTex.width - faceX;
153
			if((faceY + faceH) > colorTex.height) faceH = colorTex.height - faceY;
154

    
155
			if(faceTex.width != faceW || faceTex.height != faceH)
156
			{
157
				faceTex.Resize(faceW, faceH);
158
			}
159

    
160
			if (foregroundTex) 
161
			{
162
				KinectInterop.RenderTex2Tex2D(foregroundTex, faceX, foregroundTex.height - faceY - faceH, faceW, faceH, ref faceTex);
163
			}
164
			else if(colorTex)
165
			{
166
				Color[] colorPixels = colorTex.GetPixels(faceX, faceY, faceW, faceH, 0);
167
				faceTex.SetPixels(colorPixels);
168
				faceTex.Apply();
169
			}
170

    
171
			if (targetObject && !targetObject.gameObject.activeSelf) 
172
			{
173
				targetObject.gameObject.SetActive(true);
174
			}
175

    
176
			if(targetObject && targetObject.material)
177
			{
178
				targetObject.material.mainTexture = faceTex;
179
			}
180

    
181
			// don't rotate the transform - mesh follows the head rotation
182
			if (targetObject.transform.rotation != Quaternion.identity) 
183
			{
184
				targetObject.transform.rotation = Quaternion.identity;
185
			}
186
		} 
187
		else 
188
		{
189
			if (targetObject && targetObject.gameObject.activeSelf) 
190
			{
191
				targetObject.gameObject.SetActive(false);
192
			}
193

    
194
			if(targetObject && targetObject.material && targetObject.material.mainTexture != null)
195
			{
196
				targetObject.material.mainTexture = null;
197
			}
198
		}
199
	}
200

    
201
	private Rect GetHeadJointFaceRect(long userId)
202
	{
203
		Rect faceJointRect = new Rect();
204

    
205
		if (useTrackedFaceRect && faceManager && 
206
			faceManager.IsFaceTrackingInitialized () && faceManager.IsTrackingFace (userId)) 
207
		{
208
			faceJointRect = faceManager.GetFaceColorRect(userId);
209
			return faceJointRect;
210
		}
211

    
212
		if(kinectManager.IsJointTracked(userId, (int)KinectInterop.JointType.Head))
213
		{
214
			Vector3 posHeadRaw = kinectManager.GetJointKinectPosition(userId, (int)KinectInterop.JointType.Head);
215
			
216
			if(posHeadRaw != Vector3.zero)
217
			{
218
				Vector2 posDepthHead = kinectManager.MapSpacePointToDepthCoords(posHeadRaw);
219
				ushort depthHead = kinectManager.GetDepthForPixel((int)posDepthHead.x, (int)posDepthHead.y);
220
				
221
				Vector3 sizeHalfFace = new Vector3(faceWidth / 2f, faceHeight / 2f, 0f);
222
				Vector3 posFaceRaw1 = posHeadRaw - sizeHalfFace;
223
				Vector3 posFaceRaw2 = posHeadRaw + sizeHalfFace;
224
				
225
				Vector2 posDepthFace1 = kinectManager.MapSpacePointToDepthCoords(posFaceRaw1);
226
				Vector2 posDepthFace2 = kinectManager.MapSpacePointToDepthCoords(posFaceRaw2);
227

    
228
				if(posDepthFace1 != Vector2.zero && posDepthFace2 != Vector2.zero && depthHead > 0)
229
				{
230
					Vector2 posColorFace1 = kinectManager.MapDepthPointToColorCoords(posDepthFace1, depthHead);
231
					Vector2 posColorFace2 = kinectManager.MapDepthPointToColorCoords(posDepthFace2, depthHead);
232
					
233
					if(!float.IsInfinity(posColorFace1.x) && !float.IsInfinity(posColorFace1.y) &&
234
					   !float.IsInfinity(posColorFace2.x) && !float.IsInfinity(posColorFace2.y))
235
					{
236
						faceJointRect.x = posColorFace1.x;
237
						faceJointRect.y = posColorFace2.y;
238
						faceJointRect.width = Mathf.Abs(posColorFace2.x - posColorFace1.x);
239
						faceJointRect.height = Mathf.Abs(posColorFace2.y - posColorFace1.y);
240
					}
241
				}
242
			}
243
		}
244

    
245
		return faceJointRect;
246
	}
247

    
248
}