Esempio n. 1
0
        /// <summary>
        /// This method retrieves a new skeleton frame if necessary.
        /// </summary>
        /// <param name="gameTime">The elapsed game time.</param>
        public override void Update(GameTime gameTime)
        {
            // If the sensor is not found, not running, or not connected, return now
            if (null == this.Chooser || null == this.Chooser.Sensor || false == this.Chooser.Sensor.IsRunning || this.Chooser.Sensor.Status != KinectStatus.Connected)
            {
                return;
            }

            // If we have already drawn this skeleton, then we should retrieve a new frame
            // This prevents us from calling the next frame more than once per update
            if (false == this.SkeletonDrawn && null != this.skeleton && this.useKinectAvateering && this.SkeletonVisible)
            {
                // Copy all bind pose matrices to boneTransforms
                // Note: most are identity, but the translation is important to describe bone length/the offset between bone drawing positions
                this.skinningDataValue.BindPose.CopyTo(this.boneTransforms, 0);
                this.UpdateWorldTransforms(Matrix.Identity);
                this.UpdateSkinTransforms();

                // If required, we should modify the joint positions before we access the bone orientations, as orientations are calculated
                // on the first access, and then whenever a joint position changes. Hence changing joint positions interleaved with accessing
                // rotations will cause unnecessary additional computation.
                float currentNuiTime = (float)this.frameTimer.AbsoluteTime;
                float deltaNuiTime   = currentNuiTime - this.lastNuiTime;

                // Fixup Skeleton to improve avatar appearance.
                if (this.filterClippedLegs && null != this.clippedLegs && null != this.Chooser && !this.Chooser.SeatedMode)
                {
                    this.clippedLegs.FilterSkeleton(this.skeleton, deltaNuiTime);
                }

                if (this.selfIntersectionConstraints)
                {
                    // Constrain the wrist and hand joint positions to not intersect the torso
                    SkeletonJointsSelfIntersectionConstraint.Constrain(this.skeleton);
                }

                if (this.tiltCompensate)
                {
                    int elevationAngle = 0;
                    try
                    {
                        elevationAngle = this.Chooser.Sensor.ElevationAngle;
                    }
                    catch (InvalidOperationException)
                    {
                        // Ignore any exception accessing the sensor if it has just been disconnected
                    }

                    // Correct for sensor tilt if we have a valid floor plane or a sensor tilt value from the motor.
                    SkeletonJointsSensorTiltCorrection.CorrectSensorTilt(this.skeleton, this.FloorClipPlane, elevationAngle);
                }

                if (this.floorOffsetCompensate && 0.0f != this.AvatarHipCenterHeight)
                {
                    // Correct for the sensor height from the floor (moves the skeleton to the floor plane) if we have a valid plane, or feet visible in the image.
                    // Note that by default this will not run unless we have set a non-zero AvatarHipCenterHeight
                    this.sensorOffsetCorrection.CorrectSkeletonOffsetFromFloor(this.skeleton, this.FloorClipPlane, this.AvatarHipCenterHeight);
                }

                if (this.mirrorView)
                {
                    SkeletonJointsMirror.MirrorSkeleton(this.skeleton);
                }

                // Filter the joint positions manually, using a double exponential filter.
                this.jointPositionFilter.UpdateFilter(this.skeleton);

                if (this.boneConstraints && null != this.boneOrientationConstraints)
                {
                    // Constrain the joint positions to approximate range of human motion.
                    this.boneOrientationConstraints.Constrain(this.skeleton, this.mirrorView);
                }

                if (this.filterBoneOrientations && null != this.boneOrientationFilter)
                {
                    // Double Exponential Filtering of the joint orientations.
                    // Note: This updates the joint orientations directly in the skeleton.
                    // It should be performed after all joint position modifications.
                    this.boneOrientationFilter.UpdateFilter(this.skeleton);
                }

                if (null != this.retargetMethod)
                {
                    // Adapt the rotation matrices to the avatar mesh joint local coordinate systems
                    this.retargetMethod(this.skeleton, this.skinningDataValue.BindPose[0], this.boneTransforms);
                }

                // Calculate the Avatar world transforms from the relative bone transforms of Kinect skeleton
                this.UpdateWorldTransforms(Matrix.Identity);

                // Refresh the Avatar SkinTransforms data based on the transforms we just applied
                this.UpdateSkinTransforms();

                this.lastNuiTime = currentNuiTime;
            }

            this.HandleInput();

            base.Update(gameTime);
        }
Esempio n. 2
0
        /// <summary>
        /// This method retrieves a new skeleton frame if necessary.
        /// </summary>
        /// <param name="gameTime">The elapsed game time.</param>
        public Skeleton Filter(Skeleton skel)
        {
            this.skeleton = skel;

            // If we have already drawn this skeleton, then we should retrieve a new frame
            // This prevents us from calling the next frame more than once per update
            if (null != this.skeleton)
            {
                // If required, we should modify the joint positions before we access the bone orientations, as orientations are calculated
                // on the first access, and then whenever a joint position changes. Hence changing joint positions interleaved with accessing
                // rotations will cause unnecessary additional computation.
                float currentNuiTime = (float)this.frameTimer.AbsoluteTime;
                float deltaNuiTime   = currentNuiTime - this.lastNuiTime;

                // Fixup Skeleton to improve avatar appearance.
                if (this.filterClippedLegs && null != this.clippedLegs)
                {
                    this.clippedLegs.FilterSkeleton(this.skeleton, deltaNuiTime);
                }

                if (this.selfIntersectionConstraints)
                {
                    // Constrain the wrist and hand joint positions to not intersect the torso
                    SkeletonJointsSelfIntersectionConstraint.Constrain(this.skeleton);
                }

                if (this.tiltCompensate)
                {
                    int elevationAngle = 0;
                    try
                    {
                        elevationAngle = this.sensor.ElevationAngle;
                    }
                    catch (InvalidOperationException)
                    {
                        // Ignore any exception accessing the sensor if it has just been disconnected
                    }

                    // Correct for sensor tilt if we have a valid floor plane or a sensor tilt value from the motor.
                    SkeletonJointsSensorTiltCorrection.CorrectSensorTilt(this.skeleton, this.FloorClipPlane, elevationAngle);
                }

                if (this.floorOffsetCompensate && 0.0f != this.AvatarHipCenterHeight)
                {
                    // Correct for the sensor height from the floor (moves the skeleton to the floor plane) if we have a valid plane, or feet visible in the image.
                    // Note that by default this will not run unless we have set a non-zero AvatarHipCenterHeight
                    this.sensorOffsetCorrection.CorrectSkeletonOffsetFromFloor(this.skeleton, this.FloorClipPlane, this.AvatarHipCenterHeight);
                }

                if (this.mirrorView)
                {
                    SkeletonJointsMirror.MirrorSkeleton(this.skeleton);
                }

                // Filter the joint positions manually, using a double exponential filter.
                this.jointPositionFilter.UpdateFilter(this.skeleton);

                if (this.boneConstraints && null != this.boneOrientationConstraints)
                {
                    // Constrain the joint positions to approximate range of human motion.
                    this.boneOrientationConstraints.Constrain(this.skeleton, this.mirrorView);
                }

                /*if (this.filterBoneOrientations && null != this.boneOrientationFilter)
                 * {
                 *  // Double Exponential Filtering of the joint orientations.
                 *  // Note: This updates the joint orientations directly in the skeleton.
                 *  // It should be performed after all joint position modifications.
                 *  this.boneOrientationFilter.UpdateFilter(this.skeleton);
                 * }
                 */


                this.lastNuiTime = currentNuiTime;
            }

            return(skel);
        }