Commit 130c6822 authored by Marek Szczerba's avatar Marek Szczerba
Browse files

Merge branch '109-add-euler-angle-processing' into '109-harmonize-head-and-orientation-tracking'

Addition of Euler angle processing

See merge request !485
parents e7d9b579 6d9fcc64
Loading
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -946,7 +946,7 @@ int main(

    if ( !args.quietModeEnabled )
    {
        fprintf( stdout, "\n------ Running the rondoror ------\n\n" );
        fprintf( stdout, "\n------ Running the renderer ------\n\n" );
        fprintf( stdout, "Frames processed:       " );
    }
    else
+48 −19
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@

*******************************************************************************************************/

#include "common_api_types.h"
#include <stdint.h>
#include "options.h"
#include "ivas_prot.h"
@@ -508,7 +509,17 @@ ivas_error ivas_orient_trk_SetReferenceRotation(
    {
        return IVAS_ERR_UNEXPECTED_NULL_POINTER;
    }

    /* check for Euler angle signaling */
    if ( refRot.w == -3.0f )
    {
        Euler2Quat(deg2rad( refRot.x ), deg2rad( refRot.y ), deg2rad( refRot.z ), &pOTR->refRot );
    }
    else
    {
        pOTR->refRot = refRot;
    }
    
    return IVAS_ERR_OK;
}

@@ -654,48 +665,57 @@ ivas_error ivas_orient_trk_Process(
    float alpha = pOTR->alpha;
    float ang;
    ivas_error result;
#ifdef OTR_REFERENCE_VECTOR_TRACKING
    IVAS_QUATERNION refRot_absRot_product;
#endif /* OTR_REFERENCE_VECTOR_TRACKING */
    IVAS_QUATERNION absQuat, trkQuat;
    IVAS_QUATERNION trkEuler;

    if ( pOTR == NULL || pTrkRot == NULL )
    {
        return IVAS_ERR_UNEXPECTED_NULL_POINTER;
    }

    /* check for Euler angle signaling */
    if ( pAbsRot->w == -3.0f )
    {
        Euler2Quat(deg2rad( pAbsRot->x ), deg2rad( pAbsRot->y ), deg2rad( pAbsRot->z ), &absQuat);
    }
    else
    {
        absQuat = *pAbsRot;
    }

    result = IVAS_ERR_OK;

    switch ( pOTR->trackingType )
    {
        case OTR_TRACKING_NONE:
            *pTrkRot = *pAbsRot;
            trkQuat = absQuat;
            break;

        case OTR_TRACKING_REF_ORIENT:
            /* Reset average orientation   */
            pOTR->absAvgRot = *pAbsRot;
            pOTR->absAvgRot = absQuat;

            /* Reset adaptation filter - start adaptation at center rate */
            pOTR->alpha = sinf( 2.0f * EVS_PI * pOTR->centerAdaptationRate / updateRate );

            /* Compute relative orientation = (absolute orientation) - (reference orientation) */
            QuaternionInverse( pOTR->refRot, pTrkRot );
            QuaternionProduct( *pTrkRot, *pAbsRot, pTrkRot );
            QuaternionInverse( pOTR->refRot, &trkQuat );
            QuaternionProduct( trkQuat, absQuat, &trkQuat );
            break;

        case OTR_TRACKING_AVG_ORIENT:
            /* Compute average (low-pass filtered) absolute orientation */
            QuaternionSlerp( pOTR->absAvgRot, *pAbsRot, alpha, &pOTR->absAvgRot );
            QuaternionSlerp( pOTR->absAvgRot, absQuat, alpha, &pOTR->absAvgRot );

            /* Compute relative orientation = (absolute orientation) - (average absolute orientation) */
            QuaternionInverse( pOTR->absAvgRot, pTrkRot );
            QuaternionProduct( *pTrkRot, *pAbsRot, pTrkRot );
            QuaternionInverse( pOTR->absAvgRot, &trkQuat );
            QuaternionProduct( trkQuat, absQuat, &trkQuat );

            /* Adapt LPF constant based on orientation excursion relative to current mean:
            - low  cutoff (slow adaptation) for small excursions (around center)
            - high cutoff (fast adaptation) for large excursions (off-center)
            */
            ang = QuaternionAngle( *pAbsRot, *pTrkRot );
            ang = QuaternionAngle( absQuat, trkQuat );
            normalizedOrientation = ang * ang;

            relativeOrientationRate = sqrtf( normalizedOrientation ) / pOTR->adaptationAngle;
@@ -724,12 +744,7 @@ ivas_error ivas_orient_trk_Process(
        case OTR_TRACKING_REF_VEC_LEV:
        {
            /* This processing step of the OTR_TRACKING_REF_VEC/OTR_TRACKING_REF_VEC_LEVEL is identical */
            QuaternionProduct( pOTR->refRot, *pAbsRot, &refRot_absRot_product );

            pTrkRot->w = refRot_absRot_product.w;
            pTrkRot->x = refRot_absRot_product.x;
            pTrkRot->y = refRot_absRot_product.y;
            pTrkRot->z = refRot_absRot_product.z;
            QuaternionProduct( pOTR->refRot, absQuat, &trkQuat );
            break;
        }
#endif /* OTR_REFERENCE_VECTOR_TRACKING */
@@ -740,7 +755,21 @@ ivas_error ivas_orient_trk_Process(

    if ( result == IVAS_ERR_OK )
    {
        pOTR->trkRot = *pTrkRot;
        pOTR->trkRot = trkQuat;

        if ( pAbsRot->w == -3.0f )
        {
            Quat2Euler( trkQuat, &trkEuler.z, &trkEuler.y, &trkEuler.x );
            trkEuler.x = rad2deg( trkEuler.x );
            trkEuler.y = rad2deg( trkEuler.y );
            trkEuler.z = rad2deg( trkEuler.z );
            trkEuler.w = -3.0f;
            *pTrkRot = trkEuler;
        }
        else
        {
            *pTrkRot = trkQuat;
        }
    }

    return result;
+17 −4
Original line number Diff line number Diff line
@@ -807,11 +807,24 @@ void ivas_headTrack_close(

void Quat2Euler(
    const IVAS_QUATERNION quat,                                 /* i  : quaternion describing the rotation  */
    float *yaw,                                                 /* o  : yaw                                             */
    float *pitch,                                               /* o  : pitch                                           */
    float *roll                                                 /* o  : roll                                            */
    float *yaw,                                                 /* o  : yaw   (z)                           */
    float *pitch,                                               /* o  : pitch (y)                           */
    float *roll                                                 /* o  : roll  (x)                           */
);

#ifdef FIX_I109_ORIENTATION_TRACKING
void Euler2Quat(
    const float roll,                                           /* i  : roll  (x)                           */
    const float pitch,                                          /* i  : pitch (y)                           */
    const float yaw,                                            /* i  : yaw   (z)                           */
    IVAS_QUATERNION *quat                                       /* o  : quaternion describing the rotation  */
);

float deg2rad( float degrees );

float rad2deg( float radians );
#endif

void QuatToRotMat(
    const IVAS_QUATERNION quat,                                 /* i  : quaternion describing the rotation              */
    float Rmat[3][3]                                            /* o  : real-space rotation matrix for this rotation    */
+67 −7
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@

*******************************************************************************************************/

#include "ivas_cnst.h"
#include <assert.h>
#include <stdint.h>
#include "options.h"
@@ -127,7 +128,11 @@ void QuatToRotMat(
     *  Euler angles instead of quaternions. In this case, all the w values must
     *  be set to -3.0 in the trajectory file to signal switching to Euler angles.
     *  The x,y, and z components of the quaternion are then interpreted as
#ifdef FIX_I109_ORIENTATION_TRACKING
     *  yaw-pitch-roll.
#else // see below: "Euler angles in R_X(roll)*R_Y(pitch)*R_Z(yaw) convention"
     *  roll-pitch-yaw.
#endif
     */
    if ( quat.w != -3.0 )
    {
@@ -176,25 +181,30 @@ void QuatToRotMat(
    return;
}

#ifndef FIX_I109_ORIENTATION_TRACKING
/*-------------------------------------------------------------------------
 * Quat2Euler()
 *
 * Quaternion handling: calculate corresponding Euler angles
 * Quaternion handling: calculate corresponding Euler angles in radians
 *------------------------------------------------------------------------*/

void Quat2Euler(
    const IVAS_QUATERNION quat, /* i  : quaternion describing the rotation  */
    float *yaw,                 /* o  : yaw                                 */
    float *pitch,               /* o  : pitch                               */
    float *roll                 /* o  : roll                                */
    float *yaw,                 /* o  : yaw   (z)                           */
    float *pitch,               /* o  : pitch (y)                           */
    float *roll                 /* o  : roll  (x)                           */
)
{
    if ( quat.w != -3.0 )
    {
#ifdef FIX_I109_ORIENTATION_TRACKING
        *roll = atan2f( 2 * ( quat.w * quat.x + quat.y * quat.z ), 1 - 2 * ( quat.x * quat.x + quat.y * quat.y ) );
        *pitch = asinf( 2 * ( quat.w * quat.y - quat.z * quat.x ) );
        *yaw = atan2f( 2 * ( quat.w * quat.z + quat.x * quat.y ), 1 - 2 * ( quat.y * quat.y + quat.z * quat.z ) );
#else // bug: x and z swapped
        *yaw = atan2f( 2 * ( quat.w * quat.x + quat.y * quat.z ), 1 - 2 * ( quat.x * quat.x + quat.y * quat.y ) );
        *pitch = asinf( 2 * ( quat.w * quat.y - quat.z * quat.x ) );
        *roll = atan2f( 2 * ( quat.w * quat.z + quat.x * quat.y ), 1 - 2 * ( quat.y * quat.y + quat.z * quat.z ) );
#endif
    }
    else
    {
@@ -211,6 +221,56 @@ void Quat2Euler(

    return;
}

#ifdef FIX_I109_ORIENTATION_TRACKING
/*-------------------------------------------------------------------------
 * Euler2Quat()
 *
 * Calculate corresponding Quaternion from Euler angles in radians
 *------------------------------------------------------------------------*/

void Euler2Quat(
    const float roll,           /* i  : roll  (x)                           */
    const float pitch,          /* i  : pitch (y)                           */
    const float yaw,            /* i  : yaw   (z)                           */
    IVAS_QUATERNION *quat       /* o  : quaternion describing the rotation  */
)
{
    float cr = cosf( roll * 0.5f );
    float sr = sinf( roll * 0.5f );
    float cp = cosf( pitch * 0.5f );
    float sp = sinf( pitch * 0.5f );
    float cy = cosf( yaw * 0.5f );
    float sy = sinf( yaw * 0.5f );

    quat->w = cr * cp * cy + sr * sp * sy;
    quat->x = sr * cp * cy - cr * sp * sy;
    quat->y = cr * sp * cy + sr * cp * sy;
    quat->z = cr * cp * sy - sr * sp * cy;

    return;
}

/*-------------------------------------------------------------------------
 * rad2deg()
 *
 * Return angle in radians from degrees
 *------------------------------------------------------------------------*/
float deg2rad( float degrees )
{
    return PI_OVER_180 * degrees;
}

/*-------------------------------------------------------------------------
 * deg2rad()
 *
 * Return angle in degrees from radians
 *------------------------------------------------------------------------*/
float rad2deg( float radians )
{
    return _180_OVER_PI * radians;
}

#endif