프로젝트

일반

사용자정보

통계
| 개정판:

t1 / TFDContents / Assets / KinectDemos / VariousDemos / Scripts / SimpleHolographicCamera.cs @ 3

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

1
using UnityEngine;
2
using System;
3

    
4

    
5
/// <summary>
6
/// Script that emulates a 3D holographic display based on the viewer position
7
/// by Davi Loots (Twitter: @davloots), Start() & Update()-functions added by Rumen Filkov (Twitter: @roumenf)
8
/// Usage:
9
/// - Attach to a camera.
10
/// - Update the HeadPosition each frame either in this or in an external script based on some form of headtracking
11
/// - For best effect - and if available - use a stereoscopic display and calculate the head 
12
///   position twice by simply offsetting the HeadPosition .03 to the left and to the right for
13
///   each of the views.
14
/// </summary>
15
class SimpleHolographicCamera : MonoBehaviour
16
{
17
	[Tooltip("Index of the player, tracked by this component. 0 means the 1st player, 1 - the 2nd one, 2 - the 3rd one, etc.")]
18
	public int playerIndex = 0;
19

    
20
	//[Tooltip("How high above the ground is the center of the display, in meters.")]
21
	//public float ScreenCenterY = 0.5f;
22

    
23
	[Tooltip("The position of display center, in Kinect world coordinates, in meters.")]
24
	public Vector3 screenCenterPos = new Vector3(0f, 1f, 0f);
25

    
26
	[Tooltip("Width of the display in meters.")]
27
	public float screenWidth = 1.6f; // 0.88f;
28

    
29
	[Tooltip("Height of the display in meters.")]
30
	public float screenHeight = 0.9f; // 0.50f;
31

    
32
	[Tooltip("Maximum distance from the user to the display wall, in meters.")]
33
	public float maxUserDistance = 3f;
34

    
35
	[Tooltip("GUI-Text to display status messages.")]
36
	public GUIText statusText = null;
37

    
38
	private float left = -0.2F;
39
	private float right = 0.2F;
40
	private float bottom = -0.2F;
41
	private float top = 0.2F;
42

    
43
	private KinectManager kinectManager;
44

    
45
	private Vector3 jointHeadPos;
46
	private Vector3 headRelPosition;
47
	private bool headPosValid = false;
48

    
49
	private Vector3 initialCamPos = Vector3.zero;
50
	private Quaternion initialCamRot = Quaternion.identity;
51
	private Matrix4x4 initialCamPM = Matrix4x4.identity;
52
	private Vector3 initialRelPos = Vector3.zero;
53

    
54

    
55
	void Start()
56
	{
57
		kinectManager = KinectManager.Instance;
58
		//screenCenterPos = new Vector3 (0f, ScreenCenterY, 0f);
59

    
60
		Camera cam = GetComponent<Camera>();
61
		if (cam) 
62
		{
63
			initialCamPos = cam.transform.position;
64
			initialCamRot = cam.transform.rotation;
65
			initialCamPM = cam.projectionMatrix;
66
		}
67
	}
68

    
69
	void Update()
70
	{
71
		headPosValid = false;
72

    
73
		if (kinectManager && kinectManager.IsInitialized()) 
74
		{
75
			long userId = kinectManager.GetUserIdByIndex(playerIndex);
76

    
77
			if (kinectManager.IsUserTracked (userId) && kinectManager.IsJointTracked (userId, (int)KinectInterop.JointType.Head)) 
78
			{
79
				jointHeadPos = kinectManager.GetJointPosition (userId, (int)KinectInterop.JointType.Head);
80
				headRelPosition = jointHeadPos - screenCenterPos;
81
				headPosValid = true;
82

    
83
				if (initialRelPos == Vector3.zero) 
84
				{
85
					initialRelPos = headRelPosition;
86
				}
87

    
88
				if (statusText) 
89
				{
90
					string sStatusMsg = string.Format ("Head position: {0}\nRelative to screen: {1}", jointHeadPos, headRelPosition);
91
					statusText.text = sStatusMsg;
92
				}
93
			}
94
			else 
95
			{
96
				initialRelPos = Vector3.zero;
97
			}
98
		}
99

    
100
	}
101

    
102

    
103
    /// <summary>
104
    /// Updates the projection matrix and camera position to get the correct anamorph perspective
105
    /// </summary>
106
    void LateUpdate()
107
    {
108
		Camera cam = GetComponent<Camera>();
109

    
110
		if (cam) 
111
		{
112
			if (headPosValid) 
113
			{
114
				// set off-center projection
115
				left = cam.nearClipPlane * (-screenWidth / 2 - headRelPosition.x) / initialRelPos.z;
116
				right = cam.nearClipPlane * (screenWidth / 2 - headRelPosition.x) / initialRelPos.z;
117

    
118
				bottom = cam.nearClipPlane * (-screenHeight / 2 - headRelPosition.y) / initialRelPos.z;
119
				top = cam.nearClipPlane * (screenHeight / 2 - headRelPosition.y) / initialRelPos.z;
120

    
121
				cam.transform.position = new Vector3(headRelPosition.x, headRelPosition.y, -headRelPosition.z);
122
				cam.transform.LookAt(new Vector3(headRelPosition.x, headRelPosition.y, 0));
123

    
124
				Matrix4x4 m = PerspectiveOffCenter(left, right, bottom, top, cam.nearClipPlane, cam.farClipPlane);
125
				cam.projectionMatrix = m;
126
			}
127
			else
128
			{
129
				// set the initial camera settings
130
				cam.transform.position = initialCamPos;
131
				cam.transform.rotation = initialCamRot;
132
				cam.projectionMatrix = initialCamPM;
133
			}
134
		}
135
    }
136

    
137
    /// <summary>
138
    /// Calculates the camera projection matrix
139
    /// </summary>
140
    /// <returns>The off center matrix.</returns>
141
    /// <param name="left">Left.</param>
142
    /// <param name="right">Right.</param>
143
    /// <param name="bottom">Bottom.</param>
144
    /// <param name="top">Top.</param>
145
    /// <param name="near">Near.</param>
146
    /// <param name="far">Far.</param>
147
    private Matrix4x4 PerspectiveOffCenter(float left, float right, float bottom, float top, float near, float far)
148
    {
149
        float x = 2.0F * near / (right - left);
150
        float y = 2.0F * near / (top - bottom);
151
        float a = (right + left) / (right - left);
152
        float b = (top + bottom) / (top - bottom);
153
        float c = -(far + near) / (far - near);
154
        float d = -(2.0F * far * near) / (far - near);
155
        float e = -1.0F;
156

    
157
        Matrix4x4 m = new Matrix4x4();
158
        m[0, 0] = x;
159
        m[0, 1] = 0;
160
        m[0, 2] = a;
161
        m[0, 3] = 0;
162
        m[1, 0] = 0;
163
        m[1, 1] = y;
164
        m[1, 2] = b;
165
        m[1, 3] = 0;
166
        m[2, 0] = 0;
167
        m[2, 1] = 0;
168
        m[2, 2] = c;
169
        m[2, 3] = d;
170
        m[3, 0] = 0;
171
        m[3, 1] = 0;
172
        m[3, 2] = e;
173
        m[3, 3] = 0;
174

    
175
        return m;
176
    }
177

    
178
}
179