Пример #1
0
void CCAMERA::Reset()
{
    m_parametersChanged    = true;
    m_projectionMatrix     = glm::mat4( 1.0f );
    m_projectionMatrixInv  = glm::mat4( 1.0f );
    m_rotationMatrix       = glm::mat4( 1.0f );
    m_rotationMatrixAux    = glm::mat4( 1.0f );
    m_lastPosition         = wxPoint( 0, 0 );

    m_zoom                 = 1.0f;
    m_zoom_t0              = 1.0f;
    m_zoom_t1              = 1.0f;
    m_camera_pos           = m_camera_pos_init;
    m_camera_pos_t0        = m_camera_pos_init;
    m_camera_pos_t1        = m_camera_pos_init;
    m_lookat_pos           = m_board_lookat_pos_init;
    m_lookat_pos_t0        = m_board_lookat_pos_init;
    m_lookat_pos_t1        = m_board_lookat_pos_init;

    m_rotate_aux           = SFVEC3F( 0.0f );
    m_rotate_aux_t0        = SFVEC3F( 0.0f );
    m_rotate_aux_t1        = SFVEC3F( 0.0f );

    updateRotationMatrix();
    updateViewMatrix();
    m_viewMatrixInverse    = glm::inverse( m_viewMatrix );
    m_scr_nX.clear();
    m_scr_nY.clear();
    rebuildProjection();
}
SFVEC3F CSOLDERMASKNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const
{
    if( m_copper_normal_generator )
    {
        const SFVEC3F copperNormal = m_copper_normal_generator->Generate( aRay, aHitInfo );

        return copperNormal * SFVEC3F(0.10f);
    }
    else
        return SFVEC3F(0.0f);
}
CMATERIAL::CMATERIAL()
{
    m_ambientColor  = SFVEC3F( 0.2f, 0.2f, 0.2f );
    m_emissiveColor = SFVEC3F( 0.0f, 0.0f, 0.0f );
    m_specularColor = SFVEC3F( 1.0f, 1.0f, 1.0f );
    m_shinness      = 50.2f;
    m_transparency  = 0.0f; // completely opaque
    m_cast_shadows  = true;
    m_reflection    = 0.0f;

    m_normal_perturbator = NULL;
}
SFVEC3F CPOSTSHADER_SSAO::giColorCurve( const SFVEC3F &aColor ) const
{
    const SFVEC3F vec1 = SFVEC3F(1.0f);

    // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtKDEvKHgqMS4wKzEuMCkpK3gqMC4xIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiLTAuMDYyMTg0NjE1Mzg0NjE1NTA1IiwiMS4xNDI5ODQ2MTUzODQ2MTQ2IiwiLTAuMTI3MDk5OTk5OTk5OTk5NzciLCIxLjEzMjYiXX1d
    return vec1 - ( vec1 / (aColor + vec1) ) + aColor * SFVEC3F(0.10f);

    // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtKDEuMC8oeCoyLjArMS4wKSkreCowLjEiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC4wNjIxODQ2MTUzODQ2MTU1MDUiLCIxLjE0Mjk4NDYxNTM4NDYxNDYiLCItMC4xMjcwOTk5OTk5OTk5OTk3NyIsIjEuMTMyNiJdfV0-
    //return vec1 - ( vec1 / (aColor * SFVEC3F(2.0f) + vec1) ) + aColor * SFVEC3F(0.10f);

    //return aColor;
}
Пример #5
0
CCAMERA::CCAMERA( float aRangeScale )
{
    wxLogTrace( m_logTrace, wxT( "CCAMERA::CCAMERA" ) );

    m_range_scale           = aRangeScale;
    m_camera_pos_init       = SFVEC3F( 0.0f, 0.0f, -(aRangeScale * 2.0f ) );
    m_board_lookat_pos_init = SFVEC3F( 0.0f );
    m_windowSize            = SFVEC2I( 0, 0 );
    m_projectionType        = PROJECTION_PERSPECTIVE;
    m_interpolation_mode    = INTERPOLATION_BEZIER;

    Reset();
}
Пример #6
0
void CCAMERA::Reset_T1()
{
    m_camera_pos_t1        = m_camera_pos_init;
    m_zoom_t1              = 1.0f;
    m_rotate_aux_t1        = SFVEC3F( 0.0f );
    m_lookat_pos_t1        = m_board_lookat_pos_init;
}
CVCYLINDER::CVCYLINDER( SFVEC2F aCenterPoint,
                        float aZmin,
                        float aZmax,
                        float aRadius ) : COBJECT( OBJ3D_CYLINDER )
{
    m_center = aCenterPoint;
    m_radius_squared = aRadius * aRadius;
    m_inv_radius = 1.0f / aRadius;

    m_bbox.Set( SFVEC3F( aCenterPoint.x - aRadius,
                         aCenterPoint.y - aRadius,
                         aZmin ),
                SFVEC3F( aCenterPoint.x + aRadius,
                         aCenterPoint.y + aRadius,
                         aZmax ) );
    m_bbox.ScaleNextUp();
    m_centroid = m_bbox.GetCenter();
}
Пример #8
0
void CCAMERA::updateFrustum()
{
    // Update matrix and vectors
    m_viewMatrixInverse = glm::inverse( m_viewMatrix );

    m_right = glm::normalize( SFVEC3F( m_viewMatrixInverse *
                                       glm::vec4( SFVEC3F( 1.0, 0.0, 0.0 ), 0.0 ) ) );

    m_up    = glm::normalize( SFVEC3F( m_viewMatrixInverse *
                                       glm::vec4( SFVEC3F( 0.0, 1.0, 0.0 ), 0.0 ) ) );

    m_dir   = glm::normalize( SFVEC3F( m_viewMatrixInverse *
                                       glm::vec4( SFVEC3F( 0.0, 0.0, 1.0 ), 0.0 ) ) );

    m_pos   = SFVEC3F( m_viewMatrixInverse * glm::vec4( SFVEC3F( 0.0, 0.0, 0.0 ), 1.0 ) );


    /*
     * Frustum is a implementation based on a tutorial by
     * http://www.lighthouse3d.com/tutorials/view-frustum-culling/
     */

    // compute the centers of the near and far planes
    m_frustum.nc = m_pos - m_dir * m_frustum.nearD;
    m_frustum.fc = m_pos - m_dir * m_frustum.farD;

    // compute the 4 corners of the frustum on the near plane
    m_frustum.ntl = m_frustum.nc + m_up * m_frustum.nh - m_right * m_frustum.nw;
    m_frustum.ntr = m_frustum.nc + m_up * m_frustum.nh + m_right * m_frustum.nw;
    m_frustum.nbl = m_frustum.nc - m_up * m_frustum.nh - m_right * m_frustum.nw;
    m_frustum.nbr = m_frustum.nc - m_up * m_frustum.nh + m_right * m_frustum.nw;

    // compute the 4 corners of the frustum on the far plane
    m_frustum.ftl = m_frustum.fc + m_up * m_frustum.fh - m_right * m_frustum.fw;
    m_frustum.ftr = m_frustum.fc + m_up * m_frustum.fh + m_right * m_frustum.fw;
    m_frustum.fbl = m_frustum.fc - m_up * m_frustum.fh - m_right * m_frustum.fw;
    m_frustum.fbr = m_frustum.fc - m_up * m_frustum.fh + m_right * m_frustum.fw;

    // Reserve size for precalc values
    m_right_nX.resize( m_windowSize.x );
    m_up_nY.resize( m_windowSize.y );

    // Precalc X values for camera -> ray generation
    const SFVEC3F right_nw = m_right * m_frustum.nw;

    for( unsigned int x = 0; x < (unsigned int)m_windowSize.x; ++x )
        m_right_nX[x] = right_nw * m_scr_nX[x];

    // Precalc Y values for camera -> ray generation
    const SFVEC3F up_nh = m_up * m_frustum.nh;

    for( unsigned int y = 0; y < (unsigned int)m_windowSize.y; ++y )
        m_up_nY[y] = up_nh * m_scr_nY[y];
}
Пример #9
0
void CCAMERA::updateRotationMatrix()
{
    m_rotationMatrixAux = glm::rotate( glm::mat4( 1.0f ),
                                       m_rotate_aux.x,
                                       SFVEC3F( 1.0f, 0.0f, 0.0f ) );

    m_rotationMatrixAux = glm::rotate( m_rotationMatrixAux,
                                       m_rotate_aux.y,
                                       SFVEC3F( 0.0f, 1.0f, 0.0f ) );

    m_rotationMatrixAux = glm::rotate( m_rotationMatrixAux,
                                       m_rotate_aux.z,
                                       SFVEC3F( 0.0f, 0.0f, 1.0f ) );

    m_parametersChanged = true;

    updateViewMatrix();
    updateFrustum();
}
Пример #10
0
SFVEC3F CINFO3D_VISU::GetColor( EDA_COLOR_T aColor ) const
{
    const StructColors &colordata = g_ColorRefs[ColorGetBase( aColor )];

    static const float inv_255 = 1.0f / 255.0f;

    const float red     = colordata.m_Red   * inv_255;
    const float green   = colordata.m_Green * inv_255;
    const float blue    = colordata.m_Blue  * inv_255;

    return SFVEC3F( red, green, blue );
}
Пример #11
0
CROUNDSEG::CROUNDSEG( const CROUNDSEGMENT2D &aSeg2D,
                      float aZmin,
                      float aZmax ) : COBJECT( OBJ3D_ROUNDSEG ),
    m_segment( aSeg2D.m_segment )
{
    m_radius = aSeg2D.GetRadius();
    m_radius_squared = m_radius * m_radius;
    m_inv_radius = 1.0f / m_radius;

    m_plane_dir_left  = SFVEC3F( -m_segment.m_Dir.y,  m_segment.m_Dir.x, 0.0f );
    m_plane_dir_right = SFVEC3F(  m_segment.m_Dir.y, -m_segment.m_Dir.x, 0.0f );

    m_bbox.Reset();

    m_bbox.Set( SFVEC3F( m_segment.m_Start.x, m_segment.m_Start.y, aZmin),
                SFVEC3F( m_segment.m_End.x,   m_segment.m_End.y,   aZmax) );

    m_bbox.Set( m_bbox.Min() - SFVEC3F( m_radius, m_radius, 0.0f ),
                m_bbox.Max() + SFVEC3F( m_radius, m_radius, 0.0f ) );

    m_bbox.ScaleNextUp();
    m_centroid = m_bbox.GetCenter();

    m_center_left  = m_centroid + m_plane_dir_left  * m_radius;
    m_center_right = m_centroid + m_plane_dir_right * m_radius;

    m_seglen_over_two_squared = (m_segment.m_Length / 2.0f) *
                                (m_segment.m_Length / 2.0f);
}
Пример #12
0
SFVEC3F CCOPPERNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const
{
    if( m_board_normal_generator )
    {
        const SFVEC3F boardNormal = m_board_normal_generator->Generate( aRay, aHitInfo );

        SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;

        const float noise = (m_copper_perlin.noise( hitPos.x + Fast_RandFloat() * 0.1f,
                                                    hitPos.y ) - 0.5f) * 2.0f;

        float scratchPattern = (m_copper_perlin.noise( hitPos.x / 100.0f, hitPos.y  * 20.0f ) - 0.5f);

        scratchPattern = glm::clamp( scratchPattern * 5.0f, -1.0f, 1.0f );

        const float x = glm::clamp( (noise + scratchPattern)           * 0.04f, -0.10f, 0.10f );
        const float y = glm::clamp( (noise + (noise * scratchPattern)) * 0.04f, -0.10f, 0.10f );

        return SFVEC3F( x, y, 0.0f ) + boardNormal * 0.85f;
    }
    else
        return SFVEC3F(0.0f);
}
Пример #13
0
SFVEC3F CPLASTICSHINENORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const
{
    SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;

    const float noise1 = (m_perlin.noise( hitPos.x,
                                          hitPos.y,
                                          hitPos.z ) - 0.5f);

    const float noise2 = (m_perlin.noise( hitPos.x * 3.0f,
                                          hitPos.y * 3.0f,
                                          hitPos.z * 3.0f ) - 0.5f);

    return SFVEC3F( noise1 * 0.09f + noise2 * 0.08f );
}
Пример #14
0
SFVEC3F CBOARDNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const
{
    const SFVEC3F &hitPos = aHitInfo.m_HitPoint;

    // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJzaW4oc2luKHNpbih4KSoxLjkpKjEuNSkiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC45NjIxMDU3MDgwNzg1MjYyIiwiNy45NzE0MjYyNjc2MDE0MyIsIi0yLjUxNzYyMDM1MTQ4MjQ0OSIsIjIuOTc5OTM3Nzg3Mzk3NTMwMyJdLCJzaXplIjpbNjQ2LDM5Nl19XQ--

    // Implement a texture as the "measling crazing blistering" method of FR4

    const float x = (glm::sin(glm::sin( glm::sin( hitPos.x * m_scale ) * 1.9f ) * 1.5f ) + 0.0f) * 0.10f;
    const float y = (glm::sin(glm::sin( glm::sin( hitPos.y * m_scale ) * 1.9f ) * 1.5f ) + 0.0f) * 0.10f;
    const float z = glm::sin( 2.0f * hitPos.z * m_scale + Fast_RandFloat() * 1.0f ) * 0.2f;

    return SFVEC3F( x, y, z );
}
Пример #15
0
SFVEC3F CINFO3D_VISU::GetLayerColor( LAYER_ID aLayerId ) const
{
    wxASSERT( aLayerId < LAYER_ID_COUNT );

    const EDA_COLOR_T color = g_ColorsSettings.GetLayerColor( aLayerId );
    const StructColors &colordata = g_ColorRefs[ColorGetBase( color )];

    static const float inv_255 = 1.0f / 255.0f;

    const float red     = colordata.m_Red   * inv_255;
    const float green   = colordata.m_Green * inv_255;
    const float blue    = colordata.m_Blue  * inv_255;

    return SFVEC3F( red, green, blue );
}
void C3D_RENDER_OGL_LEGACY::add_triangle_top_bot( CLAYER_TRIANGLES *aDst, const SFVEC2F &v0, const SFVEC2F &v1, const SFVEC2F &v2, float top, float bot )
{
    aDst->m_layer_bot_triangles->AddTriangle( SFVEC3F( v0.x, v0.y, bot ),
                                              SFVEC3F( v1.x, v1.y, bot ),
                                              SFVEC3F( v2.x, v2.y, bot ) );

    aDst->m_layer_top_triangles->AddTriangle( SFVEC3F( v2.x, v2.y, top ),
                                              SFVEC3F( v1.x, v1.y, top ),
                                              SFVEC3F( v0.x, v0.y, top ) );
}
Пример #17
0
SFVEC3F CPLASTICNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const
{
        SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;

        const float noise1 = (m_perlin.noise( hitPos.x,
                                              hitPos.y,
                                              hitPos.z ) - 0.5f);

        const float noise2 = (m_perlin.noise( hitPos.x * 5.0f,
                                              hitPos.y * 5.0f,
                                              hitPos.z * 5.0f ) - 0.5f);

        const float noise3 = (m_perlin.noise( hitPos.x * 10.0f + Fast_RandFloat() * 0.10f,
                                              hitPos.y * 10.0f + Fast_RandFloat() * 0.10f,
                                              hitPos.z * 10.0f + Fast_RandFloat() * 0.10f ) - 0.5f);

        return SFVEC3F( noise1 * 0.08f + noise2 * 0.10f + noise3 * 0.30f );
}
Пример #18
0
SFVEC3F CMETALBRUSHEDNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const
{
    SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;

    SFVEC3F hitPosRelative = hitPos - glm::floor( hitPos );

    const float noiseX = (m_perlin.noise( hitPos.x * (60.0f),
                                          hitPos.y * 1.0f,
                                          hitPos.z * 1.0f ) - 0.5f);

    const float noiseY = (m_perlin.noise( hitPos.x * 1.0f,
                                          hitPos.y * (60.0f),
                                          hitPos.z * 1.0f ) - 0.5f);

    const float noise2 = (m_perlin.noise( hitPos.x * 1.0f,
                                          hitPos.y * 1.0f,
                                          hitPos.z * 1.0f ) - 0.5f);

    const float noise3X = (m_perlin.noise( hitPos.x * (80.0f + noise2 * 0.5f),
                                           hitPos.y * 0.5f + Fast_RandFloat() * 0.05f,
                                           hitPos.z * 0.5f ) - 0.5f );

    const float noise3Y = (m_perlin.noise( hitPos.x * 0.5f + Fast_RandFloat() * 0.05f,
                                           hitPos.y * (80.0f + noise2 * 0.5f),
                                           hitPos.z * 0.5f ) - 0.5f );

    // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgtZmxvb3IoeCkpK3Npbih4KSleMyIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi02LjcxNDAwMDAxOTAzMDA3NyIsIjcuMjQ0NjQzNjkyOTY5NzM5IiwiLTMuMTU1NTUyNjAxNDUyNTg4IiwiNS40MzQzODE5OTA1NDczMDY1Il0sInNpemUiOls2NDQsMzk0XX1d
    // ((x - floor(x))+sin(x))^3

    float sawX = (hitPosRelative.x + glm::sin(10.0f * hitPos.x + 5.0f * noise2 + Fast_RandFloat() ) );
          sawX = sawX * sawX * sawX;

    float sawY = (hitPosRelative.y + glm::sin(10.0f * hitPos.y + 5.0f * noise2 + Fast_RandFloat() ) );
          sawY = sawY * sawY * sawY;

    float xOut = sawX * noise3X * 0.07f + noiseX * 0.25f + noise3X * 0.07f;
    float yOut = sawY * noise3Y * 0.07f + noiseY * 0.25f + noise3Y * 0.07f;

    const float outLowFreqNoise = noise2 * 0.005f;

    return SFVEC3F( xOut + outLowFreqNoise,
                    yOut + outLowFreqNoise,
                    0.0f + outLowFreqNoise );
}
void C3D_RENDER_OGL_LEGACY::generate_cylinder( const SFVEC2F &aCenter,
                                               float aInnerRadius,
                                               float aOuterRadius,
                                               float aZtop,
                                               float aZbot,
                                               unsigned int aNr_sides_per_circle,
                                               CLAYER_TRIANGLES *aDstLayer )
{
    std::vector< SFVEC2F > innerContour;
    std::vector< SFVEC2F > outerContour;

    generate_ring_contour( aCenter,
                           aInnerRadius,
                           aOuterRadius,
                           aNr_sides_per_circle,
                           innerContour,
                           outerContour,
                           false );

    for( unsigned int i = 0; i < ( innerContour.size() - 1 ); ++i )
    {
        const SFVEC2F &vi0 = innerContour[i + 0];
        const SFVEC2F &vi1 = innerContour[i + 1];
        const SFVEC2F &vo0 = outerContour[i + 0];
        const SFVEC2F &vo1 = outerContour[i + 1];

        aDstLayer->m_layer_top_triangles->AddQuad( SFVEC3F( vi1.x, vi1.y, aZtop ),
                                                   SFVEC3F( vi0.x, vi0.y, aZtop ),
                                                   SFVEC3F( vo0.x, vo0.y, aZtop ),
                                                   SFVEC3F( vo1.x, vo1.y, aZtop ) );

        aDstLayer->m_layer_bot_triangles->AddQuad( SFVEC3F( vi1.x, vi1.y, aZbot ),
                                                   SFVEC3F( vo1.x, vo1.y, aZbot ),
                                                   SFVEC3F( vo0.x, vo0.y, aZbot ),
                                                   SFVEC3F( vi0.x, vi0.y, aZbot ) );
    }

    aDstLayer->AddToMiddleContourns( outerContour, aZbot, aZtop, true );
    aDstLayer->AddToMiddleContourns( innerContour, aZbot, aZtop, false );
}
void C3D_RENDER_OGL_LEGACY::add_object_to_triangle_layer( const CRING2D * aRing,
                                                          CLAYER_TRIANGLES *aDstLayer,
                                                          float aZtop,
                                                          float aZbot )
{
    const SFVEC2F &center = aRing->GetCenter();
    const float inner = aRing->GetInnerRadius();
    const float outer = aRing->GetOuterRadius();

    std::vector< SFVEC2F > innerContour;
    std::vector< SFVEC2F > outerContour;

    generate_ring_contour( center,
                           inner,
                           outer,
                           m_settings.GetNrSegmentsCircle( outer * 2.0f ),
                           innerContour,
                           outerContour,
                           false );

    // This will add the top and bot quads that will form the approximated ring

    for( unsigned int i = 0; i < ( innerContour.size() - 1 ); ++i )
    {
        const SFVEC2F &vi0 = innerContour[i + 0];
        const SFVEC2F &vi1 = innerContour[i + 1];
        const SFVEC2F &vo0 = outerContour[i + 0];
        const SFVEC2F &vo1 = outerContour[i + 1];

        aDstLayer->m_layer_top_triangles->AddQuad( SFVEC3F( vi1.x, vi1.y, aZtop ),
                                                   SFVEC3F( vi0.x, vi0.y, aZtop ),
                                                   SFVEC3F( vo0.x, vo0.y, aZtop ),
                                                   SFVEC3F( vo1.x, vo1.y, aZtop ) );

        aDstLayer->m_layer_bot_triangles->AddQuad( SFVEC3F( vi1.x, vi1.y, aZbot ),
                                                   SFVEC3F( vo1.x, vo1.y, aZbot ),
                                                   SFVEC3F( vo0.x, vo0.y, aZbot ),
                                                   SFVEC3F( vi0.x, vi0.y, aZbot ) );
    }
}
bool CVCYLINDER::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
{
    // Based on:
    // http://www.cs.utah.edu/~lha/Code%206620%20/Ray4/Cylinder.cpp
    // Ray-sphere intersection: geometric
    // /////////////////////////////////////////////////////////////////////////
    const double OCx_Start = aRay.m_Origin.x - m_center.x;
    const double OCy_Start = aRay.m_Origin.y - m_center.y;

    const double p_dot_p = OCx_Start * OCx_Start + OCy_Start * OCy_Start;

    const double a = (double)aRay.m_Dir.x * (double)aRay.m_Dir.x +
                     (double)aRay.m_Dir.y * (double)aRay.m_Dir.y;
    const double b = (double)aRay.m_Dir.x * (double)OCx_Start +
                     (double)aRay.m_Dir.y * (double)OCy_Start;
    const double c = p_dot_p - m_radius_squared;

    const float delta = (float)(b * b - a * c);

    bool hitResult = false;

    if( delta > FLT_EPSILON )
    {
        const float inv_a = 1.0 / a;

        const float sdelta = sqrtf( delta );
        const float t = (-b - sdelta) * inv_a;
        const float z = aRay.m_Origin.z + t * aRay.m_Dir.z;

        if( (z >= m_bbox.Min().z) &&
            (z <= m_bbox.Max().z) )
        {
            if( t < aHitInfo.m_tHit )
            {
                hitResult = true;
                aHitInfo.m_tHit = t;
            }
        }

        if( !hitResult )
        {
            const float t1 = (-b + sdelta) * inv_a;
            const float z1 = aRay.m_Origin.z + t1 * aRay.m_Dir.z;

            if( (z1 > m_bbox.Min().z ) &&
                (z1 < m_bbox.Max().z ) )
            {
                if( t1 < aHitInfo.m_tHit )
                {
                    hitResult = true;
                    aHitInfo.m_tHit = t1;
                }
            }
        }
    }

    if( hitResult )
    {
        aHitInfo.m_HitPoint = aRay.at( aHitInfo.m_tHit );

        const SFVEC2F hitPoint2D = SFVEC2F( aHitInfo.m_HitPoint.x,
                                            aHitInfo.m_HitPoint.y );

        aHitInfo.m_HitNormal = SFVEC3F( -(hitPoint2D.x - m_center.x) * m_inv_radius,
                                        -(hitPoint2D.y - m_center.y) * m_inv_radius,
                                        0.0f );

        m_material->PerturbeNormal( aHitInfo.m_HitNormal, aRay, aHitInfo );

        aHitInfo.pHitObject = this;
    }

    return hitResult;
}
SFVEC3F CPOSTSHADER_SSAO::Shade( const SFVEC2I &aShaderPos ) const
{
    // Test source code
    //return SFVEC3F( GetShadowFactorAt( aShaderPos ) );
    //return GetColorAt( aShaderPos );
    //return SFVEC3F( 1.0f - GetDepthNormalizedAt( aShaderPos ) );
    //return SFVEC3F( (1.0f / GetDepthAt( aShaderPos )) * 0.5f );
    //return SFVEC3F( 1.0f - GetDepthNormalizedAt( aShaderPos ) +
    //                (1.0f / GetDepthAt( aShaderPos )) * 0.5f );

#if 1
    float cdepth = GetDepthAt( aShaderPos );

    if( cdepth > FLT_EPSILON )
    {

        float cNormalizedDepth = GetDepthNormalizedAt( aShaderPos );

        wxASSERT( cNormalizedDepth <= 1.0f );
        wxASSERT( cNormalizedDepth >= 0.0f );

        cdepth = ( (1.50f - cNormalizedDepth) +
                   ( 1.0f - (1.0f / (cdepth + 1.0f) ) ) * 2.5f );

        // Test source code
        //cdepth = ( (1.75f - cNormalizedDepth) + (1.0f / cdepth) * 2.0f );
        //cdepth = 1.5f - cNormalizedDepth;
        //cdepth = (1.0f / cdepth) * 2.0f;

        // read current normal,position and color.
        const SFVEC3F n = GetNormalAt( aShaderPos );
        const SFVEC3F p = GetPositionAt( aShaderPos );
        //const SFVEC3F col = GetColorAt( aShaderPos );

        const float shadowFactor = GetShadowFactorAt( aShaderPos );

        // initialize variables:
        float ao = 0.0f;
        SFVEC3F gi = SFVEC3F(0.0f);

        // This calculated the "window range" of the shader. So it will get
        // more or less sparsed samples
        const int incx = 3;
        const int incy = 3;

        //3 rounds of 8 samples each.
        for( unsigned int i = 0; i < 3; ++i )
        {
            static const int mask[3] = { 0x01, 0x03, 0x03 };
            const int pw = 1 + (Fast_rand() & mask[i]);
            const int ph = 1 + (Fast_rand() & mask[i]);

            const int npw = (int)((pw + incx * i) * cdepth );
            const int nph = (int)((ph + incy * i) * cdepth );

            const SFVEC3F ddiff  = GetPositionAt( aShaderPos + SFVEC2I( npw, nph ) ) - p;
            const SFVEC3F ddiff2 = GetPositionAt( aShaderPos + SFVEC2I( npw,-nph ) ) - p;
            const SFVEC3F ddiff3 = GetPositionAt( aShaderPos + SFVEC2I(-npw, nph ) ) - p;
            const SFVEC3F ddiff4 = GetPositionAt( aShaderPos + SFVEC2I(-npw,-nph ) ) - p;
            const SFVEC3F ddiff5 = GetPositionAt( aShaderPos + SFVEC2I(   0, nph ) ) - p;
            const SFVEC3F ddiff6 = GetPositionAt( aShaderPos + SFVEC2I(   0,-nph ) ) - p;
            const SFVEC3F ddiff7 = GetPositionAt( aShaderPos + SFVEC2I( npw,   0 ) ) - p;
            const SFVEC3F ddiff8 = GetPositionAt( aShaderPos + SFVEC2I(-npw,   0 ) ) - p;

            ao+=  aoFF( aShaderPos, ddiff , n,  npw, nph, shadowFactor );
            ao+=  aoFF( aShaderPos, ddiff2, n,  npw,-nph, shadowFactor );
            ao+=  aoFF( aShaderPos, ddiff3, n, -npw, nph, shadowFactor );
            ao+=  aoFF( aShaderPos, ddiff4, n, -npw,-nph, shadowFactor );
            ao+=  aoFF( aShaderPos, ddiff5, n,    0, nph, shadowFactor );
            ao+=  aoFF( aShaderPos, ddiff6, n,    0,-nph, shadowFactor );
            ao+=  aoFF( aShaderPos, ddiff7, n,  npw,   0, shadowFactor );
            ao+=  aoFF( aShaderPos, ddiff8, n, -npw,   0, shadowFactor );

            gi+=  giFF( aShaderPos, ddiff , n, npw,  nph) *
                    giColorCurve( GetColorAt( aShaderPos + SFVEC2I(  npw, nph ) ) );
            gi+=  giFF( aShaderPos, ddiff2, n, npw, -nph) *
                    giColorCurve( GetColorAt( aShaderPos + SFVEC2I(  npw,-nph ) ) );
            gi+=  giFF( aShaderPos, ddiff3, n,-npw,  nph) *
                    giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw, nph ) ) );
            gi+=  giFF( aShaderPos, ddiff4, n,-npw, -nph) *
                    giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw,-nph ) ) );
            gi+=  giFF( aShaderPos, ddiff5, n, 0.0f, nph) *
                    giColorCurve( GetColorAt( aShaderPos + SFVEC2I(    0, nph ) ) );
            gi+=  giFF( aShaderPos, ddiff6, n, 0.0f,-nph) *
                    giColorCurve( GetColorAt( aShaderPos + SFVEC2I(    0,-nph ) ) );
            gi+=  giFF( aShaderPos, ddiff7, n, npw, 0.0f) *
                    giColorCurve( GetColorAt( aShaderPos + SFVEC2I(  npw,    0) ) );
            gi+=  giFF( aShaderPos, ddiff8, n,-npw, 0.0f) *
                    giColorCurve( GetColorAt( aShaderPos + SFVEC2I( -npw,    0) ) );
        }
        ao = (ao / 24.0f) + 0.0f; // Apply a bias for the ambient oclusion
        gi = (gi * 5.0f / 24.0f); // Apply a bias for the global illumination

        //return SFVEC3F(ao);
        return SFVEC3F( SFVEC3F(ao) - gi);

        // Test source code
        //return SFVEC3F( col );
        //return SFVEC3F( col - SFVEC3F(ao) + gi * 5.0f );
        //return SFVEC3F( SFVEC3F(1.0f) - SFVEC3F(ao) + gi * 5.0f );
        //return SFVEC3F(cdepth);
        //return 1.0f - SFVEC3F(ao);
        //return SFVEC3F(ao);
    }
    else
        return SFVEC3F(0.0f);
#endif
}
Пример #23
0
 BVHPrimitiveInfo()
 {
     primitiveNumber = 0;
     bounds.Reset();
     centroid = SFVEC3F( 0.0f );
 }
Пример #24
0
BVHBuildNode *CBVH_PBRT::HLBVHBuild( const std::vector<BVHPrimitiveInfo> &primitiveInfo,
                                     int *totalNodes,
                                     CONST_VECTOR_OBJECT &orderedPrims )
{
    // Compute bounding box of all primitive centroids
    CBBOX bounds;
    bounds.Reset();

    for( unsigned int i = 0; i < primitiveInfo.size(); ++i )
        bounds.Union( primitiveInfo[i].centroid );

    // Compute Morton indices of primitives
    std::vector<MortonPrimitive> mortonPrims( primitiveInfo.size() );

    for( int i = 0; i < (int)primitiveInfo.size(); ++i )
    {
        // Initialize _mortonPrims[i]_ for _i_th primitive
        const int mortonBits  = 10;
        const int mortonScale = 1 << mortonBits;

        wxASSERT( primitiveInfo[i].primitiveNumber < (int)primitiveInfo.size() );

        mortonPrims[i].primitiveIndex = primitiveInfo[i].primitiveNumber;

        const SFVEC3F centroidOffset = bounds.Offset( primitiveInfo[i].centroid );

        wxASSERT( (centroidOffset.x >= 0.0f) && (centroidOffset.x <= 1.0f) );
        wxASSERT( (centroidOffset.y >= 0.0f) && (centroidOffset.y <= 1.0f) );
        wxASSERT( (centroidOffset.z >= 0.0f) && (centroidOffset.z <= 1.0f) );

        mortonPrims[i].mortonCode = EncodeMorton3( centroidOffset *
                                                   SFVEC3F( (float)mortonScale ) );
    }

    // Radix sort primitive Morton indices
    RadixSort( &mortonPrims );

    // Create LBVH treelets at bottom of BVH

    // Find intervals of primitives for each treelet
    std::vector<LBVHTreelet> treeletsToBuild;

    for( int start = 0, end = 1; end <= (int)mortonPrims.size(); ++end )
    {
        const uint32_t mask = 0b00111111111111000000000000000000;

        if( (end == (int)mortonPrims.size()) ||
            ( (mortonPrims[start].mortonCode & mask) !=
              (mortonPrims[end].mortonCode & mask) ) )
        {
            // Add entry to _treeletsToBuild_ for this treelet
            const int numPrimitives = end - start;
            const int maxBVHNodes = 2 * numPrimitives;

            // !TODO: implement a memory arena
            BVHBuildNode *nodes = static_cast<BVHBuildNode *>( _mm_malloc( maxBVHNodes *
                                                                           sizeof( BVHBuildNode ),
                                                                           L1_CACHE_LINE_SIZE ) );

            m_addresses_pointer_to_mm_free.push_back( nodes );

            for( int i = 0; i < maxBVHNodes; ++i )
            {
                nodes[i].bounds.Reset();
                nodes[i].firstPrimOffset = 0;
                nodes[i].nPrimitives = 0;
                nodes[i].splitAxis = 0;
                nodes[i].children[0] = NULL;
                nodes[i].children[1] = NULL;
            }

            LBVHTreelet tmpTreelet;

            tmpTreelet.startIndex = start;
            tmpTreelet.numPrimitives = numPrimitives;
            tmpTreelet.buildNodes = nodes;

            treeletsToBuild.push_back( tmpTreelet );

            start = end;
        }
    }

    // Create LBVHs for treelets in parallel
    int atomicTotal = 0;
    int orderedPrimsOffset = 0;

    orderedPrims.resize( m_primitives.size() );

    for( int index = 0; index < (int)treeletsToBuild.size(); ++index )
    {
        // Generate _index_th LBVH treelet
        int nodesCreated = 0;
        const int firstBit = 29 - 12;

        LBVHTreelet &tr = treeletsToBuild[index];

        wxASSERT( tr.startIndex < (int)mortonPrims.size() );

        tr.buildNodes = emitLBVH( tr.buildNodes,
                                  primitiveInfo,
                                  &mortonPrims[tr.startIndex],
                                  tr.numPrimitives,
                                  &nodesCreated,
                                  orderedPrims,
                                  &orderedPrimsOffset,
                                  firstBit );

        atomicTotal += nodesCreated;
    }

    *totalNodes = atomicTotal;

    // Initialize _finishedTreelets_ with treelet root node pointers
    std::vector<BVHBuildNode *> finishedTreelets;
    finishedTreelets.reserve( treeletsToBuild.size() );

    for( int index = 0; index < (int)treeletsToBuild.size(); ++index )
        finishedTreelets.push_back( treeletsToBuild[index].buildNodes );

    // Create and return SAH BVH from LBVH treelets
    return buildUpperSAH( finishedTreelets,
                          0,
                          finishedTreelets.size(),
                          totalNodes );
}
void C3D_RENDER_OGL_LEGACY::add_object_to_triangle_layer( const CFILLEDCIRCLE2D * aFilledCircle,
                                                          CLAYER_TRIANGLES *aDstLayer,
                                                          float aZtop,
                                                          float aZbot )
{
    const SFVEC2F &center = aFilledCircle->GetCenter();
    const float radius = aFilledCircle->GetRadius() *
                         2.0f; // Double because the render triangle

    // This is a small adjustment to the circle texture
    const float texture_factor = (8.0f / (float)SIZE_OF_CIRCLE_TEXTURE) + 1.0f;
    const float f = (sqrtf(2.0f) / 2.0f) * radius * texture_factor;

    // Top and Bot segments ends are just triangle semi-circles, so need to add
    // it in duplicated
    aDstLayer->m_layer_top_segment_ends->AddTriangle( SFVEC3F( center.x + f, center.y, aZtop ),
                                                      SFVEC3F( center.x - f, center.y, aZtop ),
                                                      SFVEC3F( center.x,
                                                               center.y - f, aZtop ) );

    aDstLayer->m_layer_top_segment_ends->AddTriangle( SFVEC3F( center.x - f, center.y, aZtop ),
                                                      SFVEC3F( center.x + f, center.y, aZtop ),
                                                      SFVEC3F( center.x,
                                                               center.y + f, aZtop ) );

    aDstLayer->m_layer_bot_segment_ends->AddTriangle( SFVEC3F( center.x - f, center.y, aZbot ),
                                                      SFVEC3F( center.x + f, center.y, aZbot ),
                                                      SFVEC3F( center.x,
                                                               center.y - f, aZbot ) );

    aDstLayer->m_layer_bot_segment_ends->AddTriangle( SFVEC3F( center.x + f, center.y, aZbot ),
                                                      SFVEC3F( center.x - f, center.y, aZbot ),
                                                      SFVEC3F( center.x,
                                                               center.y + f, aZbot ) );
}
void C3D_RENDER_OGL_LEGACY::add_object_to_triangle_layer( const CROUNDSEGMENT2D * aSeg,
                                                          CLAYER_TRIANGLES *aDstLayer,
                                                          float aZtop,
                                                          float aZbot )
{
    const SFVEC2F leftStart   = aSeg->GetLeftStar();
    const SFVEC2F leftEnd     = aSeg->GetLeftEnd();
    const SFVEC2F leftDir     = aSeg->GetLeftDir();

    const SFVEC2F rightStart  = aSeg->GetRightStar();
    const SFVEC2F rightEnd    = aSeg->GetRightEnd();
    const SFVEC2F rightDir    = aSeg->GetRightDir();
    const float   radius      = aSeg->GetRadius();

    const SFVEC2F start       = aSeg->GetStart();
    const SFVEC2F end         = aSeg->GetEnd();

    const float texture_factor = (12.0f / (float)SIZE_OF_CIRCLE_TEXTURE) + 1.0f;
    const float texture_factorF= ( 6.0f / (float)SIZE_OF_CIRCLE_TEXTURE) + 1.0f;

    const float radius_of_the_square = sqrtf( aSeg->GetRadiusSquared() * 2.0f );
    const float radius_triangle_factor = (radius_of_the_square - radius) / radius;

    const SFVEC2F factorS = SFVEC2F( -rightDir.y * radius * radius_triangle_factor,
                                      rightDir.x * radius * radius_triangle_factor );

    const SFVEC2F factorE = SFVEC2F( -leftDir.y  * radius * radius_triangle_factor,
                                      leftDir.x  * radius * radius_triangle_factor );

    // Top end segment triangles (semi-circles)
    aDstLayer->m_layer_top_segment_ends->AddTriangle(
                SFVEC3F( rightEnd.x  + texture_factor * factorS.x,
                         rightEnd.y  + texture_factor * factorS.y,
                         aZtop ),
                SFVEC3F( leftStart.x + texture_factor * factorE.x,
                         leftStart.y + texture_factor * factorE.y,
                         aZtop ),
                SFVEC3F( start.x - texture_factorF * leftDir.x * radius * sqrtf( 2.0f ),
                         start.y - texture_factorF * leftDir.y * radius * sqrtf( 2.0f ),
                         aZtop ) );

    aDstLayer->m_layer_top_segment_ends->AddTriangle(
                SFVEC3F( leftEnd.x    + texture_factor * factorE.x,
                         leftEnd.y    + texture_factor * factorE.y, aZtop ),
                SFVEC3F( rightStart.x + texture_factor * factorS.x,
                         rightStart.y + texture_factor * factorS.y, aZtop ),
                SFVEC3F( end.x - texture_factorF * rightDir.x * radius * sqrtf( 2.0f ),
                         end.y - texture_factorF * rightDir.y * radius * sqrtf( 2.0f ),
                         aZtop ) );

    // Bot end segment triangles (semi-circles)
    aDstLayer->m_layer_bot_segment_ends->AddTriangle(
                SFVEC3F( leftStart.x + texture_factor * factorE.x,
                         leftStart.y + texture_factor * factorE.y,
                         aZbot ),
                SFVEC3F( rightEnd.x  + texture_factor * factorS.x,
                         rightEnd.y  + texture_factor * factorS.y,
                         aZbot ),
                SFVEC3F( start.x - texture_factorF * leftDir.x * radius * sqrtf( 2.0f ),
                         start.y - texture_factorF * leftDir.y * radius * sqrtf( 2.0f ),
                         aZbot ) );

    aDstLayer->m_layer_bot_segment_ends->AddTriangle(
                SFVEC3F( rightStart.x + texture_factor * factorS.x,
                         rightStart.y + texture_factor * factorS.y, aZbot ),
                SFVEC3F( leftEnd.x    + texture_factor * factorE.x,
                         leftEnd.y    + texture_factor * factorE.y, aZbot ),
                SFVEC3F( end.x - texture_factorF * rightDir.x * radius * sqrtf( 2.0f ),
                         end.y - texture_factorF * rightDir.y * radius * sqrtf( 2.0f ),
                         aZbot ) );

    // Segment top and bot planes
    aDstLayer->m_layer_top_triangles->AddQuad(
                SFVEC3F( rightEnd.x,   rightEnd.y,   aZtop ),
                SFVEC3F( rightStart.x, rightStart.y, aZtop ),
                SFVEC3F( leftEnd.x,    leftEnd.y,    aZtop ),
                SFVEC3F( leftStart.x,  leftStart.y,  aZtop ) );

    aDstLayer->m_layer_bot_triangles->AddQuad(
                SFVEC3F( rightEnd.x,   rightEnd.y,   aZbot ),
                SFVEC3F( leftStart.x,  leftStart.y,  aZbot ),
                SFVEC3F( leftEnd.x,    leftEnd.y,    aZbot ),
                SFVEC3F( rightStart.x, rightStart.y, aZbot ) );
}
Пример #27
0
CINFO3D_VISU::CINFO3D_VISU() :
    m_currentCamera( m_trackBallCamera ),
    m_trackBallCamera( RANGE_SCALE_3D )
{
    wxLogTrace( m_logTrace, wxT( "CINFO3D_VISU::CINFO3D_VISU" ) );

    m_board = NULL;
    m_3d_model_manager = NULL;
    m_3D_grid_type = GRID3D_NONE;
    m_drawFlags.resize( FL_LAST, false );

    m_render_engine = RENDER_ENGINE_OPENGL_LEGACY;
    m_material_mode = MATERIAL_MODE_NORMAL;

    m_boardPos = wxPoint();
    m_boardSize = wxSize();
    m_boardCenter = SFVEC3F();

    m_boardBoudingBox.Reset();
    m_board2dBBox3DU.Reset();

    m_layers_container2D.clear();
    m_layers_holes2D.clear();
    m_through_holes_inner.Clear();
    m_through_holes_outer.Clear();

    m_copperLayersCount = -1;
    m_epoxyThickness3DU = 0.0f;
    m_copperThickness3DU  = 0.0f;
    m_nonCopperLayerThickness3DU = 0.0f;
    m_biuTo3Dunits = 1.0;

    m_stats_nr_tracks = 0;
    m_stats_nr_vias = 0;
    m_stats_via_med_hole_diameter = 0.0f;
    m_stats_nr_holes = 0;
    m_stats_hole_med_diameter = 0.0f;
    m_stats_track_med_width = 0.0f;

    m_calc_seg_min_factor3DU = 0.0f;
    m_calc_seg_max_factor3DU = 0.0f;


    memset( m_layerZcoordTop, 0, sizeof( m_layerZcoordTop ) );
    memset( m_layerZcoordBottom, 0, sizeof( m_layerZcoordBottom ) );

    SetFlag( FL_USE_REALISTIC_MODE, true );
    SetFlag( FL_MODULE_ATTRIBUTES_NORMAL, true );
    SetFlag( FL_SHOW_BOARD_BODY, true );
    SetFlag( FL_RENDER_OPENGL_COPPER_THICKNESS, true );
    SetFlag( FL_MODULE_ATTRIBUTES_NORMAL, true );
    SetFlag( FL_MODULE_ATTRIBUTES_NORMAL_INSERT, true );
    SetFlag( FL_MODULE_ATTRIBUTES_VIRTUAL, true );
    SetFlag( FL_ZONE, true );
    SetFlag( FL_SILKSCREEN, true );
    SetFlag( FL_SOLDERMASK, true );

    m_BgColorBot        = SFVEC3D( 0.4, 0.4, 0.5 );
    m_BgColorTop        = SFVEC3D( 0.8, 0.8, 0.9 );
    m_BoardBodyColor    = SFVEC3D( 0.4, 0.4, 0.5 );
    m_SolderMaskColor   = SFVEC3D( 0.1, 0.2, 0.1 );
    m_SolderPasteColor  = SFVEC3D( 0.4, 0.4, 0.4 );
    m_SilkScreenColor   = SFVEC3D( 0.9, 0.9, 0.9 );
    m_CopperColor       = SFVEC3D( 0.75, 0.61, 0.23 );
}
void C3D_MODEL_VIEWER::OnPaint( wxPaintEvent &event )
{
    wxPaintDC( this );

    // SwapBuffer requires the window to be shown before calling
    if( !IsShownOnScreen() )
    {
        wxLogTrace( m_logTrace, wxT( "C3D_MODEL_VIEWER::OnPaint !IsShown" ) );
        return;
    }

    // "Makes the OpenGL state that is represented by the OpenGL rendering
    //  context context current, i.e. it will be used by all subsequent OpenGL calls.
    //  This function may only be called when the window is shown on screen"
    GL_CONTEXT_MANAGER::Get().LockCtx( m_glRC, this );

    // Set the OpenGL viewport according to the client size of this canvas.
    // This is done here rather than in a wxSizeEvent handler because our
    // OpenGL rendering context (and thus viewport setting) is used with
    // multiple canvases: If we updated the viewport in the wxSizeEvent
    // handler, changing the size of one canvas causes a viewport setting that
    // is wrong when next another canvas is repainted.
    wxSize clientSize = GetClientSize();

    if( !m_ogl_initialized )
    {
        m_ogl_initialized = true;
        ogl_initialize();
    }

    if( m_reload_is_needed )
    {
        wxLogTrace( m_logTrace, wxT( "C3D_MODEL_VIEWER::OnPaint m_reload_is_needed" ) );

        m_reload_is_needed = false;
        m_ogl_3dmodel = new C_OGL_3DMODEL( *m_3d_model );

        // It convert a model as it was a board, so get the max size dimension of the board
        // and compute the conversion scale
        m_BiuTo3Dunits = (double)RANGE_SCALE_3D / ((double)m_ogl_3dmodel->GetBBox().GetMaxDimension() * UNITS3D_TO_UNITSPCB);
    }

    glViewport( 0, 0, clientSize.x, clientSize.y );

    m_trackBallCamera.SetCurWindowSize( clientSize );

    // clear color and depth buffers
    // /////////////////////////////////////////////////////////////////////////
    glEnable( GL_DEPTH_TEST );

    glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
    glClearDepth( 1.0f );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    // Set projection and modelview matrixes
    // /////////////////////////////////////////////////////////////////////////
    glMatrixMode( GL_PROJECTION );
    glLoadMatrixf( glm::value_ptr( m_trackBallCamera.GetProjectionMatrix() ) );

    glMatrixMode( GL_MODELVIEW );
    glLoadMatrixf( glm::value_ptr( m_trackBallCamera.GetViewMatrix() ) );

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    // Render Model
    if( m_ogl_3dmodel )
    {
        glPushMatrix();

        double modelunit_to_3d_units_factor = m_BiuTo3Dunits * UNITS3D_TO_UNITSPCB;

        glScaled( modelunit_to_3d_units_factor, modelunit_to_3d_units_factor, modelunit_to_3d_units_factor);

        // Center model in the render viewport
        const SFVEC3F model_center = m_ogl_3dmodel->GetBBox().GetCenter();
        glTranslatef( -model_center.x, -model_center.y, -model_center.z );

        // !TODO: draw transparent models
        m_ogl_3dmodel->Draw_opaque();
        m_ogl_3dmodel->Draw_transparent();
        //m_ogl_3dmodel->Draw_bboxes();

        glPopMatrix();
    }


    glViewport( 0, 0, clientSize.y / 8 , clientSize.y / 8 );                    // YxY squared view port
    glClear( GL_DEPTH_BUFFER_BIT );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 45.0f, 1.0f, 0.01f, RANGE_SCALE_3D * 2.0f );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    const glm::mat4 TranslationMatrix = glm::translate( glm::mat4(1.0f), SFVEC3F( 0.0f, 0.0f, -RANGE_SCALE_3D ) );
    const glm::mat4 ViewMatrix = TranslationMatrix * m_trackBallCamera.GetRotationMatrix();

    glLoadMatrixf( glm::value_ptr( ViewMatrix ) );

    ogl_set_arrow_material();

    glColor3f( 0.9f, 0.0f, 0.0f );
    OGL_draw_arrow( SFVEC3F( 0.0f, 0.0f, 0.0f ),
                    SFVEC3F( RANGE_SCALE_3D / 2.65f, 0.0f, 0.0f ),
                    0.275f );

    glColor3f( 0.0f, 0.9f, 0.0f );
    OGL_draw_arrow( SFVEC3F( 0.0f, 0.0f, 0.0f ),
                    SFVEC3F( 0.0f, RANGE_SCALE_3D / 2.65f, 0.0f ),
                    0.275f );

    glColor3f( 0.0f, 0.0f, 0.9f );
    OGL_draw_arrow( SFVEC3F( 0.0f, 0.0f, 0.0f ),
                    SFVEC3F( 0.0f, 0.0f, RANGE_SCALE_3D / 2.65f ),
                    0.275f );

    // "Swaps the double-buffer of this window, making the back-buffer the
    //  front-buffer and vice versa, so that the output of the previous OpenGL
    //  commands is displayed on the window."
    SwapBuffers();
    GL_CONTEXT_MANAGER::Get().UnlockCtx( m_glRC );

    event.Skip();
}
void CLAYER_TRIANGLES::AddToMiddleContourns( const std::vector< SFVEC2F > &aContournPoints,
                                             float zBot,
                                             float zTop,
                                             bool aInvertFaceDirection )
{
    if( aContournPoints.size() > 4 )
    {
        // Calculate normals of each segment of the contourn
        std::vector< SFVEC2F > contournNormals;

        contournNormals.clear();
        contournNormals.resize( aContournPoints.size() - 1 );

        if( aInvertFaceDirection )
        {
            for( unsigned int i = 0; i < ( aContournPoints.size() - 1 ); ++i )
            {
                const SFVEC2F &v0 = aContournPoints[i + 0];
                const SFVEC2F &v1 = aContournPoints[i + 1];

                const SFVEC2F n = glm::normalize( v1 - v0 );

                contournNormals[i] = SFVEC2F( n.y,-n.x );
            }
        }
        else
        {
            for( unsigned int i = 0; i < ( aContournPoints.size() - 1 ); ++i )
            {
                const SFVEC2F &v0 = aContournPoints[i + 0];
                const SFVEC2F &v1 = aContournPoints[i + 1];

                const SFVEC2F n = glm::normalize( v1 - v0 );

                contournNormals[i] = SFVEC2F( -n.y, n.x );
            }
        }


        if( aInvertFaceDirection )
            std::swap( zBot, zTop );

        const unsigned int nContournsToProcess = ( aContournPoints.size() - 1 );

        for( unsigned int i = 0; i < nContournsToProcess; ++i )
        {
            SFVEC2F lastNormal;

            if( i > 0 )
                lastNormal = contournNormals[i - 1];
            else
                lastNormal = contournNormals[nContournsToProcess - 1];

            SFVEC2F n0 = contournNormals[i];

            // Only interpolate the normal if the angle is closer
            if( glm::dot( n0, lastNormal ) > 0.5f )
                n0 = glm::normalize( n0 + lastNormal );

            SFVEC2F nextNormal;

            if( i < (nContournsToProcess - 1) )
                nextNormal = contournNormals[i + 1];
            else
                nextNormal = contournNormals[0];

            SFVEC2F n1 = contournNormals[i];

            if( glm::dot( n1, nextNormal ) > 0.5f )
                n1 = glm::normalize( n1 + nextNormal );

            const SFVEC3F n3d0 = SFVEC3F( n0.x, n0.y, 0.0f );
            const SFVEC3F n3d1 = SFVEC3F( n1.x, n1.y, 0.0f );

            const SFVEC2F &v0 = aContournPoints[i + 0];
            const SFVEC2F &v1 = aContournPoints[i + 1];

            #pragma omp critical
            {
                m_layer_middle_contourns_quads->AddQuad( SFVEC3F( v0.x, v0.y, zTop ),
                                                         SFVEC3F( v1.x, v1.y, zTop ),
                                                         SFVEC3F( v1.x, v1.y, zBot ),
                                                         SFVEC3F( v0.x, v0.y, zBot ) );

                m_layer_middle_contourns_quads->AddNormal( n3d0, n3d1, n3d1, n3d0 );
            }
        }
    }
}
Пример #30
0
bool SGSHAPE::Prepare( const glm::dmat4* aTransform,
    S3D::MATLIST& materials, std::vector< SMESH >& meshes )
{
    SMESH m;
    S3D::INIT_SMESH( m );

    SGAPPEARANCE* pa = m_Appearance;
    SGFACESET* pf = m_FaceSet;

    if( NULL == pa )
        pa = m_RAppearance;

    if( NULL == pf )
        pf = m_RFaceSet;

    // no face sets = nothing to render, which is valid though pointless
    if( NULL == pf )
        return true;

    if( !pf->validate() )
    {
#ifdef DEBUG
        std::ostringstream ostr;
        ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
        ostr << " * [INFO] bad model; inconsistent data";
        wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
#endif
        return true;
    }

    if( NULL == pa )
    {
        m.m_MaterialIdx = 0;
    }
    else
    {
        int idx;

        if( !S3D::GetMatIndex( materials, pa, idx ) )
        {
            m.m_MaterialIdx = 0;
        }
        else
        {
            m.m_MaterialIdx = idx;
        }
    }

    SGCOLORS* pc = pf->m_Colors;
    SGCOORDS* pv = pf->m_Coords;
    SGCOORDINDEX* vidx = pf->m_CoordIndices;
    SGNORMALS* pn = pf->m_Normals;

    if( NULL == pc )
        pc = pf->m_RColors;

    if( NULL == pv )
        pv = pf->m_RCoords;

    if( NULL == pn )
        pn = pf->m_RNormals;

    // set the vertex points and indices
    size_t nCoords = 0;
    SGPOINT* pCoords = NULL;
    pv->GetCoordsList( nCoords, pCoords );

    size_t nColors = 0;
    SGCOLOR* pColors = NULL;

    if( pc )
    {
        // check the vertex colors
        pc->GetColorList( nColors, pColors );

        if( nColors < nCoords )
        {
            #ifdef DEBUG
            std::ostringstream ostr;
            ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
            ostr << " * [INFO] bad model; not enough colors per vertex (";
            ostr << nColors << " vs " << nCoords << ")";
            wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
            #endif
            return true;
        }
    }

    // set the vertex indices
    size_t nvidx = 0;
    int*   lv = NULL;
    vidx->GetIndices( nvidx, lv );

    // note: reduce the vertex set to include only the referenced vertices
    std::vector< int > vertices;            // store the list of temp vertex indices
    std::map< int, unsigned int > indexmap; // map temp vertex to true vertex
    std::map< int, unsigned int >::iterator mit;

    for( unsigned int i = 0; i < nvidx; ++i )
    {
        mit = indexmap.find( lv[i] );

        if( mit == indexmap.end() )
        {
            indexmap.insert( std::pair< int, unsigned int >( lv[i], vertices.size() ) );
            vertices.push_back( lv[i] );
        }
    }

    if( vertices.size() < 3 )
    {
        #ifdef DEBUG
        std::ostringstream ostr;
        ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
        ostr << " * [INFO] bad model; not enough vertices";
        wxLogTrace( MASK_3D_SG, "%s\n", ostr.str().c_str() );
        #endif
        return true;
    }

    // construct the final vertex/color list
    SFVEC3F* lColors = NULL;
    SFVEC3F* lCoords = new SFVEC3F[ vertices.size() ];
    int ti;

    if( pc )
    {
        lColors = new SFVEC3F[vertices.size()];
        m.m_Color = lColors;
    }


    if( pc )
    {
        for( size_t i = 0; i < vertices.size(); ++i )
        {
            ti = vertices[i];
            glm::dvec4 pt( pCoords[ti].x, pCoords[ti].y, pCoords[ti].z, 1.0 );
            pt = (*aTransform) * pt;
            pColors[ti].GetColor( lColors[i].x, lColors[i].y, lColors[i].z );
            lCoords[i] = SFVEC3F( pt.x, pt.y, pt.z );
        }
    }
    else
    {
        for( size_t i = 0; i < vertices.size(); ++i )
        {
            ti = vertices[i];
            glm::dvec4 pt( pCoords[ti].x, pCoords[ti].y, pCoords[ti].z, 1.0 );
            pt = (*aTransform) * pt;
            lCoords[i] = SFVEC3F( pt.x, pt.y, pt.z );
        }
    }

    m.m_VertexSize = (unsigned int) vertices.size();
    m.m_Positions = lCoords;
    unsigned int* lvidx = new unsigned int[ nvidx ];

    for( unsigned int i = 0; i < nvidx; ++i )
    {
        mit = indexmap.find( lv[i] );
        lvidx[i] = mit->second;
    }

    m.m_FaceIdxSize = (unsigned int )nvidx;
    m.m_FaceIdx = lvidx;

    // set the per-vertex normals
    size_t nNorms = 0;
    SGVECTOR* pNorms = NULL;
    double x, y, z;

    pn->GetNormalList( nNorms, pNorms );
    SFVEC3F* lNorms = new SFVEC3F[ vertices.size() ];

    for( size_t i = 0; i < vertices.size(); ++i )
    {
        ti = vertices[i];
        pNorms[ti].GetVector( x, y, z );
        glm::dvec4 pt( x, y, z, 0.0 );
        pt = (*aTransform) * pt;

        lNorms[i] = SFVEC3F( pt.x, pt.y, pt.z );
    }

    m.m_Normals = lNorms;
    meshes.push_back( m );

    return true;
}