GLProgramming.com

home :: about :: development guides :: irc :: forums :: search :: paste :: links :: contribute :: code dump

-> Click here to learn how to get live help <-


New Paste :: Recent Pastes:: No Line Numbers


sorting vertex order by Scouse
1
 
void Poly::SortVerticesCW ( )
{
    //
    // Calculate center of polygon
    //
    Vector3    center;

    for ( int i = 0; i < GetNumberOfVertices ( ); i++ )
    {
        center = center + verts[ i ].p;
    }

    center = center / GetNumberOfVertices ( );

    //
    // Sort vertices
    //
    for ( i = 0; i < GetNumberOfVertices ( ) - 2; i++ )
    {
        Vector3    a;
        Plane    p;
        double    SmallestAngle    = -1;
        int        Smallest        = -1;

        a = verts[ i ].p - center;
        a.Normalize ( );

        p.PointsToPlane ( verts[ i ].p, center, center + plane.n );

        for ( int j = i + 1; j < GetNumberOfVertices ( ); j++ )
        {
            if ( p.ClassifyPoint ( verts[ j ].p ) != Plane::eCP::BACK )
            {
                Vector3    b;
                double    Angle;
                
                b = verts[ j ].p - center;
                b.Normalize ( );

                Angle = a.Dot ( b );

                if ( Angle > SmallestAngle )
                {
                    SmallestAngle    = Angle;
                    Smallest        = j;
                }
            }
        }

        if ( Smallest == -1 )
        {
            cout << "Error: Degenerate polygon!" << endl;

            abort ( );
        }

        Vertex    t            = verts[ Smallest ];
        verts[ Smallest ]    = verts[ i + 1 ];
        verts[ i + 1 ]        = t;
    }

    //
    // Check if vertex order needs to be reversed for back-facing polygon
    //
    Plane    oldPlane = plane;

    CalculatePlane ( );

    if ( plane.n.Dot ( oldPlane.n ) < 0 )
    {
        int j = GetNumberOfVertices ( );

        for ( int i = 0; i < j / 2; i++ )
        {
            Vertex v            = verts[ i ];
            verts[ i ]            = verts[ j - i - 1 ];
            verts[ j - i - 1 ]    = v;
        }
    }
}


bool Poly::CalculatePlane ( )
{
    Vector3    centerOfMass;
    double    magnitude;
    int     i, j;

    if ( GetNumberOfVertices ( ) < 3 )
    {
        cout << "Polygon has less than 3 vertices!" << endl;

        return false;
    }

    plane.n.x        = 0.0f;
    plane.n.y        = 0.0f;
    plane.n.z        = 0.0f;
    centerOfMass.x    = 0.0f; 
    centerOfMass.y    = 0.0f; 
    centerOfMass.z    = 0.0f;

    for ( i = 0; i < GetNumberOfVertices ( ); i++ )
    {
        j = i + 1;

        if ( j >= GetNumberOfVertices ( ) )
        {
            j = 0;
        }

        plane.n.x += ( verts[ i ].p.y - verts[ j ].p.y ) * ( verts[ i ].p.z + verts[ j ].p.z );
        plane.n.y += ( verts[ i ].p.z - verts[ j ].p.z ) * ( verts[ i ].p.x + verts[ j ].p.x );
        plane.n.z += ( verts[ i ].p.x - verts[ j ].p.x ) * ( verts[ i ].p.y + verts[ j ].p.y );

        centerOfMass.x += verts[ i ].p.x;
        centerOfMass.y += verts[ i ].p.y;
        centerOfMass.z += verts[ i ].p.z;
    }

    if ( ( fabs ( plane.n.x ) < epsilon ) && ( fabs ( plane.n.y ) < epsilon ) &&
         ( fabs ( plane.n.z ) < epsilon ) )
    {
        return false;
    }

    magnitude = sqrt ( plane.n.x * plane.n.x + plane.n.y * plane.n.y + plane.n.z * plane.n.z );

    if ( magnitude < epsilon )
    {
        return false;
    }

    plane.n.x /= magnitude;
    plane.n.y /= magnitude;
    plane.n.z /= magnitude;

    centerOfMass.x /= ( double )GetNumberOfVertices ( );
    centerOfMass.y /= ( double )GetNumberOfVertices ( );
    centerOfMass.z /= ( double )GetNumberOfVertices ( );

    plane.d = -( centerOfMass.Dot ( plane.n ) );

    return true;
}