using System;
using System.Linq;
using Microsoft.Kinect;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace MFTGuide.Screens
{
class MainMenuScreen : GameScreen
{
Texture2D t_logo;
Vector2 v_logo;
Vector2Converter mVector = new Vector2Converter();
ContentManager content;
/// <summary>
/// 손을 후두부로
/// </summary>
Texture2DButton bt_0;
Vector2 v_bt_0 = new Vector2(393.5f, 326.0f);
/// <summary>
/// 상지 측방 거상
/// </summary>
Texture2DButton bt_1;
Vector2 v_bt_1 = new Vector2(394.0f, 400.0f);
/// <summary>
/// 손을 후두부로
/// </summary>
Texture2DButton bt_2;
Vector2 v_bt_2 = new Vector2(400.0f, 473.0f);
/// <summary>
/// 잡기
/// </summary>
Texture2DButton bt_3;
Vector2 v_bt_3 = new Vector2(308.0f, 547.0f);
// -------------------
KinectSensor kinectSensor;
Vector2 handPosition = new Vector2();
string connectedStatus = "Not connected";
Texture2D hand;
public MainMenuScreen()
{
TransitionOnTime = TimeSpan.FromSeconds(1.5);
TransitionOffTime = TimeSpan.FromSeconds(0.5);
// 센서에 내용이 변경될 때 호출되는 이벤트를 추가한다.
KinectSensor.KinectSensors.StatusChanged += new EventHandler<StatusChangedEventArgs>(KinectSensors_StatusChanged);
DiscoverKinectSensor();
}
// ---------------------------------------------------------------
/// <summary>
/// 키넥트 센서 상태가 변경될 때 호출한다.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void KinectSensors_StatusChanged(object sender, StatusChangedEventArgs e)
{
if (this.kinectSensor == e.Sensor)
{
// 키넥트가 연결되어 있지 않거나, 파워가 들어와 있지 않을경우
if (e.Status == KinectStatus.Disconnected ||
e.Status == KinectStatus.NotPowered)
{
this.kinectSensor = null;
this.DiscoverKinectSensor();
}
}
}
/// <summary>
/// 키넥트 센서를 찾다.
/// </summary>
private void DiscoverKinectSensor()
{
// 키넥트 센서 연결확인
foreach (KinectSensor sensor in KinectSensor.KinectSensors)
{
// 키넥트 센서가 연결되어있으면
if (sensor.Status == KinectStatus.Connected)
{
// Found one, set our sensor to this
// 키넥트 센서가 연결되어있으면, 키넥트 센서 변수는 센서를 참조한다.
kinectSensor = sensor;
break;
}
}
// foreach 문에서 키넥트를 센서를 찾지만 없을 경우
if (this.kinectSensor == null)
{
connectedStatus = "Found none Kinect Sensors connected to USB";
return;
}
// 키넥트 센서에 상태를 "kinectSensor.Status"를 사용해서 확인한다.
switch (kinectSensor.Status)
{
case KinectStatus.Connected:
{
// 키넥트 센서가 연결되어 있음
connectedStatus = "Status: Connected";
break;
}
case KinectStatus.Disconnected:
{
// 키넥트 센서가 연결 끊김
connectedStatus = "Status: Disconnected";
break;
}
case KinectStatus.NotPowered:
{
// 키넥트 센서가 전원이 안들어와 있음
connectedStatus = "Status: Connect the power";
break;
}
default:
{
// 키넥트 센서가 알수 없는 애러가 발생함.
connectedStatus = "Status: Error";
break;
}
}
// 정상적으로 연결되어 있다면, 키넥트를 설정 및 초기화한다.
if (kinectSensor.Status == KinectStatus.Connected)
{
InitializeKinect();
}
}
/// <summary>
/// 키넥트 초기 설정
/// </summary>
/// <returns></returns>
private bool InitializeKinect()
{
#region 키넥트 컬러 스트림 초기 설정
// 키넥트 센서 컬러 처리 : 컬러 포맷을 ColorImageFormat 로 사용 한다.
// 윈도우 키넥트에서는 640x480 / 1280x 960 해상도와 FPS을 지원한다.
kinectSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
// 키넥트 센서 프레임 레디는 키넥트가 준비가 완료될 시, 호출되는 함수를 등록한다.
kinectSensor.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(kinectSensor_ColorFrameReady);
#endregion
#region 키넥트 뼈대 스트림 초기 설정
// 키넥트 센서 뼈대 스트림을 활성화한다.
// 키넥트가 사람의 위치를 따라가다(Track)하다 잘못됭 경우(이러한 경우를 SDK내에서 jitter이라고 한다.)를 막기 위해
// TransformSmoothParameters를 추가한다.
// TransformSmoothParameters 은 좀더 부드럽게 관절을 연결하기 위해 셋팅하는 방법.
kinectSensor.SkeletonStream.Enable(new TransformSmoothParameters()
{
// 다듬는다.
Smoothing = 0.5f,
// 교정한다.
Correction = 0.5f,
// 예측한다.
Prediction = 0.5f,
// 이상(Jitter) 반경
JitterRadius = 0.05f,
// 최대 탈선 반경
MaxDeviationRadius = 0.04f
});
// 키넥트 센서 프레임 레디는 키넥트가 준비가 완료될 시, 호출되는 함수를 등록한다.
kinectSensor.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(kinectSensor_SkeletonFrameReady);
#endregion
#region 키넥트 시작
try
{
// 키넥트 시작
kinectSensor.Start();
}
catch
{
connectedStatus = "Unable to start the Kinect Sensor";
return false;
}
#endregion
return true;
}
void kinectSensor_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
// skeletonFrame 는 e.OpenSkeletonFrame() 를 사용한다.
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
//skeletonFrame 이 정상이라면
if (skeletonFrame != null)
{
//int skeletonSlot = 0;
//skeletonData 는 스켈래톤 배열이며, 스캘래톤 프레임 길이 만큼의 배열로해서 생성한다.
Skeleton[] skeletonData = new Skeleton[skeletonFrame.SkeletonArrayLength];
// 그리고 스캘래톤데이터는 스켈레톤 프레임에 데이터를 카피한다.
skeletonFrame.CopySkeletonDataTo(skeletonData);
// 이부분은 잘모르겠다..
// LINQ
// 플레이어 스켈레톤은 (특정 데이터만 조회한다..) 시퀀스의 첫 번째 요소를 반환하거나 요소가 없는 경우 기본값 반환
Skeleton playerSkeleton = (from s in skeletonData where s.TrackingState == SkeletonTrackingState.Tracked select s).FirstOrDefault();
if (playerSkeleton != null)
{
// TODO: 포인트 가져온다.
// 관절 오른손은 플레이어 스켈레톤에 오른손이다.
Joint rightHand = playerSkeleton.Joints[JointType.HandRight];
//
handPosition = new Vector2((((0.5f * rightHand.Position.X) + 0.5f) * (Config.DISPLAY_WIDTH)), (((-0.5f * rightHand.Position.Y) + 0.5f) * (Config.DISPLAY_HEIGHT)));
}
}
}
}
void kinectSensor_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{
using (ColorImageFrame colorImageFrame = e.OpenColorImageFrame())
{
if (colorImageFrame != null)
{
byte[] pixelsFromFrame = new byte[colorImageFrame.PixelDataLength];
colorImageFrame.CopyPixelDataTo(pixelsFromFrame);
Color[] color = new Color[colorImageFrame.Height * colorImageFrame.Width];
// Go through each pixel and set the bytes correctly
// Remember, each pixel got a Rad, Green and Blue
int index = 0;
for (int y = 0; y < colorImageFrame.Height; y++)
{
for (int x = 0; x < colorImageFrame.Width; x++, index += 4)
{
color[y * colorImageFrame.Width + x] = new Color(pixelsFromFrame[index + 2], pixelsFromFrame[index + 1], pixelsFromFrame[index + 0]);
}
}
}
}
}
// ---------------------------------------------------------------
public override void LoadContent()
{
if (content == null)
content = new ContentManager(ScreenManager.Game.Services, "Content");
t_logo = content.Load<Texture2D>("Textures/MainMenu/logo_mft");
v_logo = new Vector2(400.0f, 159.0f);
bt_0 = new Texture2DButton(
content.Load<Texture2D>("Textures/MainMenu/bt_0_normal"),
content.Load<Texture2D>("Textures/MainMenu/bt_0_select"),
v_bt_0);
bt_1 = new Texture2DButton(
content.Load<Texture2D>("Textures/MainMenu/bt_1_normal"),
content.Load<Texture2D>("Textures/MainMenu/bt_1_select"),
v_bt_1);
bt_2 = new Texture2DButton(
content.Load<Texture2D>("Textures/MainMenu/bt_2_normal"),
content.Load<Texture2D>("Textures/MainMenu/bt_2_select"),
v_bt_2);
bt_3 = new Texture2DButton(
content.Load<Texture2D>("Textures/MainMenu/bt_3_normal"),
content.Load<Texture2D>("Textures/MainMenu/bt_3_select"),
v_bt_3);
// --------------
hand = content.Load<Texture2D>("Textures/hand");
}
public override void UnloadContent()
{
kinectSensor.Stop();
kinectSensor.Dispose();
content.Unload();
}
#region Update and Draw
public override void HandleInput(InputState input)
{
base.HandleInput(input);
//MouseState mounState = Mouse.GetState();
//if (bt_0.IsClick(mounState))
//{
// //LoadingScreen.Load(ScreenManager, true, ControllingPlayer, new MainMenuScreen());
//}
//if (bt_1.IsClick(mounState))
//{
// //LoadingScreen.Load(ScreenManager, true, ControllingPlayer, new MainMenuScreen());
//}
//if (bt_2.IsClick(mounState))
//{
// //LoadingScreen.Load(ScreenManager, true, ControllingPlayer, new MainMenuScreen());
//}
//if (bt_3.IsClick(mounState))
//{
// LoadingScreen.Load(ScreenManager, true, ControllingPlayer, new BackgroundScreen(), new ScoreScreen(1, 1));
//}
if (bt_0.IsOveray(handPosition))
{
}
if (bt_1.IsOveray(handPosition))
{
}
if (bt_2.IsOveray(handPosition))
{
}
if (bt_3.IsOveray(handPosition))
{
}
}
public override void Update(GameTime gameTime, bool otherScreenHasFocus,
bool coveredByOtherScreen)
{
base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
}
public override void Draw(GameTime gameTime)
{
// Our player and enemy are both actually just text strings.
SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
spriteBatch.Begin();
spriteBatch.Draw(t_logo, v_logo, null, Color.White, 0.0f, mVector.GetVector2(t_logo, 0.5f, 0.5f), 1.0f, SpriteEffects.None, 1.0f);
spriteBatch.End();
bt_0.Draw(spriteBatch);
bt_1.Draw(spriteBatch);
bt_2.Draw(spriteBatch);
bt_3.Draw(spriteBatch);
spriteBatch.Begin();
spriteBatch.Draw(hand, handPosition, null, Color.White, 0.0f, mVector.GetVector2(hand, 0.5f, 0.5f), 1.0f, SpriteEffects.None, 1.0f);
spriteBatch.End();
}
#endregion
}
}
'Dev > Kinect' 카테고리의 다른 글
Kinect 관련 유용한 자료 스크랩 (0) | 2012.04.27 |
---|