Commit 13bed108 authored by Archit Tamarapu's avatar Archit Tamarapu
Browse files

fix EFAP polygon selection in C (EFAP_FIX_POLY) and Python

parent c0dae506
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -152,6 +152,7 @@
#define ISM_BITRATE_SWITCHING                           /* Issue 115: Support for Bitrate Switching in ISM */
#define SBA_SPAR_HARM                                   /* Issue 92: maintenance of the SBA SPAR functions */
#define FIX_155_HP20_ISSUE                              /* Issue 155: apply hp20 on all input channels instead of just 2 channels */
#define EFAP_FIX_POLY                                   /* Issue 167: fix bug in EFAP polygon selection */



+100 −6
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ static void get_poly_gains( const float azi, const float ele, const float aziPol

static float get_tri_gain( const float A[2], const float B[2], const float C[2], const float P_minus_A[2] );

#if defined( DEBUG_EFAP_POLY_TOFILE )
#ifdef DEBUG_EFAP_POLY_TOFILE
static void get_poly_select( EFAP_POLYSET_DATA *polyData );
#endif

@@ -96,11 +96,13 @@ static void add_vertex( EFAP_VERTEX *vtxArray, const float azi, const float ele,

static void efap_sort_s( int16_t *x, int16_t *idx, const int16_t len );


static float vertex_distance( const EFAP_VERTEX *vtxArray, const EFAP_LS_TRIANGLE tri, const int16_t vtxIdx );

static float point_plane_distance( const float P1[3], const float P2[3], const float P3[3], const float X[3] );

#ifdef EFAP_FIX_POLY
static float point_poly_distance( const EFAP_POLYSET poly, const float X[3] );
#endif
static void efap_crossp( const float *v1, const float *v2, float *v );

static int16_t find_int_in_tri( const EFAP_LS_TRIANGLE *tri, const int16_t n, const int16_t r, int16_t *pos );
@@ -125,6 +127,9 @@ static int16_t in_poly( const float P[2], const EFAP_POLYSET poly );

static int16_t in_tri( float A[2], float B[2], float C[2], float P_minus_A[2] );

#ifdef EFAP_FIX_POLY
static void sph2cart( const float azi, const float ele, float *pos );
#endif

/*-----------------------------------------------------------------------*
 * Global function definitions
@@ -462,14 +467,14 @@ static ivas_error poly_init(
    efap->polyData.numPoly = finalLength;


#if defined( DEBUG_EFAP_POLY_TOFILE )
#ifdef DEBUG_EFAP_POLY_TOFILE
    get_poly_select( &efap->polyData );
#endif
    return error;
}


#if defined( DEBUG_EFAP_POLY_TOFILE )
#ifdef DEBUG_EFAP_POLY_TOFILE
static void get_poly_select(
    EFAP_POLYSET_DATA *polyData /* o  : Polygon data structure             */
)
@@ -1497,9 +1502,13 @@ static void add_vertex(
    vtxArray[pos].ele = ( ( -180.0f > tmp ) ? -180.0f : tmp );

    /* Converting spherical coordinates to cartesians, assuming radius = 1 */
#ifdef EFAP_FIX_POLY
    sph2cart( vtxArray[pos].azi, vtxArray[pos].ele, &vtxArray[pos].pos[0] );
#else
    vtxArray[pos].pos[0] = cosf( vtxArray[pos].azi * PI_OVER_180 ) * cosf( vtxArray[pos].ele * PI_OVER_180 );
    vtxArray[pos].pos[1] = sinf( vtxArray[pos].azi * PI_OVER_180 ) * cosf( vtxArray[pos].ele * PI_OVER_180 );
    vtxArray[pos].pos[2] = sinf( vtxArray[pos].ele * PI_OVER_180 );
#endif

    /* Computing the index defined by idx = idxAziTmp + 181 * idxEleTmp  */

@@ -1591,11 +1600,32 @@ static float vertex_distance(
    return point_plane_distance( A, B, C, P );
}

#ifdef EFAP_FIX_POLY
/*-------------------------------------------------------------------------*
 * point_plane_distance()
 *
 * Compute the signed distance between a point and polygon
 *-------------------------------------------------------------------------*/

static float point_poly_distance(
    const EFAP_POLYSET poly, /* i  : The polygon which forms a plane                */
    const float X[3]         /* i  : Cartesian coordinates of the point of interest */
)
{
    float P1[3], P2[3], P3[3];

    sph2cart( poly.polyAzi[0], poly.polyEle[0], &P1[0] );
    sph2cart( poly.polyAzi[1], poly.polyEle[1], &P2[0] );
    sph2cart( poly.polyAzi[2], poly.polyEle[2], &P3[0] );

    return point_plane_distance( P1, P2, P3, X );
}
#endif

/*-------------------------------------------------------------------------*
 * point_plane_distance()
 *
 * Compute the signed distance between a point a given plane
 * Compute the signed distance between a point and a given plane
 *-------------------------------------------------------------------------*/

static float point_plane_distance(
@@ -2082,16 +2112,63 @@ static int16_t get_poly_num(
)
{
    int16_t i;
#ifdef EFAP_FIX_POLY
    int16_t num_poly, found_poly;
    int16_t poly_tmp[9], poly_dist[9];

    float dist_tmp;
    float pos[3];

    num_poly = 0;

    sph2cart( P[0], P[1], &pos[0] );

    /* Filter the polygon list with a fast 2d check */
#endif
    for ( i = 0; i < polyData->numPoly; ++i )
    {
        if ( in_poly( P, polyData->polysetArray[i] ) )
        {
#ifdef EFAP_FIX_POLY
            /* select only polygons which are visible from the point */
            dist_tmp = point_poly_distance( polyData->polysetArray[i], pos );
            if ( dist_tmp == 0 )
            {
                return i;
            }
            else if ( dist_tmp > 0 )
            {
                poly_tmp[num_poly] = i;
                poly_dist[num_poly] = dist_tmp;
                num_poly++;
            }
#else
            return i;
#endif
        }
    }
#ifdef EFAP_FIX_POLY
    if ( num_poly == 0 )
    {
        return -1;
    }

    /* select the polygon with the smallest distance */
    found_poly = poly_tmp[0];
    dist_tmp = poly_dist[0];
    for ( i = 1; i < num_poly; i++ )
    {
        if ( poly_dist[i] < dist_tmp )
        {
            found_poly = poly_tmp[i];
            dist_tmp = poly_dist[i];
        }
    }

    return found_poly;
#else
    return -1;
#endif
}


@@ -2226,3 +2303,20 @@ static int16_t in_tri(
        return 1;
    }
}

/*-------------------------------------------------------------------------*
 * sph2cart()
 *
 * Converts a vertex position to cartesian coordinates
 *-------------------------------------------------------------------------*/

static void sph2cart(
    const float azi, /* i  : Azimuth in degrees                      */
    const float ele, /* i  : Elevation in degrees                    */
    float *pos       /* o  : Cartesian coordinates vector (x, y, z)  */
)
{
    pos[0] = cosf( azi * PI_OVER_180 ) * cosf( ele * PI_OVER_180 );
    pos[1] = sinf( azi * PI_OVER_180 ) * cosf( ele * PI_OVER_180 );
    pos[2] = sinf( ele * PI_OVER_180 );
}
+28 −6
Original line number Diff line number Diff line
@@ -744,18 +744,40 @@ class EFAP:
            raise ValueError(f"Angles cannot be NaNs : ({azimuth}, {elevation})")

        azimuth, elevation = wrap_angles(azimuth, elevation)
        point_pos = [
            np.cos(np.deg2rad(azimuth)) * np.cos(np.deg2rad(elevation)),
            np.sin(np.deg2rad(azimuth)) * np.cos(np.deg2rad(elevation)),
            np.sin(np.deg2rad(elevation)),
        ]

        # find the polygon corresponding to the given point
        found_poly = None
        mod = None
        # filter the polygon list with a quick 2d check
        found_polys = []
        for poly in self.polys:
            in_poly, mod = self._in_polygon(azimuth, elevation, poly)
            if in_poly:
                found_poly = poly
                break
        else:
                found_polys.append((poly, mod))

        if not found_polys:
            raise AssertionError("Unexpected error during panning")

        # find a visible polygon with the smallest distance
        dist = []

        for poly, mod in found_polys:
            surface = self.verts[poly]
            d = self._point_plane_dist(
                surface[0].pos,
                surface[1].pos,
                surface[2].pos,
                point_pos,
            )
            if d >= 0:
                dist.append(d)
            else:
                dist.append(np.inf)

        found_poly, mod = found_polys[np.argmin(dist)]

        # compute gains for the polygon vertices
        poly_gain = self._pan_EFAP_poly(azimuth, elevation, found_poly, mod)