//--------------------------------------------------------------------------------------
    // Name: Update()
    // Desc: Adds a new frame of positions, updates the coordiante system, and calculates 
    //       left and right hand.
    //--------------------------------------------------------------------------------------
    VOID SpineRelativeCameraSpaceCoordinateSystem::Update( const NUI_SKELETON_FRAME* pRawSkeletonFrame, INT iSkeletonIndex, XMVECTOR vLeft, XMVECTOR vRight )
    {
        if ( pRawSkeletonFrame == NULL ) return;
        if ( iSkeletonIndex < 0 || iSkeletonIndex >= NUI_SKELETON_COUNT ) return;
        CONST XMVECTOR *pSkeletonPosition = &pRawSkeletonFrame->SkeletonData[iSkeletonIndex].SkeletonPositions[0];

        if ( m_dwLastTrackingID != pRawSkeletonFrame->SkeletonData[iSkeletonIndex].dwTrackingID )
        {
            m_vAverageNormalToGravity = pRawSkeletonFrame->vNormalToGravity;
        }
        else
        {
            m_vAverageNormalToGravity = m_fSpineUpdateRate * m_vAverageNormalToGravity +
                 pRawSkeletonFrame->vNormalToGravity * ( 1.0f - m_fSpineUpdateRate );
        }
        
#if 0
        CHAR out[255];
        sprintf_s( out, "x=%f,y=%f,z=%f,w=%f\n", pRawSkeletonFrame->vNormalToGravity.x, pRawSkeletonFrame->vNormalToGravity.y, pRawSkeletonFrame->vNormalToGravity.z, pRawSkeletonFrame->vNormalToGravity.w );
        OutputDebugString( out );
#endif 
        m_matRotateToNormalToGravity = NuiTransformMatrixLevel( m_vAverageNormalToGravity );
        XMVECTOR vSpineTilted = XMVector3Transform( pSkeletonPosition[NUI_SKELETON_POSITION_SPINE], m_matRotateToNormalToGravity );
        XMVECTOR vHeadTilted = XMVector3Transform( pSkeletonPosition[NUI_SKELETON_POSITION_HEAD], m_matRotateToNormalToGravity );
        m_vLeftHandRelative = XMVector3Transform( vLeft, m_matRotateToNormalToGravity );
        m_vRightHandRelative = XMVector3Transform( vRight, m_matRotateToNormalToGravity );


        FLOAT fSpineHeadLength = XMVectorGetY( vHeadTilted ) - XMVectorGetY( vSpineTilted );
        if ( m_dwLastTrackingID != pRawSkeletonFrame->SkeletonData[iSkeletonIndex].dwTrackingID )
        {
            m_dwLastTrackingID = pRawSkeletonFrame->SkeletonData[iSkeletonIndex].dwTrackingID;
            m_vAverageSpine = vSpineTilted;
            m_fAverageSpineHeadLength = fSpineHeadLength;
        }
        else
        {
            m_vAverageSpine = m_vAverageSpine * m_fSpineUpdateRate + 
                vSpineTilted * ( 1.0f - m_fSpineUpdateRate );
            m_fAverageSpineHeadLength = ATG::Lerp( fSpineHeadLength, m_fAverageSpineHeadLength, m_fBodySizeUpdateRate );
        }

        m_vEstiamtedPivotOffsetLeft = XMVectorSet( m_fAverageSpineHeadLength * 0.3f, m_fAverageSpineHeadLength * 0.1f, 0.0f, 0.0f );
        m_vEstiamtedPivotOffsetRight = XMVectorSet( -m_fAverageSpineHeadLength * 0.3f, m_fAverageSpineHeadLength * 0.1f, 0.0f, 0.0f );
        m_vRightHandRelative -= m_vAverageSpine;
        m_vRightHandRelative += m_vEstiamtedPivotOffsetRight;
        m_vLeftHandRelative -= m_vAverageSpine;
        m_vLeftHandRelative += m_vEstiamtedPivotOffsetLeft;
        static XMVECTOR vFlipZ = XMVectorSet( 1.0f, 1.0f, -1.0f, 1.0f );
        m_vRightHandRelative *= vFlipZ;
        m_vLeftHandRelative *= vFlipZ;

    }
Example #2
0
    //--------------------------------------------------------------------------------------
    // Applies tilt correction to the skeleton data data. Source and destination can be the same
    //--------------------------------------------------------------------------------------
    VOID ApplyTiltCorrectionInPlayerSpace( NUI_SKELETON_FRAME* pDstSkeleton, const NUI_SKELETON_FRAME* pSrcSkeleton )
    {
        assert( pDstSkeleton );
        assert( pSrcSkeleton );

        if ( !pDstSkeleton ||
             !pSrcSkeleton )
        {
            return;
        }

        static const XMVECTOR vUp = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
        static XMVECTOR vAverageSpine[ NUI_SKELETON_COUNT ] = { XMVectorZero(), XMVectorZero(), XMVectorZero(),
                                                                XMVectorZero(), XMVectorZero(), XMVectorZero() };
        static XMVECTOR vAverageNormalToGravity = pSrcSkeleton->vNormalToGravity;

        // Get a valid up vector
        XMVECTOR vNormToGrav = pSrcSkeleton->vNormalToGravity;

        // Check for an invalid up vector (we will synthesize it from
        // the floor plane if that data is present). If we can't get an up
        // vector, we default to 0.0, 1.0, 0.0 instead.
        if ( fabs(vNormToGrav.x) < FLT_EPSILON &&
             fabs(vNormToGrav.y) < FLT_EPSILON &&
             fabs(vNormToGrav.z) < FLT_EPSILON )
        {
            vNormToGrav = vUp;
        }

        // Calculate running average of vector
        vAverageNormalToGravity = XMVectorLerp( vAverageNormalToGravity, vNormToGrav, 0.1f );

        // Generate the leveling matrix and apply it to all points on any skeletons
        // which are currently being tracked. 
        XMMATRIX matLevel = NuiTransformMatrixLevel( vAverageNormalToGravity );

        for ( INT i = 0 ; i < NUI_SKELETON_COUNT; i++ )
        {
            const NUI_SKELETON_DATA* pSkeletonData = &pSrcSkeleton->SkeletonData[ i ];
            XMVECTOR vSpine = pSkeletonData->SkeletonPositions[ NUI_SKELETON_POSITION_SPINE ];

            if ( pSkeletonData->eTrackingState != NUI_SKELETON_TRACKED )
            {
                vAverageSpine[ i ] = XMVectorZero();
                continue;
            }
            else
            {
                UINT uCompareResults;
                XMVectorEqualR( &uCompareResults, XMVectorZero(), vAverageSpine[ i ] );

                // if still set to zero, then start the running average
                if( XMComparisonAllTrue( uCompareResults ) )
                {
                    vAverageSpine[ i ] = vSpine;
                }
            }

            // Running average of spine
            vAverageSpine[ i ] = XMVectorLerp( vAverageSpine[ i ], vSpine, 0.1f );

            XMFLOAT4 fAverageSpine;
            XMStoreFloat4( &fAverageSpine, vAverageSpine[ i ] );
            XMMATRIX matTranslateToOrigin = XMMatrixTranslation( -fAverageSpine.x, 0, -fAverageSpine.z );
            XMMATRIX matTranslateFromOrigin = XMMatrixTranslation( fAverageSpine.x, 0, fAverageSpine.z );
            XMMATRIX matTransformation = matTranslateToOrigin * matLevel * matTranslateFromOrigin;

            for ( UINT j = 0; j < NUI_SKELETON_POSITION_COUNT; j++ )
            {
                pDstSkeleton->SkeletonData[ i ].SkeletonPositions[ j ] = XMVector3Transform( pSkeletonData->SkeletonPositions[ j ], matLevel );
            }
        }
    }