private bool was_drawn = false; // whether or not the skeleton data can be rendered

        #endregion Fields

        #region Constructors

        /*/////////////////////////////////////////
          * CONSTRUCTOR(S)/DESTRUCTOR(S)
          */
        ///////////////////////////////////////
        public SkeletonStreamManager(Rectangle p_dest_rect,
                                     KinectManager p_kinect,
                                     GraphicsDevice p_gfx_device,
                                     Texture2D p_joint,
                                     Texture2D p_bone)
        {
            // Initialisation...
            this.rect = p_dest_rect;

            // Load graphical resources:
            this.joint_texture = p_joint;
            this.bone_texture = p_bone;

            this.joint_origin = new Vector2((float)Math.Ceiling(this.joint_texture.Width / 2.0),
                                            (float)Math.Ceiling(this.joint_texture.Height / 2.0));
            this.bone_origin = new Vector2(0.05f, 0.0f);

            // Create the render target & associated data:
            PresentationParameters pres_params = p_gfx_device.PresentationParameters;
            this.render_texture = new RenderTarget2D(p_gfx_device,
                                                     pres_params.BackBufferWidth,
                                                     pres_params.BackBufferHeight,
                                                     false,
                                                     p_gfx_device.DisplayMode.Format,
                                                     DepthFormat.Depth24);

            if (p_kinect.kinect_sensor != null) p_kinect.kinect_sensor.SkeletonFrameReady += this.updateSkeleton;
        }
        public void draw(SpriteBatch p_sprite_batch,
                         KinectManager p_kinect,
                         GraphicsDevice p_gfx_device)
        {
            // Render the skeleton stream video...
            p_sprite_batch.Begin();

            p_sprite_batch.Draw(this.render_texture,
                                this.rect,
                                Color.White);

            p_sprite_batch.End();
        }
        /*/////////////////////////////////////////
          * CONSTRUCTOR(S)/DESTRUCTOR(S)
          */
        ///////////////////////////////////////
        public ColourStreamManager(Rectangle p_dest_rect,
                                   Effect p_colour_vis,
                                   KinectManager p_kinect,
                                   GraphicsDevice p_gfx_device)
        {
            // Initialisation...
            this.rect = p_dest_rect;
            this.colour_visualiser = p_colour_vis;

            this.colour_texture = new Texture2D(p_gfx_device,
                                                p_kinect.kinect_sensor.ColorStream.FrameWidth,
                                                p_kinect.kinect_sensor.ColorStream.FrameHeight);
            this.colour_data = new byte[p_kinect.kinect_sensor.ColorStream.FramePixelDataLength];

            if(p_kinect.kinect_sensor != null) p_kinect.kinect_sensor.ColorFrameReady += this.updateColourVideo;
        }
        /*/////////////////////////////////////////
          * RENDERING FUNCTION(S)
          */
        ///////////////////////////////////////
        public void draw(SpriteBatch p_sprite_batch, KinectManager p_kinect)
        {
            // Render the depth stream video...
            if (p_kinect != null &&
                p_sprite_batch != null &&
                this.depth_texture != null &&
                this.was_drawn)
            {
                this.depth_texture.SetData<short>(this.depth_data);

                p_sprite_batch.Begin(SpriteSortMode.Immediate, null, null, null, null, this.depth_visualiser);
                p_sprite_batch.Draw(depth_texture,
                                    this.rect,
                                    Color.White);
                p_sprite_batch.End();
            }
        }
        /*/////////////////////////////////////////
          * CONSTRUCTOR(S)/DESTRUCTOR(S)
          */
        ///////////////////////////////////////
        public DepthStreamManager(Rectangle p_dest_rect,
                                  Effect p_depth_vis,
                                  KinectManager p_kinect,
                                  GraphicsDevice p_gfx_device)
        {
            // Initialisation...
            rect = p_dest_rect;
            this.depth_visualiser = p_depth_vis;

            this.depth_texture = new Texture2D(p_gfx_device,
                                               p_kinect.kinect_sensor.DepthStream.FrameWidth,
                                               p_kinect.kinect_sensor.DepthStream.FrameHeight,
                                               false,
                                               SurfaceFormat.Bgra4444);
            this.depth_data = new short[p_kinect.kinect_sensor.DepthStream.FramePixelDataLength];

            if(p_kinect.kinect_sensor != null) p_kinect.kinect_sensor.DepthFrameReady += this.updateDepthVideo;
        }
        /*/////////////////////////////////////////
          * RENDERING FUNCTION(S)
          */
        ///////////////////////////////////////
        public void draw(SpriteBatch p_sprite_batch, KinectManager p_kinect)
        {
            // Render the colour stream video...
            if(p_kinect != null &&
               p_sprite_batch != null &&
               this.colour_texture != null)
            {
                this.colour_texture.SetData(this.colour_data);

                p_sprite_batch.Begin(SpriteSortMode.Immediate, null, null, null, null, this.colour_visualiser);
                p_sprite_batch.Draw(colour_texture,
                                    this.rect,
                                    Color.White);
                p_sprite_batch.End();

                was_drawn = true;
            }
        }
        private bool was_drawn = false; // whether or not the skeleton data can be rendered

        #endregion Fields

        #region Constructors

        /*/////////////////////////////////////////
          * CONSTRUCTOR(S)/DESTRUCTOR(S)
          */
        ///////////////////////////////////////
        public SkeletonStreamManager(Rectangle p_dest_rect,
                                     KinectManager p_kinect,
                                     GraphicsDevice p_gfx_device,
                                     Texture2D p_joint,
                                     Texture2D p_bone)
        {
            // Initialisation...
            this.rect = p_dest_rect;

            // Load graphical resources:
            this.joint_texture = p_joint;
            this.bone_texture = p_bone;
            this.fizbin_controller = null;

            this.joint_origin = new Vector2((float)Math.Ceiling(this.joint_texture.Width / 2.0),
                                            (float)Math.Ceiling(this.joint_texture.Height / 2.0));
            this.bone_origin = new Vector2(0.05f, 0.0f);

            // Create the render target & associated data:
            PresentationParameters pres_params = p_gfx_device.PresentationParameters;
            this.render_texture = new RenderTarget2D(p_gfx_device,
                                                     pres_params.BackBufferWidth,
                                                     pres_params.BackBufferHeight,
                                                     false,
                                                     p_gfx_device.DisplayMode.Format,
                                                     DepthFormat.Depth24);

            this.skeleton_players = new Dictionary<int, SkeletonPlayer>();
            this.player_refs = new List<int>();

            if (p_kinect.kinect_sensor != null)
            {
                // Start the Fizbin controller:
                p_kinect.kinect_sensor.SkeletonFrameReady += this.updateSkeleton;

                this.fizbin_controller = new GestureController();
                this.fizbin_controller.GestureRecognized += this.gestureRecognition;
                this.registerGestures();

                this.clear_timer = new Timer(2000); // used to clear last gesture
                this.clear_timer.Elapsed += this.clearGestures;
            }
        }
 /*/////////////////////////////////////////
   * DEPTH STREAM HANDLER SHUTDOWN
   */
 ///////////////////////////////////////
 public void close(KinectManager p_kinect)
 {
     // Remove colour frame listener...
     if (p_kinect != null && p_kinect.kinect_sensor != null) p_kinect.kinect_sensor.DepthFrameReady -= this.updateDepthVideo;
 }
 /*/////////////////////////////////////////
   * SKELETON STREAM HANDLER SHUTDOWN
   */
 ///////////////////////////////////////
 public void close(KinectManager p_kinect)
 {
     // Remove colour frame listener...
     if (p_kinect != null && p_kinect.kinect_sensor != null) p_kinect.kinect_sensor.SkeletonFrameReady -= this.updateSkeleton;
 }
 /*/////////////////////////////////////////
   * CO-ORDINATE FUNCTION(S)
   */
 ///////////////////////////////////////
 private Vector2 skeletonToPoint(SkeletonPoint p_point,
                                 KinectManager p_kinect)
 {
     // Function mapping a SkeletonPoint from one space to another...
     if(p_kinect != null &&
        p_kinect.kinect_sensor != null &&
        p_kinect.kinect_sensor.DepthStream != null)
     {
         var depth_pt = p_kinect.kinect_sensor.CoordinateMapper.MapSkeletonPointToDepthPoint(p_point,
                                                                                             p_kinect.kinect_sensor.DepthStream.Format);
         return new Vector2(depth_pt.X,
                            depth_pt.Y);
     }
     else
     {
         return Vector2.Zero;
     }
 }
        private void drawBone(JointCollection p_joints,
                              JointType p_start,
                              JointType p_end,
                              KinectManager p_kinect,
                              SpriteBatch p_sprite_batch)
        {
            // Draw a single joint-bone-joint...
            Vector2 start = this.skeletonToPoint(p_joints[p_start].Position, p_kinect);
            Vector2 end = this.skeletonToPoint(p_joints[p_end].Position, p_kinect);
            Vector2 difference = end - start;
            Vector2 scale = new Vector2(1.0f, difference.Length() / this.bone_texture.Height);

            float angle = (float)Math.Atan2(difference.Y, difference.X) - MathHelper.PiOver2;

            // Set colour(s):
            Color colour = Color.LightGreen;

            if (p_joints[p_start].TrackingState != JointTrackingState.Tracked ||
                p_joints[p_end].TrackingState != JointTrackingState.Tracked)
            {
                colour = Color.Gray;
            }

            p_sprite_batch.Draw(this.bone_texture,
                                start,
                                null,
                                colour,
                                angle,
                                this.bone_origin,
                                scale,
                                SpriteEffects.None,
                                1.0f);
        }
 /*/////////////////////////////////////////
   * JOINT POSITION FUNCTION(S)
   */
 ///////////////////////////////////////
 public Vector2 getJointPos(JointType p_joint, byte p_skeleton_id, KinectManager p_kinect)
 {
     // Return the screen position of the specified skeleton joint (if applicable)...
     if(p_skeleton_id < skeleton_data.Length)
     {
         return this.skeletonToPoint(skeleton_data[p_skeleton_id].Joints[p_joint].Position, p_kinect);
     }
     else
     {
         return Vector2.Zero;
     }
 }
        /*/////////////////////////////////////////
          * RENDERING FUNCTION(S)
          */
        ///////////////////////////////////////
        public void drawToTexture(KinectManager p_kinect,
                                  GraphicsDevice p_gfx_device,
                                  SpriteBatch p_sprite_batch)
        {
            // Render the skeleton stream video to the render target...
            if (p_kinect != null &&
                p_kinect.kinect_sensor != null)
            {
                p_gfx_device.SetRenderTarget(this.render_texture); // draw to the render texture
                p_gfx_device.Clear(Color.DarkRed);

                if (this.skeleton_data != null)
                {
                    p_sprite_batch.Begin();

                    foreach (var skeleton in this.skeleton_data)
                    {
                        if (skeleton.TrackingState == SkeletonTrackingState.Tracked)
                        {
                            // Draw upper body:
                            this.drawBone(skeleton.Joints, JointType.Head, JointType.ShoulderCenter, p_kinect, p_sprite_batch);
                            this.drawBone(skeleton.Joints, JointType.ShoulderCenter, JointType.ShoulderLeft, p_kinect, p_sprite_batch);
                            this.drawBone(skeleton.Joints, JointType.ShoulderCenter, JointType.ShoulderRight, p_kinect, p_sprite_batch);

                            // Draw lower body
                            //if(p_kinect.kinect_sensor)
                            //{
                                this.drawBone(skeleton.Joints, JointType.ShoulderCenter, JointType.Spine, p_kinect, p_sprite_batch);
                                this.drawBone(skeleton.Joints, JointType.Spine, JointType.HipCenter, p_kinect, p_sprite_batch);
                                this.drawBone(skeleton.Joints, JointType.HipCenter, JointType.HipLeft, p_kinect, p_sprite_batch);
                                this.drawBone(skeleton.Joints, JointType.HipCenter, JointType.HipRight, p_kinect, p_sprite_batch);
                            //}

                            // Draw left arm:
                            this.drawBone(skeleton.Joints, JointType.ShoulderLeft, JointType.ElbowLeft, p_kinect, p_sprite_batch);
                            this.drawBone(skeleton.Joints, JointType.ElbowLeft, JointType.WristLeft, p_kinect, p_sprite_batch);
                            this.drawBone(skeleton.Joints, JointType.WristLeft, JointType.HandLeft, p_kinect, p_sprite_batch);

                            // Draw right arm:
                            this.drawBone(skeleton.Joints, JointType.ShoulderRight, JointType.ElbowRight, p_kinect, p_sprite_batch);
                            this.drawBone(skeleton.Joints, JointType.ElbowRight, JointType.WristRight, p_kinect, p_sprite_batch);
                            this.drawBone(skeleton.Joints, JointType.WristRight, JointType.HandRight, p_kinect, p_sprite_batch);

                            // Draw left leg:
                            this.drawBone(skeleton.Joints, JointType.HipLeft, JointType.KneeLeft, p_kinect, p_sprite_batch);
                            this.drawBone(skeleton.Joints, JointType.KneeLeft, JointType.AnkleLeft, p_kinect, p_sprite_batch);
                            this.drawBone(skeleton.Joints, JointType.AnkleLeft, JointType.FootLeft, p_kinect, p_sprite_batch);

                            // Draw right leg:
                            this.drawBone(skeleton.Joints, JointType.HipRight, JointType.KneeRight, p_kinect, p_sprite_batch);
                            this.drawBone(skeleton.Joints, JointType.KneeRight, JointType.AnkleRight, p_kinect, p_sprite_batch);
                            this.drawBone(skeleton.Joints, JointType.AnkleRight, JointType.FootRight, p_kinect, p_sprite_batch);

                            // Draw all the joints:
                            foreach (Joint j in skeleton.Joints)
                            {
                                Color joint_colour = Color.Green;

                                if (j.TrackingState != JointTrackingState.Tracked)
                                {
                                    joint_colour = Color.Yellow;
                                }

                                p_sprite_batch.Draw(this.joint_texture,
                                                    this.skeletonToPoint(j.Position, p_kinect),
                                                    null,
                                                    joint_colour,
                                                    0.0f,
                                                    this.joint_origin,
                                                    1.0f,
                                                    SpriteEffects.None,
                                                    0.0f);
                            }
                        }
                        else if (skeleton.TrackingState == SkeletonTrackingState.PositionOnly)
                        {
                            // If only tracking position, draw a blue dot:
                            p_sprite_batch.Draw(this.joint_texture,
                                                          this.skeletonToPoint(skeleton.Position, p_kinect),
                                                          null,
                                                          Color.Blue,
                                                          0.0f,
                                                          this.joint_origin,
                                                          1.0f,
                                                          SpriteEffects.None,
                                                          0.0f);
                        }
                    }

                    p_sprite_batch.End();
                }

                p_gfx_device.SetRenderTarget(null); // back to regular drawing
                was_drawn = true;
            }
        }
 /*/////////////////////////////////////////
   * SKELETON STREAM HANDLER SHUTDOWN
   */
 ///////////////////////////////////////
 public void close(KinectManager p_kinect)
 {
     // Remove frame listener...
     if (p_kinect != null && p_kinect.kinect_sensor != null)
     {
         p_kinect.kinect_sensor.SkeletonFrameReady -= this.updateSkeleton;
         this.fizbin_controller.GestureRecognized -= this.gestureRecognition;
     }
 }
        /*/////////////////////////////////////////
         * GRAPHICAL DATA & RESOURCE LOADING
         */
        ////////////////////////////////////////
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            this.sprite_batch = new SpriteBatch(this.GraphicsDevice);

            // Load game logo:
            this.logo = this.Content.Load<Texture2D>("Textures/Interface/UI_Logo");
            this.logo_pos = new Vector2((float)Math.Ceiling((this.GraphicsDevice.Viewport.Width - this.logo.Width) / 2.0),
                                        (float)Math.Ceiling((this.GraphicsDevice.Viewport.Height - this.logo.Height) / 2.0));

            // Create Kinect manager:
            this.kinect_manager = new KinectManager(ColorImageFormat.RgbResolution640x480Fps30,
                                                    DepthImageFormat.Resolution640x480Fps30,
                                                    this);
        }