3D viewer code cleaning round 3.

This commit is contained in:
Wayne Stambaugh 2020-12-13 18:02:57 -05:00
parent 9dae57ae9d
commit 4d128b819a
22 changed files with 747 additions and 835 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -44,8 +44,7 @@ void C3D_RENDER_OGL_LEGACY::add_object_to_triangle_layer( const CFILLEDCIRCLE2D
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
// 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 ) );
@ -96,7 +95,7 @@ void C3D_RENDER_OGL_LEGACY::generate_ring_contour( const SFVEC2F &aCenter,
for( int ii = 0; ii < 3600; ii += delta )
{
float angle = (float)( aInvertOrder ? ( 3600 - ii ) : ii )
* 2.0f * glm::pi<float>() / 3600.0f;
* 2.0f * glm::pi<float>() / 3600.0f;
const SFVEC2F rotatedDir = SFVEC2F( cos( angle ), sin( angle ) );
aInnerContourResult.emplace_back( aCenter.x + rotatedDir.x * aInnerRadius,
@ -133,7 +132,6 @@ void C3D_RENDER_OGL_LEGACY::add_object_to_triangle_layer( const CRING2D * aRing,
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];
@ -182,11 +180,11 @@ void C3D_RENDER_OGL_LEGACY::add_object_to_triangle_layer( const CROUNDSEGMENT2D
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 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 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 );
@ -295,9 +293,7 @@ CLAYERS_OGL_DISP_LISTS *C3D_RENDER_OGL_LEGACY::generate_holes_display_list(
}
// Note: he can have a aListHolesObject2d whith holes but without countours
// eg: when there are only NPTH on the list and the contours were not
// added
// eg: when there are only NPTH on the list and the contours were not added
if( aPoly.OutlineCount() > 0 )
{
layerTriangles->AddToMiddleContourns( aPoly, aZbot, aZtop,
@ -386,8 +382,8 @@ C3D_RENDER_OGL_LEGACY::generateLayerListFromContainer( const CBVHCONTAINER2D *aC
layerTriangles->AddToMiddleContourns( *aPolyList, layer_z_bot, layer_z_top,
m_boardAdapter.BiuTo3Dunits(), false, aThroughHoles );
}
// Create display list
// /////////////////////////////////////////////////////////////////////
return new CLAYERS_OGL_DISP_LISTS( *layerTriangles, m_ogl_circle_texture, layer_z_bot,
layer_z_top );
}
@ -421,7 +417,7 @@ CLAYERS_OGL_DISP_LISTS* C3D_RENDER_OGL_LEGACY::createBoard( const SHAPE_POLY_SET
itemOnLayer != listBoardObject2d.end();
++itemOnLayer )
{
const COBJECT2D *object2d_A = static_cast<const COBJECT2D *>(*itemOnLayer);
const COBJECT2D* object2d_A = static_cast<const COBJECT2D*>( *itemOnLayer );
wxASSERT( object2d_A->GetObjectType() == OBJECT2D_TYPE::TRIANGLE );
@ -470,8 +466,6 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
aStatusReporter->Report( _( "Load OpenGL: board" ) );
// Create Board
// /////////////////////////////////////////////////////////////////////////
m_board = createBoard( m_boardAdapter.GetBoardPoly(), &m_boardAdapter.GetThroughHole_Inner() );
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
@ -495,22 +489,20 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetThroughHole_Outer_poly_NPTH(),
SHAPE_POLY_SET::PM_FAST );
m_board_with_holes = createBoard( board_poly_with_holes );
if( m_anti_board )
m_anti_board->SetItIsTransparent( true );
// Create Through Holes and vias
// /////////////////////////////////////////////////////////////////////////
if( aStatusReporter )
aStatusReporter->Report( _( "Load OpenGL: holes and vias" ) );
SHAPE_POLY_SET outerPolyTHT = m_boardAdapter.GetThroughHole_Outer_poly();
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
m_through_holes_outer = generate_holes_display_list(
m_boardAdapter.GetThroughHole_Outer().GetList(),
@ -538,13 +530,12 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
false );
}
// Not in use
/// @todo Determine what to do with this commented out code.
//m_ogl_disp_list_through_holes_vias_inner = generate_holes_display_list(
// m_boardAdapter.GetThroughHole_Vias_Inner().GetList(),
// m_boardAdapter.GetThroughHole_Vias_Inner_poly(),
// 1.0f, 0.0f,
// false );
const MAP_POLY & innerMapHoles = m_boardAdapter.GetPolyMapHoles_Inner();
const MAP_POLY & outerMapHoles = m_boardAdapter.GetPolyMapHoles_Outer();
@ -557,13 +548,11 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
float layer_z_bot = 0.0f;
float layer_z_top = 0.0f;
for( MAP_POLY::const_iterator ii = outerMapHoles.begin();
ii != outerMapHoles.end();
++ii )
for( MAP_POLY::const_iterator ii = outerMapHoles.begin(); ii != outerMapHoles.end(); ++ii )
{
PCB_LAYER_ID layer_id = static_cast<PCB_LAYER_ID>(ii->first);
const SHAPE_POLY_SET *poly = static_cast<const SHAPE_POLY_SET *>(ii->second);
const CBVHCONTAINER2D *container = map_holes.at( layer_id );
const SHAPE_POLY_SET* poly = static_cast<const SHAPE_POLY_SET*>( ii->second );
const CBVHCONTAINER2D* container = map_holes.at( layer_id );
get_layer_z_pos( layer_id, layer_z_top, layer_z_bot );
@ -572,13 +561,11 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
layer_z_bot, false );
}
for( MAP_POLY::const_iterator ii = innerMapHoles.begin();
ii != innerMapHoles.end();
++ii )
for( MAP_POLY::const_iterator ii = innerMapHoles.begin(); ii != innerMapHoles.end(); ++ii )
{
PCB_LAYER_ID layer_id = static_cast<PCB_LAYER_ID>(ii->first);
const SHAPE_POLY_SET *poly = static_cast<const SHAPE_POLY_SET *>(ii->second);
const CBVHCONTAINER2D *container = map_holes.at( layer_id );
PCB_LAYER_ID layer_id = static_cast<PCB_LAYER_ID>( ii->first );
const SHAPE_POLY_SET* poly = static_cast<const SHAPE_POLY_SET*>( ii->second );
const CBVHCONTAINER2D* container = map_holes.at( layer_id );
get_layer_z_pos( layer_id, layer_z_top, layer_z_bot );
@ -592,7 +579,6 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
generate_3D_Vias_and_Pads();
// Add layers maps
if( aStatusReporter )
aStatusReporter->Report( _( "Load OpenGL: layers" ) );
@ -602,12 +588,12 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
ii != m_boardAdapter.GetMapLayers().end();
++ii )
{
PCB_LAYER_ID layer_id = static_cast<PCB_LAYER_ID>(ii->first);
PCB_LAYER_ID layer_id = static_cast<PCB_LAYER_ID>( ii->first );
if( !m_boardAdapter.Is3DLayerEnabled( layer_id ) )
continue;
const CBVHCONTAINER2D *container2d = static_cast<const CBVHCONTAINER2D *>(ii->second);
const CBVHCONTAINER2D* container2d = static_cast<const CBVHCONTAINER2D*>( ii->second );
SHAPE_POLY_SET polyListSubtracted;
SHAPE_POLY_SET *aPolyList = nullptr;
@ -621,14 +607,16 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
if( ( layer_id != B_Paste ) && ( layer_id != F_Paste ) &&
m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
{
polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST );
polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(),
SHAPE_POLY_SET::PM_FAST );
if( ( layer_id != B_Mask ) && ( layer_id != F_Mask ) )
{
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetThroughHole_Outer_poly(),
SHAPE_POLY_SET::PM_FAST );
polyListSubtracted.BooleanSubtract( m_boardAdapter.GetThroughHole_Outer_poly_NPTH(),
SHAPE_POLY_SET::PM_FAST );
polyListSubtracted.BooleanSubtract(
m_boardAdapter.GetThroughHole_Outer_poly_NPTH(),
SHAPE_POLY_SET::PM_FAST );
}
if( m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK ) )
@ -650,14 +638,15 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
aPolyList = &polyListSubtracted;
}
CLAYERS_OGL_DISP_LISTS* oglList = generateLayerListFromContainer( container2d, aPolyList,
layer_id,
&m_boardAdapter.GetThroughHole_Inner() );
CLAYERS_OGL_DISP_LISTS* oglList = generateLayerListFromContainer(
container2d, aPolyList,
layer_id,
&m_boardAdapter.GetThroughHole_Inner() );
if( oglList != nullptr )
m_layers[layer_id] = oglList;
}// for each layer on
}
if( m_boardAdapter.GetFlag( FL_RENDER_PLATED_PADS_AS_PLATED ) &&
m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
@ -672,8 +661,9 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
polySubtracted.BooleanSubtract( m_boardAdapter.GetThroughHole_Outer_poly_NPTH(),
SHAPE_POLY_SET::PM_FAST );
m_platedPads_F_Cu = generateLayerListFromContainer( m_boardAdapter.GetPlatedPads_Front(),
&polySubtracted, F_Cu );
m_platedPads_F_Cu = generateLayerListFromContainer(
m_boardAdapter.GetPlatedPads_Front(),
&polySubtracted, F_Cu );
}
if( m_boardAdapter.GetPolyPlatedPads_Back() )
@ -692,7 +682,6 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
}
// Load 3D models
// /////////////////////////////////////////////////////////////////////////
if( aStatusReporter )
aStatusReporter->Report( _( "Loading 3D models" ) );
@ -784,14 +773,14 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
if( m_boardAdapter.GetStats_Nr_Vias() )
{
const unsigned int reserve_nr_triangles_estimation =
m_boardAdapter.GetNrSegmentsCircle( m_boardAdapter.GetStats_Med_Via_Hole_Diameter3DU() ) *
8 *
m_boardAdapter.GetStats_Nr_Vias();
m_boardAdapter.GetNrSegmentsCircle(
m_boardAdapter.GetStats_Med_Via_Hole_Diameter3DU() ) * 8 *
m_boardAdapter.GetStats_Nr_Vias();
CLAYER_TRIANGLES *layerTriangleVIA = new CLAYER_TRIANGLES( reserve_nr_triangles_estimation );
CLAYER_TRIANGLES *layerTriangleVIA =
new CLAYER_TRIANGLES( reserve_nr_triangles_estimation );
// Insert plated vertical holes inside the board
// /////////////////////////////////////////////////////////////////////////
// Insert vias holes (vertical cylinders)
for( auto track : m_boardAdapter.GetBoard()->Tracks() )
@ -800,10 +789,10 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
{
const VIA *via = static_cast<const VIA*>(track);
const float holediameter = via->GetDrillValue() * m_boardAdapter.BiuTo3Dunits();
const float thickness = m_boardAdapter.GetCopperThickness3DU();
const int nrSegments = m_boardAdapter.GetNrSegmentsCircle( via->GetDrillValue() );
const float hole_inner_radius = holediameter / 2.0f;
const float holediameter = via->GetDrillValue() * m_boardAdapter.BiuTo3Dunits();
const float thickness = m_boardAdapter.GetCopperThickness3DU();
const int nrSegments = m_boardAdapter.GetNrSegmentsCircle( via->GetDrillValue() );
const float hole_inner_radius = holediameter / 2.0f;
const SFVEC2F via_center( via->GetStart().x * m_boardAdapter.BiuTo3Dunits(),
-via->GetStart().y * m_boardAdapter.BiuTo3Dunits() );
@ -921,17 +910,11 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
}
/*
* This function will get models from the cache and load it to openGL lists
* in the form of C_OGL_3DMODEL. So this map of models will work as a local
* cache for this render. (cache based on C_OGL_3DMODEL with associated
* openGL lists in GPU memory)
*/
void C3D_RENDER_OGL_LEGACY::load_3D_models( REPORTER* aStatusReporter )
{
if( !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL )
&& !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL_INSERT )
&& !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_VIRTUAL ) )
&& !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL_INSERT )
&& !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_VIRTUAL ) )
{
return;
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -34,8 +34,8 @@
#include <base_units.h>
/**
* Scale conversion from 3d model units to pcb units
*/
* Scale conversion from 3d model units to pcb units
*/
#define UNITS3D_TO_UNITSPCB (IU_PER_MM)
C3D_RENDER_OGL_LEGACY::C3D_RENDER_OGL_LEGACY( BOARD_ADAPTER& aAdapter, CCAMERA& aCamera ) :
@ -144,7 +144,8 @@ void C3D_RENDER_OGL_LEGACY::render_3D_arrows()
glLoadIdentity();
const glm::mat4 TranslationMatrix = glm::translate( glm::mat4(1.0f),
SFVEC3F( 0.0f, 0.0f, -(arrow_size * 2.75f) ) );
SFVEC3F( 0.0f, 0.0f,
-(arrow_size * 2.75f) ) );
const glm::mat4 ViewMatrix = TranslationMatrix * m_camera.GetRotationMatrix();
@ -202,7 +203,8 @@ void C3D_RENDER_OGL_LEGACY::setupMaterials()
// Non plated copper (raw copper)
m_materials.m_NonPlatedCopper.m_Ambient = SFVEC3F( 0.191f, 0.073f, 0.022f );
m_materials.m_NonPlatedCopper.m_Diffuse = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f );
m_materials.m_NonPlatedCopper.m_Diffuse = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f,
50.0f / 255.0f );
m_materials.m_NonPlatedCopper.m_Specular = SFVEC3F( 0.256f, 0.137f, 0.086f );
m_materials.m_NonPlatedCopper.m_Shininess = 0.1f * 128.0f;
m_materials.m_NonPlatedCopper.m_Emissive = SFVEC3F( 0.0f, 0.0f, 0.0f );
@ -222,7 +224,6 @@ void C3D_RENDER_OGL_LEGACY::setupMaterials()
m_materials.m_Paste.m_Shininess = 0.1f * 128.0f;
m_materials.m_Paste.m_Emissive = SFVEC3F( 0.0f, 0.0f, 0.0f );
// Silk screen material mixed with silk screen color
m_materials.m_SilkSTop.m_Ambient = SFVEC3F( m_boardAdapter.m_SilkScreenColorTop.r,
m_boardAdapter.m_SilkScreenColorTop.g,
@ -320,73 +321,74 @@ void C3D_RENDER_OGL_LEGACY::set_layer_material( PCB_LAYER_ID aLayerID )
{
switch( aLayerID )
{
case F_Mask:
case B_Mask:
case F_Mask:
case B_Mask:
{
const SFVEC4F layerColor = get_layer_color( aLayerID );
m_materials.m_SolderMask.m_Diffuse = layerColor;
// Convert Opacity to Transparency
m_materials.m_SolderMask.m_Transparency = 1.0f - layerColor.a;
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
{
const SFVEC4F layerColor = get_layer_color( aLayerID );
m_materials.m_SolderMask.m_Ambient = m_materials.m_SolderMask.m_Diffuse * 0.3f;
m_materials.m_SolderMask.m_Diffuse = layerColor;
m_materials.m_SolderMask.m_Transparency = 1.0f - layerColor.a; // Convert Opacity to Transparency
if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) )
{
m_materials.m_SolderMask.m_Ambient = m_materials.m_SolderMask.m_Diffuse * 0.3f;
m_materials.m_SolderMask.m_Specular = m_materials.m_SolderMask.m_Diffuse *
m_materials.m_SolderMask.m_Diffuse;
}
OGL_SetMaterial( m_materials.m_SolderMask, 1.0f );
break;
m_materials.m_SolderMask.m_Specular =
m_materials.m_SolderMask.m_Diffuse * m_materials.m_SolderMask.m_Diffuse;
}
case B_Paste:
case F_Paste:
m_materials.m_Paste.m_Diffuse = get_layer_color( aLayerID );
OGL_SetMaterial( m_materials.m_Paste, 1.0f );
break;
OGL_SetMaterial( m_materials.m_SolderMask, 1.0f );
break;
}
case B_SilkS:
m_materials.m_SilkSBot.m_Diffuse = get_layer_color( aLayerID );
OGL_SetMaterial( m_materials.m_SilkSBot, 1.0f );
break;
case F_SilkS:
m_materials.m_SilkSTop.m_Diffuse = get_layer_color( aLayerID );
OGL_SetMaterial( m_materials.m_SilkSTop, 1.0f );
break;
case B_Adhes:
case F_Adhes:
case Dwgs_User:
case Cmts_User:
case Eco1_User:
case Eco2_User:
case Edge_Cuts:
case Margin:
case B_CrtYd:
case F_CrtYd:
case B_Fab:
case F_Fab:
m_materials.m_Plastic.m_Diffuse = get_layer_color( aLayerID );
m_materials.m_Plastic.m_Ambient = SFVEC3F( m_materials.m_Plastic.m_Diffuse.r * 0.05f,
m_materials.m_Plastic.m_Diffuse.g * 0.05f,
m_materials.m_Plastic.m_Diffuse.b * 0.05f );
m_materials.m_Plastic.m_Specular = SFVEC3F( m_materials.m_Plastic.m_Diffuse.r * 0.7f,
m_materials.m_Plastic.m_Diffuse.g * 0.7f,
m_materials.m_Plastic.m_Diffuse.b * 0.7f );
m_materials.m_Plastic.m_Shininess = 0.078125f * 128.0f;
m_materials.m_Plastic.m_Emissive = SFVEC3F( 0.0f, 0.0f, 0.0f );
OGL_SetMaterial( m_materials.m_Plastic, 1.0f );
case B_Paste:
case F_Paste:
m_materials.m_Paste.m_Diffuse = get_layer_color( aLayerID );
OGL_SetMaterial( m_materials.m_Paste, 1.0f );
break;
default:
m_materials.m_Copper.m_Diffuse = get_layer_color( aLayerID );
OGL_SetMaterial( m_materials.m_Copper, 1.0f );
case B_SilkS:
m_materials.m_SilkSBot.m_Diffuse = get_layer_color( aLayerID );
OGL_SetMaterial( m_materials.m_SilkSBot, 1.0f );
break;
case F_SilkS:
m_materials.m_SilkSTop.m_Diffuse = get_layer_color( aLayerID );
OGL_SetMaterial( m_materials.m_SilkSTop, 1.0f );
break;
case B_Adhes:
case F_Adhes:
case Dwgs_User:
case Cmts_User:
case Eco1_User:
case Eco2_User:
case Edge_Cuts:
case Margin:
case B_CrtYd:
case F_CrtYd:
case B_Fab:
case F_Fab:
m_materials.m_Plastic.m_Diffuse = get_layer_color( aLayerID );
m_materials.m_Plastic.m_Ambient = SFVEC3F( m_materials.m_Plastic.m_Diffuse.r * 0.05f,
m_materials.m_Plastic.m_Diffuse.g * 0.05f,
m_materials.m_Plastic.m_Diffuse.b * 0.05f );
m_materials.m_Plastic.m_Specular = SFVEC3F( m_materials.m_Plastic.m_Diffuse.r * 0.7f,
m_materials.m_Plastic.m_Diffuse.g * 0.7f,
m_materials.m_Plastic.m_Diffuse.b * 0.7f );
m_materials.m_Plastic.m_Shininess = 0.078125f * 128.0f;
m_materials.m_Plastic.m_Emissive = SFVEC3F( 0.0f, 0.0f, 0.0f );
OGL_SetMaterial( m_materials.m_Plastic, 1.0f );
break;
default:
m_materials.m_Copper.m_Diffuse = get_layer_color( aLayerID );
OGL_SetMaterial( m_materials.m_Copper, 1.0f );
break;
}
}
@ -400,48 +402,48 @@ SFVEC4F C3D_RENDER_OGL_LEGACY::get_layer_color( PCB_LAYER_ID aLayerID )
{
switch( aLayerID )
{
case B_Adhes:
case F_Adhes:
break;
case B_Adhes:
case F_Adhes:
break;
case B_Mask:
layerColor = m_boardAdapter.m_SolderMaskColorBot;
break;
case F_Mask:
layerColor = m_boardAdapter.m_SolderMaskColorTop;
break;
case B_Mask:
layerColor = m_boardAdapter.m_SolderMaskColorBot;
break;
case F_Mask:
layerColor = m_boardAdapter.m_SolderMaskColorTop;
break;
case B_Paste:
case F_Paste:
layerColor = m_boardAdapter.m_SolderPasteColor;
break;
case B_Paste:
case F_Paste:
layerColor = m_boardAdapter.m_SolderPasteColor;
break;
case B_SilkS:
layerColor = m_boardAdapter.m_SilkScreenColorBot;
break;
case F_SilkS:
layerColor = m_boardAdapter.m_SilkScreenColorTop;
break;
case B_SilkS:
layerColor = m_boardAdapter.m_SilkScreenColorBot;
break;
case F_SilkS:
layerColor = m_boardAdapter.m_SilkScreenColorTop;
break;
case Dwgs_User:
case Cmts_User:
case Eco1_User:
case Eco2_User:
case Edge_Cuts:
case Margin:
break;
case Dwgs_User:
case Cmts_User:
case Eco1_User:
case Eco2_User:
case Edge_Cuts:
case Margin:
break;
case B_CrtYd:
case F_CrtYd:
break;
case B_CrtYd:
case F_CrtYd:
break;
case B_Fab:
case F_Fab:
break;
case B_Fab:
case F_Fab:
break;
default:
layerColor = m_boardAdapter.m_CopperColor;
break;
default:
layerColor = m_boardAdapter.m_CopperColor;
break;
}
}
@ -453,7 +455,6 @@ void init_lights(void)
{
// Setup light
// https://www.opengl.org/sdk/docs/man2/xhtml/glLight.xml
// /////////////////////////////////////////////////////////////////////////
const GLfloat ambient[] = { 0.084f, 0.084f, 0.084f, 1.0f };
const GLfloat diffuse0[] = { 0.3f, 0.3f, 0.3f, 1.0f };
const GLfloat specular0[] = { 0.5f, 0.5f, 0.5f, 1.0f };
@ -481,7 +482,6 @@ void init_lights(void)
glLightfv( GL_LIGHT1, GL_SPECULAR, specular12 );
glLightfv( GL_LIGHT1, GL_POSITION, position );
// defines a directional light that points along the positive z-axis
position[2] = -position[2];
@ -521,7 +521,9 @@ void C3D_RENDER_OGL_LEGACY::unsetDepthOffset()
void C3D_RENDER_OGL_LEGACY::render_board_body( bool aSkipRenderHoles )
{
m_materials.m_EpoxyBoard.m_Diffuse = m_boardAdapter.m_BoardBodyColor;
m_materials.m_EpoxyBoard.m_Transparency = 1.0f - m_boardAdapter.m_BoardBodyColor.a; // opacity to transparency
// opacity to transparency
m_materials.m_EpoxyBoard.m_Transparency = 1.0f - m_boardAdapter.m_BoardBodyColor.a;
OGL_SetMaterial( m_materials.m_EpoxyBoard, 1.0f );
@ -581,12 +583,10 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
setupMaterials();
// Initial setup
// /////////////////////////////////////////////////////////////////////////
glDepthFunc( GL_LESS );
glEnable( GL_CULL_FACE );
glFrontFace( GL_CCW ); // This is the OpenGL default
glEnable( GL_NORMALIZE ); // This allow OpenGL to normalize the normals after transformations
glViewport( 0, 0, m_windowSize.x, m_windowSize.y );
if( m_boardAdapter.GetFlag( FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE ) && aIsMoving )
@ -595,7 +595,6 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
glEnable( GL_MULTISAMPLE );
// clear color and depth buffers
// /////////////////////////////////////////////////////////////////////////
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClearDepth( 1.0f );
glClearStencil( 0x00 );
@ -604,26 +603,19 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
OGL_ResetTextureStateDefaults();
// Draw the background ( rectangle with color gradient)
// /////////////////////////////////////////////////////////////////////////
OGL_DrawBackground( SFVEC3F( m_boardAdapter.m_BgColorTop ),
SFVEC3F( m_boardAdapter.m_BgColorBot ) );
glEnable( GL_DEPTH_TEST );
// Set projection and modelview matrixes
// /////////////////////////////////////////////////////////////////////////
glMatrixMode( GL_PROJECTION );
glLoadMatrixf( glm::value_ptr( m_camera.GetProjectionMatrix() ) );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glLoadMatrixf( glm::value_ptr( m_camera.GetViewMatrix() ) );
// Position the headlight
// /////////////////////////////////////////////////////////////////////////
setLight_Front( true );
setLight_Top( true );
setLight_Bottom( true );
@ -680,30 +672,26 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
m_pad_holes->DrawAll();
// Display copper and tech layers
// /////////////////////////////////////////////////////////////////////////
for( MAP_OGL_DISP_LISTS::const_iterator ii = m_layers.begin(); ii != m_layers.end(); ++ii )
{
const PCB_LAYER_ID layer_id = (PCB_LAYER_ID)(ii->first);
const PCB_LAYER_ID layer_id = ( PCB_LAYER_ID )( ii->first );
// Mask layers are not processed here because they are a special case
if( (layer_id == B_Mask) || (layer_id == F_Mask) )
continue;
// Do not show inner layers when it is displaying the board
// and board body is full opaque
// Do not show inner layers when it is displaying the board and board body is full opaque
if( m_boardAdapter.GetFlag( FL_SHOW_BOARD_BODY ) &&
( m_boardAdapter.m_BoardBodyColor.a > 0.99f ) )
{
if( (layer_id > F_Cu) && (layer_id < B_Cu) )
if( ( layer_id > F_Cu ) && ( layer_id < B_Cu ) )
continue;
}
glPushMatrix();
// !TODO: if we want to increase the separation between layers
/// @todo Determine what to do with this commented out code.
//glScalef( 1.0f, 1.0f, 3.0f );
CLAYERS_OGL_DISP_LISTS *pLayerDispList = static_cast<CLAYERS_OGL_DISP_LISTS*>(ii->second);
if( (layer_id >= F_Cu) && (layer_id <= B_Cu) )
@ -720,7 +708,6 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
pLayerDispList->DrawAllCameraCulled( m_camera.GetPos().z, drawMiddleSegments );
// Draw copper plated pads
if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) &&
( m_platedPads_F_Cu || m_platedPads_B_Cu ) )
setPlatedCopperAndDepthOffset( layer_id );
@ -756,7 +743,8 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( m_layers_holes_outer.find( layer_id ) != m_layers_holes_outer.end() )
{
const CLAYERS_OGL_DISP_LISTS* viasHolesLayer = m_layers_holes_outer.at( layer_id );
const CLAYERS_OGL_DISP_LISTS* viasHolesLayer =
m_layers_holes_outer.at( layer_id );
wxASSERT( viasHolesLayer != NULL );
@ -777,17 +765,19 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( layer_id == F_Cu && m_platedPads_F_Cu )
{
m_platedPads_F_Cu->DrawAllCameraCulledSubtractLayer( drawMiddleSegments,
m_through_holes_outer,
viasHolesLayer,
m_anti_board );
m_platedPads_F_Cu->DrawAllCameraCulledSubtractLayer(
drawMiddleSegments,
m_through_holes_outer,
viasHolesLayer,
m_anti_board );
}
else if( layer_id == B_Cu && m_platedPads_B_Cu )
{
m_platedPads_B_Cu->DrawAllCameraCulledSubtractLayer( drawMiddleSegments,
m_through_holes_outer,
viasHolesLayer,
m_anti_board );
m_platedPads_B_Cu->DrawAllCameraCulledSubtractLayer(
drawMiddleSegments,
m_through_holes_outer,
viasHolesLayer,
m_anti_board );
}
unsetDepthOffset();
@ -800,7 +790,6 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
m_anti_board );
// Draw copper plated pads
if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) &&
( m_platedPads_F_Cu || m_platedPads_B_Cu ) )
{
@ -810,8 +799,8 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( layer_id == F_Cu && m_platedPads_F_Cu )
{
m_platedPads_F_Cu->DrawAllCameraCulledSubtractLayer( drawMiddleSegments,
m_through_holes_outer,
m_anti_board );
m_through_holes_outer,
m_anti_board );
}
else if( layer_id == B_Cu && m_platedPads_B_Cu )
{
@ -837,7 +826,8 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( throughHolesOuter )
{
throughHolesOuter->ApplyScalePosition( pLayerDispList->GetZBot(),
throughHolesOuter->ApplyScalePosition(
pLayerDispList->GetZBot(),
pLayerDispList->GetZTop() - pLayerDispList->GetZBot() );
}
@ -848,15 +838,16 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( anti_board )
{
anti_board->ApplyScalePosition( pLayerDispList->GetZBot(),
anti_board->ApplyScalePosition(
pLayerDispList->GetZBot(),
pLayerDispList->GetZTop() - pLayerDispList->GetZBot() );
}
if( !skipRenderHoles
&& m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK )
&& m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE )
&& ( ( layer_id == B_SilkS && m_layers.find( B_Mask ) != m_layers.end() )
|| ( layer_id == F_SilkS && m_layers.find( F_Mask ) != m_layers.end() ) ) )
&& m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK )
&& m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE )
&& ( ( layer_id == B_SilkS && m_layers.find( B_Mask ) != m_layers.end() )
|| ( layer_id == F_SilkS && m_layers.find( F_Mask ) != m_layers.end() ) ) )
{
const PCB_LAYER_ID layerMask_id = (layer_id == B_SilkS) ? B_Mask : F_Mask;
@ -873,7 +864,8 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
&& ( layer_id == B_SilkS || layer_id == F_SilkS ) )
{
pLayerDispList->DrawAllCameraCulledSubtractLayer( drawMiddleSegments, nullptr,
throughHolesOuter, anti_board );
throughHolesOuter,
anti_board );
}
else
{
@ -892,19 +884,16 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
}
// Render 3D Models (Non-transparent)
// /////////////////////////////////////////////////////////////////////////
render_3D_models( false, false );
render_3D_models( true, false );
// Display board body
// /////////////////////////////////////////////////////////////////////////
if( m_boardAdapter.GetFlag( FL_SHOW_BOARD_BODY ) )
{
render_board_body( skipRenderHoles );
}
// Display transparent mask layers
// /////////////////////////////////////////////////////////////////////////
if( m_boardAdapter.GetFlag( FL_SOLDERMASK ) )
{
//setLight_Top( true );
@ -938,12 +927,9 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
// Render 3D Models (Transparent)
// /////////////////////////////////////////////////////////////////////////
// !TODO: this can be optimized. If there are no transparent models (or no opacity),
// then there is no need to make this function call.
glDepthMask( GL_FALSE );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
@ -975,8 +961,6 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
glDepthMask( GL_TRUE );
// Render Grid
// /////////////////////////////////////////////////////////////////////////
if( m_boardAdapter.GridGet() != GRID3D_TYPE::NONE )
{
glDisable( GL_LIGHTING );
@ -987,15 +971,12 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
glEnable( GL_LIGHTING );
}
// Render 3D arrows
// /////////////////////////////////////////////////////////////////////////
if( m_boardAdapter.GetFlag( FL_AXIS ) )
render_3D_arrows();
// Return back to the original viewport (this is important if we want
// to take a screenshot after the render)
// /////////////////////////////////////////////////////////////////////////
glViewport( 0, 0, m_windowSize.x, m_windowSize.y );
return false;
@ -1016,11 +997,12 @@ bool C3D_RENDER_OGL_LEGACY::initializeOpenGL()
if( !circleImage )
return false;
circleImage->CircleFilled( (SIZE_OF_CIRCLE_TEXTURE / 2) - 0,
(SIZE_OF_CIRCLE_TEXTURE / 2) - 0,
(SIZE_OF_CIRCLE_TEXTURE / 2) - 4,
circleImage->CircleFilled( ( SIZE_OF_CIRCLE_TEXTURE / 2 ) - 0,
( SIZE_OF_CIRCLE_TEXTURE / 2 ) - 0,
( SIZE_OF_CIRCLE_TEXTURE / 2 ) - 4,
0xFF );
/// @todo Determine what to do with this commented out code.
//circleImage->CircleFilled( (SIZE_OF_CIRCLE_TEXTURE / 4)*1.5f - 1,
// (SIZE_OF_CIRCLE_TEXTURE / 4)*1.5f - 1,
// (SIZE_OF_CIRCLE_TEXTURE / 4)*1.5f - 2, 0xFF );
@ -1043,7 +1025,6 @@ bool C3D_RENDER_OGL_LEGACY::initializeOpenGL()
// Use this mode if you want see the triangle lines (debug proposes)
//glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
m_is_opengl_initialized = true;
return true;
@ -1078,7 +1059,7 @@ void C3D_RENDER_OGL_LEGACY::ogl_free_all_display_lists()
for( MAP_OGL_DISP_LISTS::const_iterator ii = m_layers.begin(); ii != m_layers.end(); ++ii )
{
CLAYERS_OGL_DISP_LISTS *pLayerDispList = static_cast<CLAYERS_OGL_DISP_LISTS*>(ii->second);
CLAYERS_OGL_DISP_LISTS *pLayerDispList = static_cast<CLAYERS_OGL_DISP_LISTS*>( ii->second );
delete pLayerDispList;
}
@ -1090,23 +1071,21 @@ void C3D_RENDER_OGL_LEGACY::ogl_free_all_display_lists()
delete m_platedPads_B_Cu;
m_platedPads_B_Cu = nullptr;
for( MAP_OGL_DISP_LISTS::const_iterator ii = m_layers_holes_outer.begin();
ii != m_layers_holes_outer.end();
++ii )
{
CLAYERS_OGL_DISP_LISTS *pLayerDispList = static_cast<CLAYERS_OGL_DISP_LISTS*>(ii->second);
CLAYERS_OGL_DISP_LISTS* pLayerDispList = static_cast<CLAYERS_OGL_DISP_LISTS*>( ii->second );
delete pLayerDispList;
}
m_layers_holes_outer.clear();
for( MAP_OGL_DISP_LISTS::const_iterator ii = m_layers_holes_inner.begin();
ii != m_layers_holes_inner.end();
++ii )
{
CLAYERS_OGL_DISP_LISTS *pLayerDispList = static_cast<CLAYERS_OGL_DISP_LISTS*>(ii->second);
CLAYERS_OGL_DISP_LISTS* pLayerDispList = static_cast<CLAYERS_OGL_DISP_LISTS*>( ii->second );
delete pLayerDispList;
}
@ -1119,7 +1098,6 @@ void C3D_RENDER_OGL_LEGACY::ogl_free_all_display_lists()
m_triangles.clear();
for( MAP_3DMODEL::const_iterator ii = m_3dmodel_map.begin(); ii != m_3dmodel_map.end(); ++ii )
{
C_OGL_3DMODEL *pointer = static_cast<C_OGL_3DMODEL*>(ii->second);
@ -1128,7 +1106,6 @@ void C3D_RENDER_OGL_LEGACY::ogl_free_all_display_lists()
m_3dmodel_map.clear();
delete m_board;
m_board = nullptr;
@ -1155,9 +1132,9 @@ void C3D_RENDER_OGL_LEGACY::ogl_free_all_display_lists()
}
void C3D_RENDER_OGL_LEGACY::render_solder_mask_layer(PCB_LAYER_ID aLayerID, float aZPosition,
bool aDrawMiddleSegments,
bool aSkipRenderHoles )
void C3D_RENDER_OGL_LEGACY::render_solder_mask_layer( PCB_LAYER_ID aLayerID, float aZPosition,
bool aDrawMiddleSegments,
bool aSkipRenderHoles )
{
wxASSERT( (aLayerID == B_Mask) || (aLayerID == F_Mask) );
@ -1228,8 +1205,8 @@ void C3D_RENDER_OGL_LEGACY::render_3D_models_selected( bool aRenderTopOrBot,
const bool isIntersected = ( fp == m_currentIntersectedBoardItem );
if( m_boardAdapter.GetFlag( FL_USE_SELECTION ) && !isIntersected
&& ( ( aRenderSelectedOnly && !fp->IsSelected() )
|| ( !aRenderSelectedOnly && fp->IsSelected() ) ) )
&& ( ( aRenderSelectedOnly && !fp->IsSelected() )
|| ( !aRenderSelectedOnly && fp->IsSelected() ) ) )
{
continue;
}
@ -1238,7 +1215,6 @@ void C3D_RENDER_OGL_LEGACY::render_3D_models_selected( bool aRenderTopOrBot,
{
glEnable( GL_POLYGON_OFFSET_LINE );
glPolygonOffset( 8.0, 1.0 );
glPolygonMode( GL_FRONT, GL_LINE );
glLineWidth( 6 );
}
@ -1267,8 +1243,7 @@ void C3D_RENDER_OGL_LEGACY::render_3D_models_selected( bool aRenderTopOrBot,
}
void C3D_RENDER_OGL_LEGACY::render_3D_models( bool aRenderTopOrBot,
bool aRenderTransparentOnly )
void C3D_RENDER_OGL_LEGACY::render_3D_models( bool aRenderTopOrBot, bool aRenderTransparentOnly )
{
if( m_boardAdapter.GetFlag( FL_USE_SELECTION ) )
render_3D_models_selected( aRenderTopOrBot, aRenderTransparentOnly, true );
@ -1291,10 +1266,10 @@ void C3D_RENDER_OGL_LEGACY::render_3D_footprint( const FOOTPRINT* aFootprint,
glTranslatef( pos.x * m_boardAdapter.BiuTo3Dunits(),
-pos.y * m_boardAdapter.BiuTo3Dunits(),
zpos );
zpos );
if( aFootprint->GetOrientation() )
glRotated((double) aFootprint->GetOrientation() / 10.0, 0.0, 0.0, 1.0 );
glRotated( (double) aFootprint->GetOrientation() / 10.0, 0.0, 0.0, 1.0 );
if( aFootprint->IsFlipped() )
{
@ -1381,8 +1356,6 @@ void C3D_RENDER_OGL_LEGACY::render_3D_footprint( const FOOTPRINT* aFootprint,
}
// create a 3D grid to an OpenGL display list: an horizontal grid (XY plane and Z = 0,
// and a vertical grid (XZ plane and Y = 0)
void C3D_RENDER_OGL_LEGACY::generate_new_3DGrid( GRID3D_TYPE aGridType )
{
if( glIsList( m_grid ) )

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -54,7 +54,7 @@ typedef std::map< wxString, C_OGL_3DMODEL * > MAP_3DMODEL;
#define SIZE_OF_CIRCLE_TEXTURE 1024
/**
* @brief The C3D_RENDER_OGL_LEGACY class render the board using openGL legacy mode
* Object to render the board using openGL legacy mode.
*/
class C3D_RENDER_OGL_LEGACY : public C3D_RENDER_BASE
{
@ -63,7 +63,6 @@ public:
~C3D_RENDER_OGL_LEGACY();
// Imported from C3D_RENDER_BASE
void SetCurWindowSize( const wxSize &aSize ) override;
bool Redraw( bool aIsMoving, REPORTER* aStatusReporter, REPORTER* aWarningReporter ) override;
@ -74,43 +73,6 @@ public:
m_currentIntersectedBoardItem = aCurrentIntersectedBoardItem;
}
private:
bool initializeOpenGL();
CLAYERS_OGL_DISP_LISTS* createBoard( const SHAPE_POLY_SET& aBoardPoly,
const CBVHCONTAINER2D *aThroughHoles = nullptr );
void reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter );
void ogl_set_arrow_material();
void ogl_free_all_display_lists();
MAP_OGL_DISP_LISTS m_layers;
CLAYERS_OGL_DISP_LISTS* m_platedPads_F_Cu;
CLAYERS_OGL_DISP_LISTS* m_platedPads_B_Cu;
MAP_OGL_DISP_LISTS m_layers_holes_outer;
MAP_OGL_DISP_LISTS m_layers_holes_inner;
CLAYERS_OGL_DISP_LISTS* m_board;
CLAYERS_OGL_DISP_LISTS* m_board_with_holes;
CLAYERS_OGL_DISP_LISTS* m_anti_board;
CLAYERS_OGL_DISP_LISTS* m_through_holes_outer;
CLAYERS_OGL_DISP_LISTS* m_through_holes_vias_outer;
CLAYERS_OGL_DISP_LISTS* m_through_holes_outer_ring;
CLAYERS_OGL_DISP_LISTS* m_vias_and_pad_holes_outer_contourn_and_caps;
LIST_TRIANGLES m_triangles; ///< store pointers so can be deleted latter
GLuint m_ogl_circle_texture;
GLuint m_grid; ///< oGL list that stores current grid
GRID3D_TYPE m_last_grid_type; ///< Stores the last grid computed
CLAYERS_OGL_DISP_LISTS* m_vias;
CLAYERS_OGL_DISP_LISTS* m_pad_holes;
MAP_3DMODEL m_3dmodel_map;
BOARD_ITEM* m_currentIntersectedBoardItem;
SHAPE_POLY_SET m_anti_board_poly; ///< negative polygon representation of the board outline
private:
CLAYERS_OGL_DISP_LISTS *generate_holes_display_list( const LIST_OBJECT2D &aListHolesObject2d,
const SHAPE_POLY_SET &aPoly,
@ -120,9 +82,9 @@ private:
const CBVHCONTAINER2D *aThroughHoles = nullptr );
CLAYERS_OGL_DISP_LISTS* generateLayerListFromContainer( const CBVHCONTAINER2D *aContainer,
const SHAPE_POLY_SET *aPolyList,
PCB_LAYER_ID aLayerId,
const CBVHCONTAINER2D *aThroughHoles = nullptr );
const SHAPE_POLY_SET *aPolyList,
PCB_LAYER_ID aLayerId,
const CBVHCONTAINER2D *aThroughHoles = nullptr );
void add_triangle_top_bot( CLAYER_TRIANGLES *aDst,
const SFVEC2F &v0,
@ -185,13 +147,19 @@ private:
void generate_3D_Vias_and_Pads();
/**
* Load footprint models from the cache and load it to openGL lists in the form of
* #C_OGL_3DMODEL objects.
*
* This map of models will work as a local cache for this render. (cache based on
* C_OGL_3DMODEL with associated openGL lists in GPU memory)
*/
void load_3D_models( REPORTER* aStatusReporter );
/**
* @brief render_3D_models
* @param aRenderTopOrBot - true will render Top, false will render bottom
* @param aRenderTransparentOnly - true will render only the transparent
* objects, false will render opaque
* @param aRenderTopOrBot true will render Top, false will render bottom
* @param aRenderTransparentOnly true will render only the transparent objects, false will
* render opaque
*/
void render_3D_models( bool aRenderTopOrBot, bool aRenderTransparentOnly );
@ -207,6 +175,11 @@ private:
void render_3D_arrows();
/**
* Create a 3D grid to an OpenGL display list.
*
* A horizontal grid (XY plane and Z = 0, and a vertical grid (XZ plane and Y = 0).
*/
void generate_new_3DGrid( GRID3D_TYPE aGridType );
// Materials
@ -216,6 +189,18 @@ private:
void setPlatedCopperAndDepthOffset( PCB_LAYER_ID aLayer_id );
void unsetDepthOffset();
void set_layer_material( PCB_LAYER_ID aLayerID );
SFVEC4F get_layer_color( PCB_LAYER_ID aLayerID );
bool initializeOpenGL();
CLAYERS_OGL_DISP_LISTS* createBoard( const SHAPE_POLY_SET& aBoardPoly,
const CBVHCONTAINER2D *aThroughHoles = nullptr );
void reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter );
void ogl_set_arrow_material();
void ogl_free_all_display_lists();
struct
{
SMATERIAL m_Paste;
@ -227,11 +212,35 @@ private:
SMATERIAL m_Copper;
SMATERIAL m_Plastic;
SMATERIAL m_GrayMaterial;
}m_materials;
} m_materials;
void set_layer_material( PCB_LAYER_ID aLayerID );
SFVEC4F get_layer_color( PCB_LAYER_ID aLayerID );
MAP_OGL_DISP_LISTS m_layers;
CLAYERS_OGL_DISP_LISTS* m_platedPads_F_Cu;
CLAYERS_OGL_DISP_LISTS* m_platedPads_B_Cu;
MAP_OGL_DISP_LISTS m_layers_holes_outer;
MAP_OGL_DISP_LISTS m_layers_holes_inner;
CLAYERS_OGL_DISP_LISTS* m_board;
CLAYERS_OGL_DISP_LISTS* m_board_with_holes;
CLAYERS_OGL_DISP_LISTS* m_anti_board;
CLAYERS_OGL_DISP_LISTS* m_through_holes_outer;
CLAYERS_OGL_DISP_LISTS* m_through_holes_vias_outer;
CLAYERS_OGL_DISP_LISTS* m_through_holes_outer_ring;
CLAYERS_OGL_DISP_LISTS* m_vias_and_pad_holes_outer_contourn_and_caps;
LIST_TRIANGLES m_triangles; ///< store pointers so can be deleted latter
GLuint m_ogl_circle_texture;
GLuint m_grid; ///< oGL list that stores current grid
GRID3D_TYPE m_last_grid_type; ///< Stores the last grid computed
CLAYERS_OGL_DISP_LISTS* m_vias;
CLAYERS_OGL_DISP_LISTS* m_pad_holes;
MAP_3DMODEL m_3dmodel_map;
BOARD_ITEM* m_currentIntersectedBoardItem;
SHAPE_POLY_SET m_anti_board_poly; ///< negative polygon representation of the board outline
};
#endif // C3D_RENDER_OGL_LEGACY_H_

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2020 Oleg Endo <olegendo@gcc.gnu.org>
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -37,11 +37,16 @@
#include <wx/debug.h>
#include <chrono>
/*
* Flag to enable connectivity profiling
* @ingroup trace_env_vars
*/
const wxChar * C_OGL_3DMODEL::m_logTrace = wxT( "KI_TRACE_EDA_OGL_3DMODEL" );
void C_OGL_3DMODEL::MakeBbox( const CBBOX &aBox, unsigned int aIdxOffset,
VERTEX *aVtxOut, GLuint *aIdxOut,
const glm::vec4 &aColor )
void C_OGL_3DMODEL::MakeBbox( const CBBOX &aBox, unsigned int aIdxOffset, VERTEX *aVtxOut,
GLuint *aIdxOut, const glm::vec4 &aColor )
{
aVtxOut[0].m_pos = { aBox.Min().x, aBox.Min().y, aBox.Min().z };
aVtxOut[1].m_pos = { aBox.Max().x, aBox.Min().y, aBox.Min().z };
@ -78,8 +83,8 @@ void C_OGL_3DMODEL::MakeBbox( const CBBOX &aBox, unsigned int aIdxOffset,
#undef bbox_line
}
C_OGL_3DMODEL::C_OGL_3DMODEL( const S3DMODEL &a3DModel,
MATERIAL_MODE aMaterialMode )
C_OGL_3DMODEL::C_OGL_3DMODEL( const S3DMODEL &a3DModel, MATERIAL_MODE aMaterialMode )
{
wxLogTrace( m_logTrace, wxT( "C_OGL_3DMODEL::C_OGL_3DMODEL %u meshes %u materials" ),
static_cast<unsigned int>( a3DModel.m_MeshesSize ),
@ -152,8 +157,7 @@ C_OGL_3DMODEL::C_OGL_3DMODEL( const S3DMODEL &a3DModel,
mesh_group.m_vertices.resize( mesh_group.m_vertices.size() + mesh.m_VertexSize );
// copy vertex data and update the bounding box.
// use material color for mesh bounding box or some sort of average
// vertex color.
// use material color for mesh bounding box or some sort of average vertex color.
glm::vec3 avg_color = material.m_Diffuse;
for( unsigned int vtx_i = 0; vtx_i < mesh.m_VertexSize; ++vtx_i )
@ -233,11 +237,11 @@ C_OGL_3DMODEL::C_OGL_3DMODEL( const S3DMODEL &a3DModel,
{
if( mesh.m_FaceIdx[idx_i] >= mesh.m_VertexSize )
{
wxLogTrace( m_logTrace, wxT( " index %u out of range (%u)" ),
static_cast<unsigned int>( mesh.m_FaceIdx[idx_i] ),
static_cast<unsigned int>( mesh.m_VertexSize ) );
wxLogTrace( m_logTrace, wxT( " index %u out of range (%u)" ),
static_cast<unsigned int>( mesh.m_FaceIdx[idx_i] ),
static_cast<unsigned int>( mesh.m_VertexSize ) );
// FIXME: should skip this triangle
// FIXME: should skip this triangle
}
mesh_group.m_indices[idx_offset + idx_i] = mesh.m_FaceIdx[idx_i] + vtx_offset;
@ -277,7 +281,6 @@ C_OGL_3DMODEL::C_OGL_3DMODEL( const S3DMODEL &a3DModel,
bbox_tmp_indices.data(), GL_STATIC_DRAW );
}
// merge the mesh group geometry data.
unsigned int total_vertex_count = 0;
unsigned int total_index_count = 0;
@ -368,6 +371,7 @@ C_OGL_3DMODEL::C_OGL_3DMODEL( const S3DMODEL &a3DModel,
end_time - start_time).count() );
}
void C_OGL_3DMODEL::BeginDrawMulti( bool aUseColorInformation )
{
glEnableClientState( GL_VERTEX_ARRAY );
@ -383,6 +387,7 @@ void C_OGL_3DMODEL::BeginDrawMulti( bool aUseColorInformation )
glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
}
void C_OGL_3DMODEL::EndDrawMulti()
{
glDisable( GL_COLOR_MATERIAL );
@ -396,12 +401,12 @@ void C_OGL_3DMODEL::EndDrawMulti()
}
void C_OGL_3DMODEL::Draw(bool aTransparent, float aOpacity, bool aUseSelectedMaterial , SFVEC3F aSelectionColor ) const
void C_OGL_3DMODEL::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial,
SFVEC3F aSelectionColor ) const
{
if( aOpacity <= FLT_EPSILON )
return;
if( !glBindBuffer )
throw std::runtime_error( "The OpenGL context no longer exists: unable to draw" );
@ -428,38 +433,35 @@ void C_OGL_3DMODEL::Draw(bool aTransparent, float aOpacity, bool aUseSelectedMat
glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const float*)&param.x );
// BeginDrawMulti();
for( auto& mat : m_materials )
{
if( ( mat.IsTransparent() != aTransparent ) &&
( aOpacity >= 1.0f ) )
if( ( mat.IsTransparent() != aTransparent ) && ( aOpacity >= 1.0f ) )
continue;
switch( m_material_mode )
{
case MATERIAL_MODE::NORMAL:
OGL_SetMaterial( mat, aOpacity, aUseSelectedMaterial, aSelectionColor );
case MATERIAL_MODE::NORMAL:
OGL_SetMaterial( mat, aOpacity, aUseSelectedMaterial, aSelectionColor );
break;
case MATERIAL_MODE::DIFFUSE_ONLY:
OGL_SetDiffuseOnlyMaterial( mat.m_Diffuse, aOpacity );
case MATERIAL_MODE::DIFFUSE_ONLY:
OGL_SetDiffuseOnlyMaterial( mat.m_Diffuse, aOpacity );
break;
case MATERIAL_MODE::CAD_MODE:
OGL_SetDiffuseOnlyMaterial( MaterialDiffuseToColorCAD( mat.m_Diffuse ), aOpacity );
case MATERIAL_MODE::CAD_MODE:
OGL_SetDiffuseOnlyMaterial( MaterialDiffuseToColorCAD( mat.m_Diffuse ), aOpacity );
break;
default:
default:
break;
}
glDrawElements( GL_TRIANGLES, mat.m_render_idx_count, m_index_buffer_type,
reinterpret_cast<const void*>( mat.m_render_idx_buffer_offset ) );
}
// EndDrawMulti();
}
C_OGL_3DMODEL::~C_OGL_3DMODEL()
{
if( glDeleteBuffers )

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2020 Oleg Endo <olegendo@gcc.gnu.org>
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -37,62 +37,71 @@
#include "../3d_render_raytracing/shapes3D/cbbox.h"
#include "../../3d_enums.h"
///
class C_OGL_3DMODEL
class C_OGL_3DMODEL
{
public:
/**
* @brief C_OGL_3DMODEL - Load a 3d model. This must be called inside a gl context
* @param a3DModel: a 3d model data to load.
* @param aMaterialMode: a mode to render the materials of the model
* Load a 3d model.
*
* @note This must be called inside a gl context.
* @param a3DModel a 3d model data to load.
* @param aMaterialMode a mode to render the materials of the model.
*/
C_OGL_3DMODEL( const S3DMODEL &a3DModel, MATERIAL_MODE aMaterialMode );
~C_OGL_3DMODEL();
/**
* @brief Draw_opaque - render the model into the current context
* Render the model into the current context.
*/
void Draw_opaque( bool aUseSelectedMaterial, SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const { Draw( false, 1.0f, aUseSelectedMaterial, aSelectionColor ); }
void Draw_opaque( bool aUseSelectedMaterial,
SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const
{
Draw( false, 1.0f, aUseSelectedMaterial, aSelectionColor );
}
/**
* @brief Draw_transparent - render the model into the current context
* Render the model into the current context.
*/
void Draw_transparent( float aOpacity, bool aUseSelectedMaterial, SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const { Draw( true, aOpacity, aUseSelectedMaterial, aSelectionColor ); }
void Draw_transparent( float aOpacity, bool aUseSelectedMaterial,
SFVEC3F aSelectionColor = SFVEC3F( 0.0f ) ) const
{
Draw( true, aOpacity, aUseSelectedMaterial, aSelectionColor );
}
/**
* @brief Have_opaque - return true if have opaque meshs to render
* Return true if have opaque meshes to render.
*/
bool Have_opaque() const { return m_have_opaque_meshes; }
/**
* @brief Have_transparent - return true if have transparent meshs to render
* Return true if have transparent mesh's to render.
*/
bool Have_transparent() const { return m_have_transparent_meshes; }
/**
* @brief Draw_bbox - draw main bounding box of the model
* Draw main bounding box of the model.
*/
void Draw_bbox() const;
/**
* @brief Draw_bboxes - draw individual bounding boxes of each mesh
* Draw individual bounding boxes of each mesh.
*/
void Draw_bboxes() const;
/**
* @brief GetBBox - Get main bbox
* @return the main model bbox
* Get the main bounding box.
* @return the main model bounding box.
*/
const CBBOX &GetBBox() const { return m_model_bbox; }
/**
* @brief BeginDrawMulti - set some basic render states before drawing multiple models
* Set some basic render states before drawing multiple models.
*/
static void BeginDrawMulti( bool aUseColorInformation );
/**
* @brief EndDrawMulti - cleanup render states after drawing multiple models
* Cleanup render states after drawing multiple models.
*/
static void EndDrawMulti();
@ -155,7 +164,8 @@ private:
VERTEX *aVtxOut, GLuint *aIdxOut,
const glm::vec4 &aColor );
void Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial, SFVEC3F aSelectionColor ) const;
void Draw( bool aTransparent, float aOpacity, bool aUseSelectedMaterial,
SFVEC3F aSelectionColor ) const;
};
#endif // _C_OGL_3DMODEL_H_

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -31,18 +31,12 @@
#include <wx/image.h> // Used for save an image to disk
/**
* @brief dbg_save_rgb_buffer
* @param aFileName
* @param aRGBpixelBuffer: from wxWidget documentation
* @param aRGBpixelBuffer from the wxWidgets documentation
* "The data given must have the size (width*height*3).
* The data must have been allocated with malloc(), NOT with operator new."
* @param aXSize
* @param aYSize
*/
static void dbg_save_rgb_buffer( const wxString& aFileName,
unsigned char *aRGBpixelBuffer,
unsigned int aXSize,
unsigned int aYSize )
static void dbg_save_rgb_buffer( const wxString& aFileName, unsigned char *aRGBpixelBuffer,
unsigned int aXSize, unsigned int aYSize )
{
wxImage image( aXSize, aYSize );
image.SetData( aRGBpixelBuffer );
@ -52,10 +46,8 @@ static void dbg_save_rgb_buffer( const wxString& aFileName,
}
void DBG_SaveBuffer( const wxString& aFileName,
const unsigned char *aInBuffer,
unsigned int aXSize,
unsigned int aYSize )
void DBG_SaveBuffer( const wxString& aFileName, const unsigned char *aInBuffer,
unsigned int aXSize, unsigned int aYSize )
{
const unsigned int wxh = aXSize * aYSize;
@ -75,10 +67,8 @@ void DBG_SaveBuffer( const wxString& aFileName,
}
void DBG_SaveBuffer( const wxString& aFileName,
const float *aInBuffer,
unsigned int aXSize,
unsigned int aYSize )
void DBG_SaveBuffer( const wxString& aFileName, const float *aInBuffer,
unsigned int aXSize, unsigned int aYSize )
{
const unsigned int wxh = aXSize * aYSize;
@ -86,8 +76,7 @@ void DBG_SaveBuffer( const wxString& aFileName,
for( unsigned int i = 0; i < wxh; ++i )
{
const unsigned char v = (unsigned char)glm::min( (int)(aInBuffer[i] * 255.0f),
255 );
const unsigned char v = (unsigned char)glm::min( (int)(aInBuffer[i] * 255.0f), 255 );
// Set RGB value with all same values intensities
pixelbuffer[i * 3 + 0] = v;
@ -99,10 +88,8 @@ void DBG_SaveBuffer( const wxString& aFileName,
}
void DBG_SaveBuffer( const wxString& aFileName,
const SFVEC3F *aInBuffer,
unsigned int aXSize,
unsigned int aYSize )
void DBG_SaveBuffer( const wxString& aFileName, const SFVEC3F *aInBuffer,
unsigned int aXSize, unsigned int aYSize )
{
const unsigned int wxh = aXSize * aYSize;
@ -114,19 +101,17 @@ void DBG_SaveBuffer( const wxString& aFileName,
const unsigned int ix3 = i * 3;
// Set RGB value with all same values intensities
pixelbuffer[ix3 + 0] = (unsigned char)glm::min( (int)(v.r * 255.0f), 255 );
pixelbuffer[ix3 + 1] = (unsigned char)glm::min( (int)(v.g * 255.0f), 255 );
pixelbuffer[ix3 + 2] = (unsigned char)glm::min( (int)(v.b * 255.0f), 255 );
pixelbuffer[ix3 + 0] = (unsigned char) glm::min( (int) ( v.r * 255.0f ), 255 );
pixelbuffer[ix3 + 1] = (unsigned char) glm::min( (int) ( v.g * 255.0f ), 255 );
pixelbuffer[ix3 + 2] = (unsigned char) glm::min( (int) ( v.b * 255.0f ), 255 );
}
dbg_save_rgb_buffer( aFileName, pixelbuffer, aXSize, aYSize );
}
void DBG_SaveNormalsBuffer( const wxString& aFileName,
const SFVEC3F *aInNormalsBuffer,
unsigned int aXSize,
unsigned int aYSize )
void DBG_SaveNormalsBuffer( const wxString& aFileName, const SFVEC3F *aInNormalsBuffer,
unsigned int aXSize, unsigned int aYSize )
{
const unsigned int wxh = aXSize * aYSize;
@ -138,9 +123,9 @@ void DBG_SaveNormalsBuffer( const wxString& aFileName,
const unsigned int ix3 = i * 3;
// Set RGB value with all same values intensities
pixelbuffer[ix3 + 0] = (unsigned char)glm::min( (int)((v.r + 1.0f) * 127.0f), 255 );
pixelbuffer[ix3 + 1] = (unsigned char)glm::min( (int)((v.g + 1.0f) * 127.0f), 255 );
pixelbuffer[ix3 + 2] = (unsigned char)glm::min( (int)((v.b + 1.0f) * 127.0f), 255 );
pixelbuffer[ix3 + 0] = (unsigned char) glm::min( (int) ( ( v.r + 1.0f ) * 127.0f ), 255 );
pixelbuffer[ix3 + 1] = (unsigned char) glm::min( (int) ( ( v.g + 1.0f ) * 127.0f ), 255 );
pixelbuffer[ix3 + 2] = (unsigned char) glm::min( (int) ( ( v.b + 1.0f ) * 127.0f ), 255 );
}
dbg_save_rgb_buffer( aFileName, pixelbuffer, aXSize, aYSize );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -33,23 +33,16 @@
#include <plugins/3dapi/xv3d_types.h>
#include <wx/string.h>
void DBG_SaveBuffer( const wxString& aFileName,
const unsigned char *aInBuffer,
void DBG_SaveBuffer( const wxString& aFileName, const unsigned char *aInBuffer,
unsigned int aXSize, unsigned int aYSize );
void DBG_SaveBuffer( const wxString& aFileName,
const float *aInBuffer,
unsigned int aXSize,
unsigned int aYSize );
void DBG_SaveBuffer( const wxString& aFileName, const float *aInBuffer,
unsigned int aXSize, unsigned int aYSize );
void DBG_SaveBuffer( const wxString& aFileName,
const SFVEC3F *aInBuffer,
unsigned int aXSize,
unsigned int aYSize );
void DBG_SaveBuffer( const wxString& aFileName, const SFVEC3F *aInBuffer,
unsigned int aXSize, unsigned int aYSize );
void DBG_SaveNormalsBuffer( const wxString& aFileName,
const SFVEC3F *aInNormalsBuffer,
unsigned int aXSize,
unsigned int aYSize );
void DBG_SaveNormalsBuffer( const wxString& aFileName, const SFVEC3F *aInNormalsBuffer,
unsigned int aXSize, unsigned int aYSize );
#endif // BUFFER_DEBUG_H

View File

@ -33,11 +33,14 @@
/**
* Trace mask used to enable or disable the trace output of this class.
*
* The debug output can be turned on by setting the WXTRACE environment variable to
* "KI_TRACE_3D_RENDER". See the wxWidgets documentation on wxLogTrace for
* more information.
*
* @ingroup trace_env_vars
*/
const wxChar * C3D_RENDER_BASE::m_logTrace = wxT( "KI_TRACE_3D_RENDER" );
const wxChar* C3D_RENDER_BASE::m_logTrace = wxT( "KI_TRACE_3D_RENDER" );
C3D_RENDER_BASE::C3D_RENDER_BASE( BOARD_ADAPTER& aBoardAdapter, CCAMERA& aCamera ) :

View File

@ -42,50 +42,46 @@
*/
class C3D_RENDER_BASE
{
// Operations
public:
explicit C3D_RENDER_BASE( BOARD_ADAPTER& aBoardAdapter, CCAMERA& aCamera );
virtual ~C3D_RENDER_BASE() = 0;
/**
* @brief SetCurWindowSize - Before each render, the canvas will tell the
* render what is the size of its windows, so render can take actions if it
* changed.
* @param aSize: the current size of the render window
* Before each render, the canvas will tell the render what is the size of its windows,
* so render can take actions if it changed.
*
* @param aSize the current size of the render window
*/
virtual void SetCurWindowSize( const wxSize &aSize ) = 0;
/**
* @brief Redraw - Ask to redraw the view
* @param aIsMoving: if the user is moving the scene, it should be render in
* preview mode
* @param aStatusReporter: a pointer to the status progress reporter
* @return it will return true if the render would like to redraw again
* Redraw the view.
*
* @param aIsMoving if the user is moving the scene, it should be render in preview mode.
* @param aStatusReporter a pointer to the status progress reporter.
* @return true if the render would like to redraw again.
*/
virtual bool Redraw( bool aIsMoving, REPORTER* aStatusReporter = NULL,
REPORTER* aWarningReporter = NULL ) = 0;
/**
* @brief ReloadRequest - !TODO: this must be reviewed to add flags to
* improve specific render
* @todo This must be reviewed to add flags to improve specific render.
*/
void ReloadRequest() { m_reloadRequested = true; }
/**
* @brief IsReloadRequestPending - Query if there is a pending reload request
* Query if there is a pending reload request.
*
* @return true if it wants to reload, false if there is no reload pending
*/
bool IsReloadRequestPending() const { return m_reloadRequested; }
/**
* @brief GetWaitForEditingTimeOut - Give the interface the time (in ms)
* that it should wait for editing or movements before
* (this works for display preview mode)
* @return a value in miliseconds
* Give the interface the time (in ms) that it should wait for editing or movements before
* (this works for display preview mode).
*
* @return a value in milliseconds
*/
virtual int GetWaitForEditingTimeOut() = 0;
@ -97,27 +93,24 @@ public:
*/
void SetBusyIndicatorFactory( BUSY_INDICATOR::FACTORY aNewFactory );
// Attributes
protected:
/**
* Return a created busy indicator, if a factory has been set, else
* a null pointer.
* Return a created busy indicator, if a factory has been set, else a null pointer.
*/
std::unique_ptr<BUSY_INDICATOR> CreateBusyIndicator() const;
/// settings refrence in use for this render
///< Settings reference in use for this render.
BOARD_ADAPTER& m_boardAdapter;
CCAMERA& m_camera;
/// flag if the opengl specific for this render was already initialized
///< Flag if the opengl specific for this render was already initialized.
bool m_is_opengl_initialized;
/// !TODO: this must be reviewed in order to flag change types
///< @todo This must be reviewed in order to flag change types.
bool m_reloadRequested;
/// The window size that this camera is working.
///< The window size that this camera is working.
wxSize m_windowSize;
/**
@ -129,7 +122,7 @@ protected:
static const wxChar *m_logTrace;
private:
/// Factory that returns a suitable busy indicator for the context.
///< Factory that returns a suitable busy indicator for the context.
BUSY_INDICATOR::FACTORY m_busyIndicatorFactory;
};

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -43,16 +43,15 @@ inline void normalise2PI( float& aAngle )
/**
* Trace mask used to enable or disable the trace output of this class.
* The debug output can be turned on by setting the WXTRACE environment variable to
* "KI_TRACE_CCAMERA". See the wxWidgets documentation on wxLogTrace for
* more information.
* @ingroup trace_env_vars
*/
const wxChar *CCAMERA::m_logTrace = wxT( "KI_TRACE_CCAMERA" );
#define MIN_ZOOM 0.10f
#define MAX_ZOOM 1.25f
CCAMERA::CCAMERA( float aRangeScale )
{
wxLogTrace( m_logTrace, wxT( "CCAMERA::CCAMERA" ) );
@ -107,7 +106,6 @@ void CCAMERA::Reset_T1()
m_rotate_aux_t1 = SFVEC3F( 0.0f );
m_lookat_pos_t1 = m_board_lookat_pos_init;
// Since 0 = 2pi, we want to reset the angle to be the closest
// one to where we currently are. That ensures that we rotate
// the board around the smallest distance getting there.
@ -162,14 +160,12 @@ const glm::mat4 CCAMERA::GetRotationMatrix() const
void CCAMERA::rebuildProjection()
{
if( (m_windowSize.x == 0) ||
(m_windowSize.y == 0) )
if( ( m_windowSize.x == 0 ) || ( m_windowSize.y == 0 ) )
return;
m_frustum.ratio = (float) m_windowSize.x / (float)m_windowSize.y;
// Consider that we can render double the length multiplied by the 2/sqrt(2)
//
m_frustum.farD = glm::length( m_camera_pos_init ) * 2.0f * ( 2.0f * sqrtf( 2.0f ) );
switch( m_projectionType )
@ -182,7 +178,6 @@ void CCAMERA::rebuildProjection()
// Ratio width / height of the window display
m_frustum.angle = 45.0f * m_zoom;
m_projectionMatrix = glm::perspective( glm::radians( m_frustum.angle ),
m_frustum.ratio,
m_frustum.nearD,
@ -209,7 +204,7 @@ void CCAMERA::rebuildProjection()
const float orthoReductionFactor = glm::length( m_camera_pos_init ) *
m_zoom * m_zoom * 0.5f;
// Initialize Projection Matrix for Ortographic View
// Initialize Projection Matrix for Orthographic View
m_projectionMatrix = glm::ortho( -m_frustum.ratio * orthoReductionFactor,
m_frustum.ratio * orthoReductionFactor,
-orthoReductionFactor,
@ -226,8 +221,7 @@ void CCAMERA::rebuildProjection()
break;
}
if ( (m_windowSize.x > 0) &&
(m_windowSize.y > 0) )
if( ( m_windowSize.x > 0 ) && ( m_windowSize.y > 0 ) )
{
m_scr_nX.resize( m_windowSize.x + 1 );
m_scr_nY.resize( m_windowSize.y + 1 );
@ -275,7 +269,6 @@ void CCAMERA::updateFrustum()
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/
@ -297,8 +290,7 @@ void CCAMERA::updateFrustum()
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;
if ( (m_windowSize.x > 0) &&
(m_windowSize.y > 0) )
if( ( m_windowSize.x > 0 ) && ( m_windowSize.y > 0 ) )
{
// Reserve size for precalc values
m_right_nX.resize( m_windowSize.x + 1 );
@ -307,27 +299,25 @@ void CCAMERA::updateFrustum()
// 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 + 1); ++x )
for( unsigned int x = 0; x < ( (unsigned int) m_windowSize.x + 1 ); ++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 + 1); ++y )
for( unsigned int y = 0; y < ( (unsigned int) m_windowSize.y + 1 ); ++y )
m_up_nY[y] = up_nh * m_scr_nY[y];
}
}
void CCAMERA::MakeRay( const SFVEC2I &aWindowPos,
SFVEC3F &aOutOrigin,
void CCAMERA::MakeRay( const SFVEC2I &aWindowPos, SFVEC3F &aOutOrigin,
SFVEC3F &aOutDirection ) const
{
wxASSERT( aWindowPos.x < m_windowSize.x );
wxASSERT( aWindowPos.y < m_windowSize.y );
const SFVEC3F up_plus_right = m_up_nY[aWindowPos.y] +
m_right_nX[aWindowPos.x];
const SFVEC3F up_plus_right = m_up_nY[aWindowPos.y] + m_right_nX[aWindowPos.x];
switch( m_projectionType )
{
@ -345,7 +335,8 @@ void CCAMERA::MakeRay( const SFVEC2I &aWindowPos,
}
void CCAMERA::MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const
void CCAMERA::MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin,
SFVEC3F &aOutDirection ) const
{
wxASSERT( aWindowPos.x < (float)m_windowSize.x );
wxASSERT( aWindowPos.y < (float)m_windowSize.y );
@ -376,11 +367,9 @@ void CCAMERA::MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &
}
void CCAMERA::MakeRayAtCurrrentMousePosition( SFVEC3F &aOutOrigin,
SFVEC3F &aOutDirection ) const
void CCAMERA::MakeRayAtCurrrentMousePosition( SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const
{
const SFVEC2I windowPos = SFVEC2I( m_lastPosition.x,
m_windowSize.y - m_lastPosition.y );
const SFVEC2I windowPos = SFVEC2I( m_lastPosition.x, m_windowSize.y - m_lastPosition.y );
if( ( 0 < windowPos.x ) && ( windowPos.x < m_windowSize.x ) &&
( 0 < windowPos.y ) && ( windowPos.y < m_windowSize.y ) )
@ -477,12 +466,15 @@ void CCAMERA::ZoomReset()
bool CCAMERA::Zoom( float aFactor )
{
if ( ( m_zoom == MIN_ZOOM && aFactor > 1 ) || ( m_zoom == MAX_ZOOM && aFactor < 1 ) || aFactor == 1 )
if( ( m_zoom == MIN_ZOOM && aFactor > 1 ) || ( m_zoom == MAX_ZOOM && aFactor < 1 )
|| aFactor == 1 )
return false;
m_zoom /= aFactor;
if( m_zoom <= MIN_ZOOM )
m_zoom = MIN_ZOOM;
if( m_zoom >= MAX_ZOOM )
m_zoom = MAX_ZOOM;
@ -494,15 +486,19 @@ bool CCAMERA::Zoom( float aFactor )
return true;
}
bool CCAMERA::Zoom_T1( float aFactor )
{
if( ( m_zoom == MIN_ZOOM && aFactor > 1 ) || ( m_zoom == MAX_ZOOM && aFactor < 1 ) || aFactor == 1 )
if( ( m_zoom == MIN_ZOOM && aFactor > 1 ) || ( m_zoom == MAX_ZOOM && aFactor < 1 )
|| aFactor == 1 )
return false;
m_zoom_t1 = m_zoom / aFactor;
if (m_zoom_t1 < MIN_ZOOM )
if( m_zoom_t1 < MIN_ZOOM )
m_zoom_t1 = MIN_ZOOM;
if (m_zoom_t1 > MAX_ZOOM )
if( m_zoom_t1 > MAX_ZOOM )
m_zoom_t1 = MAX_ZOOM;
m_camera_pos_t1.z = m_camera_pos_init.z * m_zoom_t1;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -41,7 +41,6 @@ enum class PROJECTION_TYPE
};
/**
* Frustum structure
* Frustum is a implementation based on a tutorial by
* http://www.lighthouse3d.com/tutorials/view-frustum-culling/
*/
@ -71,21 +70,19 @@ enum class CAMERA_INTERPOLATION
/**
* Class CCAMERA
* is a virtual class used to derive CCAMERA objects from.
* A class used to derive camera objects from.
*
* It must be derived to other classes to implement a real camera object.
* It must be derived by other classes to implement a real camera object.
*/
class CCAMERA
{
public:
public:
/**
* @brief CCAMERA initialize a camera
* @param aRangeScale: it will be expected that the board will have a
* -aRangeScale/2 to +aRangeScale/2
* it will initialize the initial Z position with aRangeScale
* Initialize a camera.
*
* @param aRangeScale it will be expected that the board will have a
* -aRangeScale/2 to +aRangeScale/2. It will initialize the
* Z position with aRangeScale.
*/
explicit CCAMERA( float aRangeScale );
@ -95,8 +92,8 @@ class CCAMERA
/**
* Function GetRotationMatrix
* Get the rotation matrix to be applied in a transformation camera
* Get the rotation matrix to be applied in a transformation camera.
*
* @return the rotation matrix of the camera
*/
const glm::mat4 GetRotationMatrix() const;
@ -115,7 +112,8 @@ class CCAMERA
float GetNear() const { return m_frustum.nearD; }
float GetFar() const { return m_frustum.farD; }
void SetBoardLookAtPos( const SFVEC3F &aBoardPos ) {
void SetBoardLookAtPos( const SFVEC3F &aBoardPos )
{
if( m_board_lookat_pos_init != aBoardPos )
{
m_board_lookat_pos_init = aBoardPos;
@ -125,7 +123,8 @@ class CCAMERA
virtual void SetLookAtPos( const SFVEC3F &aLookAtPos ) = 0;
void SetLookAtPos_T1( const SFVEC3F &aLookAtPos ) {
void SetLookAtPos_T1( const SFVEC3F &aLookAtPos )
{
m_lookat_pos_t1 = aLookAtPos;
}
@ -144,7 +143,6 @@ class CCAMERA
virtual void Pan_T1( const SFVEC3F &aDeltaOffsetInc ) = 0;
/**
* Reset the camera to initial state
*/
@ -155,8 +153,7 @@ class CCAMERA
void ResetXYpos_T1();
/**
* It updates the current mouse position without make any new recalculations
* on camera.
* Update the current mouse position without make any new calculations on camera.
*/
void SetCurMousePosition( const wxPoint &aPosition );
@ -164,9 +161,9 @@ class CCAMERA
PROJECTION_TYPE GetProjection() { return m_projectionType; }
/**
* @brief SetCurWindowSize - update the windows size of the camera
* @param aSize
* @return true if the windows size changed since last time
* Update the windows size of the camera.
*
* @return true if the windows size changed since last time.
*/
bool SetCurWindowSize( const wxSize &aSize );
@ -187,13 +184,14 @@ class CCAMERA
void RotateZ_T1( float aAngleInRadians );
/**
* @brief SetT0_and_T1_current_T - This will set T0 and T1 with the current values
* This will set T0 and T1 with the current values.
*/
virtual void SetT0_and_T1_current_T();
/**
* @brief Interpolate - It will update the matrix to interpolate between T0 and T1 values
* @param t the interpolation time, between 0.0f and 1.0f (it will clamp if >1)
* It will update the matrix to interpolate between T0 and T1 values.
*
* @param t the interpolation time, between 0.0f and 1.0f (it will clamp if >1).
*/
virtual void Interpolate( float t );
@ -203,44 +201,43 @@ class CCAMERA
}
/**
* Function ParametersChanged
* @return true if some of the parameters in camera was changed,
* it will reset the flag
* @return true if some of the parameters in camera was changed, it will reset the flag.
*/
bool ParametersChanged();
/**
* Function ParametersChangedQuery
* @return true if some of the parameters in camera was changed,
* it will NOT reset the flag
* @return true if some of the parameters in camera was changed, it will NOT reset the flag.
*/
bool ParametersChangedQuery() const { return m_parametersChanged; }
/**
* @brief MakeRay - Make a ray based on a windows screen position
* @param aWindowPos: the windows buffer position
* @param aOutOrigin: out origin position of the ray
* @param aOutDirection: out direction
* Make a ray based on a windows screen position.
*
* @param aWindowPos the windows buffer position.
* @param aOutOrigin out origin position of the ray.
* @param aOutDirection out direction
*/
void MakeRay( const SFVEC2I &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const;
/**
* @brief MakeRay - Make a ray based on a windows screen position, it will interpolate based on the float aWindowPos
* @param aWindowPos: the windows buffer position (float value)
* @param aOutOrigin: out origin position of the ray
* @param aOutDirection: out direction
* Make a ray based on a windows screen position, it will interpolate based on the
* \a aWindowPos.
*
* @param aWindowPos the windows buffer position (float value).
* @param aOutOrigin out origin position of the ray.
* @param aOutDirection out direction.
*/
void MakeRay( const SFVEC2F &aWindowPos, SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const;
/**
* @brief MakeRayAtCurrrentMousePosition - Make a ray based on the latest mouse position
* @param aOutOrigin: out origin position of the ray
* @param aOutDirection: out direction
* Make a ray based on the latest mouse position.
*
* @param aOutOrigin out origin position of the ray.
* @param aOutDirection out direction.
*/
void MakeRayAtCurrrentMousePosition( SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection ) const;
protected:
protected:
void rebuildProjection();
void updateFrustum();
void updateViewMatrix();
@ -248,25 +245,26 @@ class CCAMERA
void updateRotationMatrix();
/**
* @brief m_range_scale - the nominal range expected to be used in the camera.
* The nominal range expected to be used in the camera.
*
* It will be used to initialize the Z position
*/
float m_range_scale;
/**
* 3D zoom value (Min 0.0 ... Max 1.0)
* 3D zoom value (Min 0.0 ... Max 1.0)
*/
float m_zoom;
float m_zoom_t0;
float m_zoom_t1;
/**
* The window size that this camera is working.
* The window size that this camera is working.
*/
SFVEC2I m_windowSize;
/**
* The last mouse position in the screen
* The last mouse position in the screen
*/
wxPoint m_lastPosition;
@ -295,39 +293,38 @@ class CCAMERA
SFVEC3F m_lookat_pos;
SFVEC3F m_lookat_pos_t0;
SFVEC3F m_lookat_pos_t1;
SFVEC3F m_board_lookat_pos_init; ///< Default boardlookat position (the board center)
SFVEC3F m_board_lookat_pos_init; ///< Default boardlookat position (the board center).
SFVEC3F m_rotate_aux; ///< Stores the rotation angle auxiliar
SFVEC3F m_rotate_aux; ///< Stores the rotation angle auxiliary.
SFVEC3F m_rotate_aux_t0;
SFVEC3F m_rotate_aux_t1;
CAMERA_INTERPOLATION m_interpolation_mode;
/**
* Precalc values array used to calc ray for each pixel
* (constant for the same window size)
* Precalc values array used to calc ray for each pixel (constant for the same window size).
*/
std::vector< float > m_scr_nX;
std::vector< float > m_scr_nY;
/**
* Precalc values array used to calc ray for each pixel,
* for X and Y axis of each new camera position
* Precalc values array used to calc ray for each pixel, for X and Y axis of each new
* camera position.
*/
std::vector< SFVEC3F > m_right_nX;
std::vector< SFVEC3F > m_up_nY;
/**
* Set to true if any of the parameters in the camera was changed
* Set to true if any of the parameters in the camera was changed
*/
bool m_parametersChanged;
/**
* Trace mask used to enable or disable the trace output of this class.
* The debug output can be turned on by setting the WXTRACE environment variable to
* "KI_TRACE_CCAMERA". See the wxWidgets documentation on wxLogTrace for
* more information.
* Trace mask used to enable or disable the trace output of this class.
*
* The debug output can be turned on by setting the WXTRACE environment variable to
* "KI_TRACE_CCAMERA". See the wxWidgets documentation on wxLogTrace for
* more information.
*/
static const wxChar *m_logTrace;
};

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -33,9 +33,9 @@
CCOLORRGB::CCOLORRGB( const SFVEC3F &aColor )
{
r = (unsigned int)glm::clamp( (int)(aColor.r * 255), 0, 255 );
g = (unsigned int)glm::clamp( (int)(aColor.g * 255), 0, 255 );
b = (unsigned int)glm::clamp( (int)(aColor.b * 255), 0, 255 );
r = (unsigned int) glm::clamp( (int) ( aColor.r * 255 ), 0, 255 );
g = (unsigned int) glm::clamp( (int) ( aColor.g * 255 ), 0, 255 );
b = (unsigned int) glm::clamp( (int) ( aColor.b * 255 ), 0, 255 );
}
@ -45,7 +45,7 @@ CCOLORRGB BlendColor( const CCOLORRGB &aC1, const CCOLORRGB &aC2 )
const unsigned int g = aC1.g + aC2.g;
const unsigned int b = aC1.b + aC2.b;
return CCOLORRGB( (r >> 1), (g >> 1), (b >> 1) );
return CCOLORRGB( ( r >> 1 ), ( g >> 1 ), ( b >> 1 ) );
}
@ -55,18 +55,16 @@ CCOLORRGB BlendColor( const CCOLORRGB &aC1, const CCOLORRGB &aC2, const CCOLORRG
const unsigned int g = aC1.g + aC2.g + aC3.g;
const unsigned int b = aC1.b + aC2.b + aC3.b;
return CCOLORRGB( (r / 3), (g / 3), (b / 3) );
return CCOLORRGB( ( r / 3 ), ( g / 3 ), ( b / 3 ) );
}
CCOLORRGB BlendColor( const CCOLORRGB &aC1,
const CCOLORRGB &aC2,
const CCOLORRGB &aC3,
CCOLORRGB BlendColor( const CCOLORRGB &aC1, const CCOLORRGB &aC2, const CCOLORRGB &aC3,
const CCOLORRGB &aC4 )
{
const unsigned int r = aC1.r + aC2.r + aC3.r + aC4.r;
const unsigned int g = aC1.g + aC2.g + aC3.g + aC4.g;
const unsigned int b = aC1.b + aC2.b + aC3.b + aC4.b;
return CCOLORRGB( (r >> 2), (g >> 2), (b >> 2) );
return CCOLORRGB( ( r >> 2 ), ( g >> 2 ), ( b >> 2 ) );
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -45,16 +45,18 @@ union CCOLORRGB
CCOLORRGB( const SFVEC3F &aColor );
CCOLORRGB() { r = 0; g = 0; b = 0; }
CCOLORRGB( unsigned char aR, unsigned char aG, unsigned char aB ) { r = aR;
g = aG;
b = aB; }
CCOLORRGB( unsigned char aR, unsigned char aG, unsigned char aB )
{
r = aR;
g = aG;
b = aB;
}
};
CCOLORRGB BlendColor( const CCOLORRGB &aC1, const CCOLORRGB &aC2 );
CCOLORRGB BlendColor( const CCOLORRGB &aC1, const CCOLORRGB &aC2, const CCOLORRGB &aC3 );
CCOLORRGB BlendColor( const CCOLORRGB &aC1,
const CCOLORRGB &aC2,
const CCOLORRGB &aC3,
CCOLORRGB BlendColor( const CCOLORRGB &aC1, const CCOLORRGB &aC2, const CCOLORRGB &aC3,
const CCOLORRGB &aC4 );
#endif // CCOLORRGB_H

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -36,8 +36,9 @@
#include <thread>
#include <chrono>
#ifndef CLAMP
#define CLAMP(n, min, max) {if( n < min ) n=min; else if( n > max ) n = max;}
#define CLAMP( n, min, max ) {if( n < min ) n=min; else if( n > max ) n = max;}
#endif
@ -80,28 +81,27 @@ bool CIMAGE::wrapCoords( int *aXo, int *aYo ) const
int x = *aXo;
int y = *aYo;
switch(m_wraping)
switch( m_wraping )
{
case IMAGE_WRAP::CLAMP:
x = (x < 0 )?0:x;
x = (x >= (int)(m_width - 1))?(m_width - 1):x;
y = (y < 0)?0:y;
y = (y >= (int)(m_height - 1))?(m_height - 1):y;
x = ( x < 0 ) ? 0 : x;
x = ( x >= (int) ( m_width - 1 ) ) ? ( m_width - 1 ) : x;
y = ( y < 0 ) ? 0 : y;
y = ( y >= (int) ( m_height - 1 ) ) ? ( m_height - 1 ) : y;
break;
case IMAGE_WRAP::WRAP:
x = (x < 0)?((m_width - 1)+x):x;
x = (x >= (int)(m_width - 1))?(x - m_width):x;
y = (y < 0)?((m_height - 1)+y):y;
y = (y >= (int)(m_height - 1))?(y - m_height):y;
x = ( x < 0 ) ? ( ( m_width - 1 ) + x ) : x;
x = ( x >= (int) ( m_width - 1 ) ) ? ( x - m_width ) : x;
y = ( y < 0 ) ? ( ( m_height - 1 ) + y ) : y;
y = ( y >= (int) ( m_height - 1 ) ) ? ( y - m_height ) : y;
break;
default:
break;
}
if( (x < 0) || (x >= (int)m_width) ||
(y < 0) || (y >= (int)m_height) )
if( ( x < 0 ) || ( x >= (int) m_width ) || ( y < 0 ) || ( y >= (int) m_height ) )
return false;
*aXo = x;
@ -110,6 +110,7 @@ bool CIMAGE::wrapCoords( int *aXo, int *aYo ) const
return true;
}
void CIMAGE::plot8CircleLines( int aCx, int aCy, int aX, int aY, unsigned char aValue )
{
Hline( aCx - aX, aCx + aX, aCy + aY, aValue );
@ -137,10 +138,8 @@ unsigned char CIMAGE::Getpixel( int aX, int aY ) const
void CIMAGE::Hline( int aXStart, int aXEnd, int aY, unsigned char aValue )
{
if( ( aY < 0 ) ||
( aY >= (int)m_height ) ||
( ( aXStart < 0 ) && ( aXEnd < 0) ) ||
( ( aXStart >= (int)m_width ) && ( aXEnd >= (int)m_width) ) )
if( ( aY < 0 ) || ( aY >= (int) m_height ) || ( ( aXStart < 0 ) && ( aXEnd < 0 ) )
|| ( ( aXStart >= (int) m_width ) && ( aXEnd >= (int) m_width ) ) )
return;
if( aXStart > aXEnd )
@ -159,7 +158,7 @@ void CIMAGE::Hline( int aXStart, int aXEnd, int aY, unsigned char aValue )
aXEnd = m_width - 1;
unsigned char* pixelPtr = &m_pixels[aXStart + aY * m_width];
unsigned char* pixelPtrEnd = pixelPtr + (unsigned int)((aXEnd - aXStart) + 1);
unsigned char* pixelPtrEnd = pixelPtr + (unsigned int) ( ( aXEnd - aXStart ) + 1 );
while( pixelPtr < pixelPtrEnd )
{
@ -168,9 +167,10 @@ void CIMAGE::Hline( int aXStart, int aXEnd, int aY, unsigned char aValue )
}
}
// Based on paper
// http://web.engr.oregonstate.edu/~sllu/bcircle.pdf
void CIMAGE::CircleFilled(int aCx, int aCy, int aRadius, unsigned char aValue)
void CIMAGE::CircleFilled( int aCx, int aCy, int aRadius, unsigned char aValue )
{
int x = aRadius;
int y = 0;
@ -185,7 +185,7 @@ void CIMAGE::CircleFilled(int aCx, int aCy, int aRadius, unsigned char aValue)
radiusError += yChange;
yChange += 2;
if( (2 * radiusError + xChange) > 0 )
if( ( 2 * radiusError + xChange ) > 0 )
{
x--;
radiusError += xChange;
@ -213,15 +213,15 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera
}
else
{
if( (aImgA == NULL) || (aImgB == NULL) )
if( ( aImgA == NULL ) || ( aImgB == NULL ) )
return;
}
switch(aOperation)
switch( aOperation )
{
case IMAGE_OP::RAW:
memcpy( m_pixels, aImgA->m_pixels, m_wxh );
break;
break;
case IMAGE_OP::ADD:
for( unsigned int it = 0;it < m_wxh; it++ )
@ -234,7 +234,7 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera
m_pixels[it] = aV;
}
break;
break;
case IMAGE_OP::SUB:
for( unsigned int it = 0;it < m_wxh; it++ )
@ -247,7 +247,7 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera
m_pixels[it] = aV;
}
break;
break;
case IMAGE_OP::DIF:
for( unsigned int it = 0;it < m_wxh; it++ )
@ -257,7 +257,7 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera
m_pixels[it] = abs( aV - bV );
}
break;
break;
case IMAGE_OP::MUL:
for( unsigned int it = 0;it < m_wxh; it++ )
@ -265,30 +265,31 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera
aV = aImgA->m_pixels[it];
bV = aImgB->m_pixels[it];
m_pixels[it] = (unsigned char)((((float)aV / 255.0f) * ((float)bV / 255.0f)) * 255);
m_pixels[it] =
(unsigned char) ( ( ( (float) aV / 255.0f ) * ( (float) bV / 255.0f ) ) * 255 );
}
break;
break;
case IMAGE_OP::AND:
for( unsigned int it = 0;it < m_wxh; it++ )
{
m_pixels[it] = aImgA->m_pixels[it] & aImgB->m_pixels[it];
}
break;
break;
case IMAGE_OP::OR:
for( unsigned int it = 0;it < m_wxh; it++ )
{
m_pixels[it] = aImgA->m_pixels[it] | aImgB->m_pixels[it];
}
break;
break;
case IMAGE_OP::XOR:
for( unsigned int it = 0;it < m_wxh; it++ )
{
m_pixels[it] = aImgA->m_pixels[it] ^ aImgB->m_pixels[it];
}
break;
break;
case IMAGE_OP::BLEND50:
for( unsigned int it = 0;it < m_wxh; it++ )
@ -298,7 +299,7 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera
m_pixels[it] = (aV + bV) / 2;
}
break;
break;
case IMAGE_OP::MIN:
for( unsigned int it = 0;it < m_wxh; it++ )
@ -308,7 +309,7 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera
m_pixels[it] = (aV < bV)?aV:bV;
}
break;
break;
case IMAGE_OP::MAX:
for( unsigned int it = 0;it < m_wxh; it++ )
@ -318,13 +319,14 @@ void CIMAGE::CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOpera
m_pixels[it] = (aV > bV)?aV:bV;
}
break;
break;
default:
break;
break;
}
}
// TIP: If you want create or test filters you can use GIMP
// with a generic convolution matrix and get the values from there.
// http://docs.gimp.org/nl/plug-in-convmatrix.html
@ -465,10 +467,10 @@ static const S_FILTER FILTERS[] = {
// clang-format on
// !TODO: This functions can be optimized slipting it between the edges and
// do it without use the getpixel function.
// Optimization can be done to m_pixels[ix + iy * m_width]
// but keep in mind the parallel process of the algorithm
/// @todo: This function can be optimized slipping it between the edges and
/// do it without use the getpixel function.
/// Optimization can be done to m_pixels[ix + iy * m_width]
/// but keep in mind the parallel process of the algorithm
void CIMAGE::EfxFilter( CIMAGE* aInImg, IMAGE_FILTER aFilterType )
{
S_FILTER filter = FILTERS[static_cast<int>( aFilterType )];
@ -486,8 +488,8 @@ void CIMAGE::EfxFilter( CIMAGE* aInImg, IMAGE_FILTER aFilterType )
std::thread t = std::thread( [&]()
{
for( size_t iy = nextRow.fetch_add( 1 );
iy < m_height;
iy = nextRow.fetch_add( 1 ) )
iy < m_height;
iy = nextRow.fetch_add( 1 ) )
{
for( size_t ix = 0; ix < m_width; ix++ )
{
@ -508,7 +510,8 @@ void CIMAGE::EfxFilter( CIMAGE* aInImg, IMAGE_FILTER aFilterType )
v /= filter.div;
v += filter.offset;
CLAMP(v, 0, 255);
//TODO: This needs to write to a separate buffer
/// @todo This needs to write to a separate buffer.
m_pixels[ix + iy * m_width] = v;
}
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -54,7 +54,7 @@ enum class IMAGE_WRAP
{
ZERO, ///< Coords that wraps are not evaluated
CLAMP, ///< Coords are clamped to image size
WRAP ///< Coords are wrapped arround
WRAP ///< Coords are wrapped around
};
@ -75,34 +75,33 @@ enum class IMAGE_FILTER
};
/// 5x5 Filter struct parameters
typedef struct {
typedef struct
{
signed char kernel[5][5];
unsigned int div;
unsigned char offset;
}S_FILTER;
} S_FILTER;
/**
* CIMAGE
* manages a 8-bit channel image
* Manage an 8-bit channel image.
*/
class CIMAGE
{
public:
/**
* Constructor CIMAGE
* constructs a CIMAGE based on image size
* Construct a CIMAGE based on image size.
*
* @param aXsize x size
* @param aYsize y size
*/
CIMAGE( unsigned int aXsize, unsigned int aYsize );
/**
* @brief CIMAGE
* constructs a CIMAGE based on an existent image. It will copy the image to
* the new
* Construct a CIMAGE based from an existing image.
*
* It will make a copy the \a aSrcImage.
*
* @param aSrcImage
*/
CIMAGE( const CIMAGE &aSrcImage );
@ -110,9 +109,9 @@ public:
~CIMAGE();
/**
* Function Setpixel
* set a value in a pixel position, position is clamped in accord with the
* current clamp settings
* Set a value in a pixel position, position is clamped in accordance with the
* current clamp settings.
*
* @param aX x position
* @param aY y position
* @param aValue value to set the pixel
@ -120,9 +119,9 @@ public:
void Setpixel( int aX, int aY, unsigned char aValue );
/**
* Function Getpixel
* get the pixel value from pixel position, position is clamped in accord with the
* current clamp settings
* Get the pixel value from pixel position, position is clamped in accord with the
* current clamp settings.
*
* @param aX x position
* @param aY y position
* @return unsigned char - pixel value
@ -130,98 +129,92 @@ public:
unsigned char Getpixel( int aX, int aY ) const;
/**
* @brief hline - Draws an horizontal line
* @param aXStart - x start position
* @param aXEnd - x end position
* @param aY - y positoin
* @param aValue - value to add
* Draw a horizontal line.
*
* @param aXStart x start position
* @param aXEnd x end position
* @param aY y position
* @param aValue value to add
*/
void Hline( int aXStart, int aXEnd, int aY, unsigned char aValue );
/**
* @brief CircleFilled
* @param aCx
* @param aCy
* @param aRadius
* @param aValue
*/
void CircleFilled( int aCx, int aCy, int aRadius, unsigned char aValue );
/**
* Function CopyFull
* perform a copy operation, based on operation type.
* The result destination is the self image class
* @param aImgA an image input
* @param aImgB an image input
* Perform a copy operation based on \a aOperation type.
*
* The available image operations.
* - IMAGE_OP::RAW this <- aImgA
* - IMAGE_OP::ADD this <- CLAMP(aImgA + aImgB)
* - IMAGE_OP::SUB this <- CLAMP(aImgA - aImgB)
* - IMAGE_OP::DIF this <- abs(aImgA - aImgB)
* - IMAGE_OP::MUL this <- aImgA * aImgB
* - IMAGE_OP::AND this <- aImgA & aImgB
* - IMAGE_OP::OR this <- aImgA | aImgB
* - IMAGE_OP::XOR this <- aImgA ^ aImgB
* - IMAGE_OP::BLEND50 this <- (aImgA + aImgB) / 2
* - IMAGE_OP::MIN this <- (aImgA < aImgB) ? aImgA : aImgB
* - IMAGE_OP::MAX this <- (aImgA > aImgB) ? aImgA : aImgB
*
* @param aImgA an image input.
* @param aImgB an image input.
* @param aOperation operation to perform
* IMAGE_OP::RAW this <- aImgA
* IMAGE_OP::ADD this <- CLAMP(aImgA + aImgB)
* IMAGE_OP::SUB this <- CLAMP(aImgA - aImgB)
* IMAGE_OP::DIF this <- abs(aImgA - aImgB)
* IMAGE_OP::MUL this <- aImgA * aImgB
* IMAGE_OP::AND this <- aImgA & aImgB
* IMAGE_OP::OR this <- aImgA | aImgB
* IMAGE_OP::XOR this <- aImgA ^ aImgB
* IMAGE_OP::BLEND50 this <- (aImgA + aImgB) / 2
* IMAGE_OP::MIN this <- (aImgA < aImgB)?aImgA:aImgB
* IMAGE_OP::MAX this <- (aImgA > aImgB)?aImgA:aImgB
*/
void CopyFull( const CIMAGE* aImgA, const CIMAGE* aImgB, IMAGE_OP aOperation );
/**
* Function Invert
* invert the values of image this <- (255 - this)
* Invert the values of this image <- (255 - this)
*/
void Invert();
/**
* Function EfxFilter
* apply a filter to the input image and stores it in the image class
* this <- FilterType(aInImg)
* Apply a filter to the input image and store it in the image class.
*
* @param aInImg input image
* @param aFilterType filter type to apply
*/
void EfxFilter( CIMAGE* aInImg, IMAGE_FILTER aFilterType );
/**
* Function SaveAsPNG
* save image buffer to a PNG file into the working folder.
* each of RGB channel will have the 8bit-channel from the image.
* @param aFileName fime name (without extension)
* Save image buffer to a PNG file into the working folder.
*
* Each RGB channel will have the 8bit-channel from the image.
*
* @param aFileName file name (without extension)
*/
void SaveAsPNG( const wxString& aFileName ) const;
/**
* Function SetPixelsFromNormalizedFloat
* set the current channel from a float normalized (0.0 - 1.0) buffer
* Set the current channel from a float normalized (0.0 - 1.0) buffer.
*
* this <- CLAMP(NormalizedFloat * 255)
*
* @param aNormalizedFloatArray a float array with the same size of the image
*/
void SetPixelsFromNormalizedFloat( const float * aNormalizedFloatArray );
void SetPixelsFromNormalizedFloat( const float* aNormalizedFloatArray );
/**
* Function GetBuffer
* get the image buffer pointer
* @return unsigned char * - the pointer of the buffer 8bit channel
* Get the image buffer pointer.
*
* @return unsigned char* the pointer of the buffer 8bit channel.
*/
unsigned char* GetBuffer() const;
unsigned int GetWidth() const { return m_width; }
unsigned int GetHeight() const { return m_height; }
private:
private:
/**
* Function wrapCoords
* calculate the coordinates points in accord with the current clamping settings
* @param aXo X coordinate to be converted (output)
* @param aXo Y coordinate to be converted (output)
* @return bool - true if the coordinates are inside the image, false otherwise
* Calculate the coordinates points in accord with the current clamping settings.
*
* @param aXo X coordinate to be converted (output).
* @param aXo Y coordinate to be converted (output).
* @return bool - true if the coordinates are inside the image, false otherwise.
*/
bool wrapCoords( int *aXo, int *aYo ) const;
void plot8CircleLines( int aCx, int aCy, int aX, int aY, unsigned char aValue );
private:
unsigned char* m_pixels; ///< buffer to store the image 8bit-channel
unsigned int m_width; ///< width of the image
unsigned int m_height; ///< height of the image

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -75,17 +75,13 @@ void CPOSTSHADER::UpdateSize( const SFVEC2UI &aSize )
}
void CPOSTSHADER::SetPixelData( unsigned int x,
unsigned int y,
const SFVEC3F &aNormal,
const SFVEC3F &aColor,
const SFVEC3F &aHitPosition,
float aDepth,
float aShadowAttFactor )
void CPOSTSHADER::SetPixelData( unsigned int x, unsigned int y, const SFVEC3F &aNormal,
const SFVEC3F &aColor, const SFVEC3F &aHitPosition,
float aDepth, float aShadowAttFactor )
{
wxASSERT( x < m_size.x );
wxASSERT( y < m_size.y );
wxASSERT( (aShadowAttFactor >= 0.0f) && (aShadowAttFactor <= 1.0f) );
wxASSERT( ( aShadowAttFactor >= 0.0f ) && ( aShadowAttFactor <= 1.0f ) );
const unsigned int idx = x + y * m_size.x;
@ -109,11 +105,16 @@ void CPOSTSHADER::SetPixelData( unsigned int x,
void CPOSTSHADER::destroy_buffers()
{
delete[] m_normals; m_normals = nullptr;
delete[] m_color; m_color = nullptr;
delete[] m_depth; m_depth = nullptr;
delete[] m_shadow_att_factor; m_shadow_att_factor = nullptr;
delete[] m_wc_hitposition; m_wc_hitposition = nullptr;
delete[] m_normals;
m_normals = nullptr;
delete[] m_color;
m_color = nullptr;
delete[] m_depth;
m_depth = nullptr;
delete[] m_shadow_att_factor;
m_shadow_att_factor = nullptr;
delete[] m_wc_hitposition;
m_wc_hitposition = nullptr;
}
@ -195,7 +196,6 @@ void CPOSTSHADER::DebugBuffersOutputAsImages() const
DBG_SaveNormalsBuffer( "m_normals", m_normals, m_size.x, m_size.y );
// Normalize depth
// /////////////////////////////////////////////////////////////////////////
float *normalizedDepth = (float*) malloc( m_size.x * m_size.y * sizeof( float ) );
float *normalizedDepthPTr = normalizedDepth;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -41,11 +41,13 @@ public:
virtual SFVEC3F Shade( const SFVEC2I &aShaderPos ) const = 0;
/**
* @brief ApplyShadeColor - apply the final color process using a previous stage color
* @param aShadeColor - The result of the shader
* Apply the final color process using a previous stage color.
*
* @param aShadeColor The result of the shader.
* @return the result of the shade process
*/
virtual SFVEC3F ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor, const SFVEC3F &aShadeColor ) const = 0;
virtual SFVEC3F ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor,
const SFVEC3F &aShadeColor ) const = 0;
void UpdateSize( const SFVEC2UI &aSize );
@ -53,37 +55,14 @@ public:
void InitFrame() { m_tmin = FLT_MAX; m_tmax = 0.0f; }
void SetPixelData( unsigned int x,
unsigned int y,
const SFVEC3F &aNormal,
const SFVEC3F &aColor,
const SFVEC3F &aHitPosition,
float aDepth,
float aShadowAttFactor );
void SetPixelData( unsigned int x, unsigned int y, const SFVEC3F &aNormal,
const SFVEC3F &aColor, const SFVEC3F &aHitPosition,
float aDepth, float aShadowAttFactor );
const SFVEC3F &GetColorAtNotProtected( const SFVEC2I &aPos ) const;
void DebugBuffersOutputAsImages() const;
protected:
const SFVEC3F &GetNormalAt( const SFVEC2F &aPos ) const;
const SFVEC3F &GetColorAt( const SFVEC2F &aPos ) const;
const SFVEC3F &GetPositionAt( const SFVEC2F &aPos ) const;
float GetDepthAt( const SFVEC2F &aPos ) const;
const SFVEC3F &GetNormalAt( const SFVEC2I &aPos ) const;
const SFVEC3F &GetColorAt( const SFVEC2I &aPos ) const;
const SFVEC3F &GetPositionAt( const SFVEC2I &aPos ) const;
const float &GetShadowFactorAt( const SFVEC2I &aPos ) const;
float GetDepthAt( const SFVEC2I &aPos ) const;
float GetDepthNormalizedAt( const SFVEC2I &aPos ) const;
float GetMaxDepth() const { return m_tmax; }
private:
void destroy_buffers();
public:
inline unsigned int GetIndex( const SFVEC2F& aPos ) const
{
SFVEC2F clampPos;
@ -107,6 +86,24 @@ public:
return (unsigned int)( clampPos.x + m_size.x * clampPos.y );
}
protected:
const SFVEC3F &GetNormalAt( const SFVEC2F &aPos ) const;
const SFVEC3F &GetColorAt( const SFVEC2F &aPos ) const;
const SFVEC3F &GetPositionAt( const SFVEC2F &aPos ) const;
float GetDepthAt( const SFVEC2F &aPos ) const;
const SFVEC3F &GetNormalAt( const SFVEC2I &aPos ) const;
const SFVEC3F &GetColorAt( const SFVEC2I &aPos ) const;
const SFVEC3F &GetPositionAt( const SFVEC2I &aPos ) const;
const float &GetShadowFactorAt( const SFVEC2I &aPos ) const;
float GetDepthAt( const SFVEC2I &aPos ) const;
float GetDepthNormalizedAt( const SFVEC2I &aPos ) const;
float GetMaxDepth() const { return m_tmax; }
private:
void destroy_buffers();
protected:
const CCAMERA &m_camera;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -38,19 +38,15 @@ CPOSTSHADER_SSAO::CPOSTSHADER_SSAO( const CCAMERA &aCamera ) :
{
}
// There are differente sources for this shader on the web
// There are different sources for this shader on the web
//https://github.com/scanberg/hbao/blob/master/resources/shaders/ssao_frag.glsl
//http://www.gamedev.net/topic/556187-the-best-ssao-ive-seen/
//http://www.gamedev.net/topic/556187-the-best-ssao-ive-seen/?view=findpost&p=4632208
float CPOSTSHADER_SSAO::aoFF( const SFVEC2I &aShaderPos,
const SFVEC3F &ddiff,
const SFVEC3F &cnorm,
const float aShadowAtSamplePos,
const float aShadowAtCenterPos,
int c1,
int c2 ) const
float CPOSTSHADER_SSAO::aoFF( const SFVEC2I &aShaderPos, const SFVEC3F &ddiff,
const SFVEC3F &cnorm, const float aShadowAtSamplePos,
const float aShadowAtCenterPos, int c1, int c2 ) const
{
const float shadowGain = 0.60f;
const float aoGain = 1.0f;
@ -81,27 +77,28 @@ float CPOSTSHADER_SSAO::aoFF( const SFVEC2I &aShaderPos,
float sampledNormalFactor = glm::max( glm::dot( GetNormalAt( vr ), cnorm ), 0.0f );
sampledNormalFactor = glm::max( 1.0f - sampledNormalFactor * sampledNormalFactor, 0.0f );
sampledNormalFactor = glm::max( 1.0f - sampledNormalFactor *
sampledNormalFactor, 0.0f );
const float shadowAttDistFactor = glm::max( glm::min( rd * 5.0f - 0.25f, 1.0f ), 0.0f );
float shadowAttFactor = glm::min( sampledNormalFactor + shadowAttDistFactor, 1.0f );
const float shadowFactor = glm::mix( shadow_factor_at_sample,
shadow_factor_at_center,
const float shadowFactor = glm::mix( shadow_factor_at_sample, shadow_factor_at_center,
shadowAttFactor );
// This is a dot product threshold factor.
// it defines after wich angle we consider that the point starts to occlude.
// it defines after which angle we consider that the point starts to occlude.
// if the value is high, it will discard low angles point
const float aDotThreshold = 0.15f;
// This is the dot product between the center pixel normal (the one that is being shaded)
// and the vector from the center to the sampled point
// This is the dot product between the center pixel normal (the one that is being
// shaded) and the vector from the center to the sampled point
const float localNormalFactor = glm::dot( cnorm, vv );
const float localNormalFactorWithThreshold = (glm::max( localNormalFactor, aDotThreshold ) - aDotThreshold) /
(1.0f - aDotThreshold);
const float localNormalFactorWithThreshold =
( glm::max( localNormalFactor, aDotThreshold ) - aDotThreshold) /
( 1.0f - aDotThreshold );
const float aoFactor = localNormalFactorWithThreshold * aoGain * attDistFactor;
@ -113,16 +110,10 @@ float CPOSTSHADER_SSAO::aoFF( const SFVEC2I &aShaderPos,
}
float CPOSTSHADER_SSAO::giFF( const SFVEC2I &aShaderPos,
const SFVEC3F &ddiff,
const SFVEC3F &cnorm,
const float aShadow,
int c1,
int c2 ) const
float CPOSTSHADER_SSAO::giFF( const SFVEC2I &aShaderPos, const SFVEC3F &ddiff,
const SFVEC3F &cnorm, const float aShadow, int c1, int c2 ) const
{
if( (ddiff.x > FLT_EPSILON) ||
(ddiff.y > FLT_EPSILON) ||
(ddiff.z > FLT_EPSILON) )
if( ( ddiff.x > FLT_EPSILON ) || ( ddiff.y > FLT_EPSILON ) || ( ddiff.z > FLT_EPSILON ) )
{
const SFVEC3F vv = glm::normalize( ddiff );
const float rd = glm::length( ddiff );
@ -131,7 +122,8 @@ float CPOSTSHADER_SSAO::giFF( const SFVEC2I &aShaderPos,
const float attDistFactor = 1.0f / ( rd * rd + 1.0f );
return ( glm::clamp( glm::dot( GetNormalAt( vr ), -vv), 0.0f, 1.0f ) *
glm::clamp( glm::dot( cnorm, vv ), 0.0f, 1.0f ) * attDistFactor ) * ( 0.03f + aShadow ) * 3.0f;
glm::clamp( glm::dot( cnorm, vv ), 0.0f, 1.0f ) * attDistFactor ) *
( 0.03f + aShadow ) * 3.0f;
}
return 0.0f;
@ -146,7 +138,7 @@ SFVEC3F CPOSTSHADER_SSAO::Shade( const SFVEC2I &aShaderPos ) const
{
cdepth = ( 30.0f / ( cdepth * 2.0f + 1.0f ) );
// read current normal,position and color.
// read current normal, position and color.
const SFVEC3F n = GetNormalAt( aShaderPos );
const SFVEC3F p = GetPositionAt( aShaderPos );
@ -229,17 +221,19 @@ SFVEC3F CPOSTSHADER_SSAO::Shade( const SFVEC2I &aShaderPos ) const
return glm::mix( SFVEC3F( ao ), -gi, giL );
}
else
return SFVEC3F(0.0f);
{
return SFVEC3F( 0.0f );
}
}
SFVEC3F CPOSTSHADER_SSAO::ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor, const SFVEC3F &aShadeColor ) const
SFVEC3F CPOSTSHADER_SSAO::ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor,
const SFVEC3F &aShadeColor ) const
{
SFVEC3F outColor;
const SFVEC3F subtracted = aInputColor - aShadeColor;
const SFVEC3F mixed = glm::mix( aInputColor,
aInputColor * 0.50f - aShadeColor * 0.05f,
const SFVEC3F mixed = glm::mix( aInputColor, aInputColor * 0.50f - aShadeColor * 0.05f,
glm::min( aShadeColor, 1.0f ) );
outColor.r = ( aShadeColor.r < 0.0f ) ? subtracted.r : mixed.r;
@ -252,15 +246,16 @@ SFVEC3F CPOSTSHADER_SSAO::ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVE
SFVEC3F CPOSTSHADER_SSAO::giColorCurve( const SFVEC3F &aColor ) const
{
const SFVEC3F vec1 = SFVEC3F(1.0f);
const SFVEC3F vec1 = SFVEC3F( 1.0f );
// This option actually apply a gama since we are using linear color space
// This option actually apply a gamma since we are using linear color space
// and the result shader will be applied after convert back to sRGB
// http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtKDEuMC8oeCo5LjArMS4wKSkreCowLjEiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC4wNjIxODQ2MTUzODQ2MTU1MDUiLCIxLjE0Mjk4NDYxNTM4NDYxNDYiLCItMC4xMjcwOTk5OTk5OTk5OTk3NyIsIjEuMTMyNiJdfV0-
return vec1 - ( vec1 / (aColor * SFVEC3F(9.0f) + vec1) ) + aColor * SFVEC3F(0.10f);
}
SFVEC3F CPOSTSHADER_SSAO::Blur( const SFVEC2I& aShaderPos ) const
{
const float dCenter = GetDepthAt( aShaderPos );
@ -283,8 +278,8 @@ SFVEC3F CPOSTSHADER_SSAO::Blur( const SFVEC2I& aShaderPos ) const
const float d = GetDepthAt( SFVEC2I( aShaderPos.x + x, aShaderPos.y + y ) );
const float depthAtt = ( dCenter - d ) * dCenter
* 25.0f; // increse the value will get more sharpness effect
// Increasing the value will get more sharpness effect.
const float depthAtt = ( dCenter - d ) * dCenter * 25.0f;
const float depthAttSqr = depthAtt * depthAtt;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -34,15 +34,14 @@
#include "cpostshader.h"
class CPOSTSHADER_SSAO : public CPOSTSHADER
class CPOSTSHADER_SSAO : public CPOSTSHADER
{
public:
explicit CPOSTSHADER_SSAO( const CCAMERA &aCamera );
//~CPOSTSHADER_SSAO();
// Imported from CPOSTSHADER
SFVEC3F Shade(const SFVEC2I &aShaderPos ) const override;
SFVEC3F ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor, const SFVEC3F &aShadeColor ) const override;
SFVEC3F ApplyShadeColor( const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor,
const SFVEC3F &aShadeColor ) const override;
SFVEC3F Blur( const SFVEC2I& aShaderPos ) const;
@ -57,31 +56,25 @@ public:
}
private:
SFVEC3F posFromDepth( const SFVEC2F &coord ) const;
SFVEC3F posFromDepth( const SFVEC2F& coord ) const;
float ec_depth( const SFVEC2F &tc ) const;
float ec_depth( const SFVEC2F& tc ) const;
float aoFF( const SFVEC2I &aShaderPos,
const SFVEC3F &ddiff,
const SFVEC3F &cnorm,
const float aShadowAtSamplePos,
const float aShadowAtCenterPos,
int c1,
int c2 ) const;
float aoFF( const SFVEC2I& aShaderPos, const SFVEC3F& ddiff, const SFVEC3F& cnorm,
const float aShadowAtSamplePos, const float aShadowAtCenterPos,
int c1, int c2 ) const;
float giFF( const SFVEC2I &aShaderPos,
const SFVEC3F &ddiff,
const SFVEC3F &cnorm,
const float aShadow,
int c1,
int c2 ) const;
float giFF( const SFVEC2I& aShaderPos, const SFVEC3F& ddiff, const SFVEC3F& cnorm,
const float aShadow, int c1, int c2 ) const;
/**
* @brief giColorCurve - Apply a curve transformation to the original color
* it will atenuate the bright colors (works as a gamma function):
* Apply a curve transformation to the original color.
*
* It will attenuate the bright colors (works as a gamma function):
* http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtKDEvKHgqMS4wKzEuMCkpK3gqMC4zMCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0wLjA2MjE4NDYxNTM4NDYxNTUwNSIsIjEuMTQyOTg0NjE1Mzg0NjE0NiIsIi0wLjEyNzA5OTk5OTk5OTk5OTc3IiwiMS4xMzI2Il19XQ--
* @param aColor input color
* @return transformated color
*
* @param aColor input color.
* @return transformed color.
*/
SFVEC3F giColorCurve( const SFVEC3F &aColor ) const;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -48,7 +48,7 @@ CTRACK_BALL::CTRACK_BALL( float aRangeScale ) : CCAMERA( aRangeScale )
}
void CTRACK_BALL::Drag( const wxPoint &aNewMousePosition )
void CTRACK_BALL::Drag( const wxPoint& aNewMousePosition )
{
m_parametersChanged = true;
@ -58,11 +58,10 @@ void CTRACK_BALL::Drag( const wxPoint &aNewMousePosition )
// the mouse, scaled so they are from (-1.0 ... 1.0)."
const float zoom = 1.0f;
trackball( spin_quat,
zoom * (2.0 * m_lastPosition.x - m_windowSize.x) / m_windowSize.x,
zoom * (m_windowSize.y - 2.0 * m_lastPosition.y) / m_windowSize.y,
zoom * (2.0 * aNewMousePosition.x - m_windowSize.x) / m_windowSize.x,
zoom * ( m_windowSize.y - 2.0 * aNewMousePosition.y ) / m_windowSize.y);
trackball( spin_quat, zoom * ( 2.0 * m_lastPosition.x - m_windowSize.x ) / m_windowSize.x,
zoom * ( m_windowSize.y - 2.0 * m_lastPosition.y ) / m_windowSize.y,
zoom * ( 2.0 * aNewMousePosition.x - m_windowSize.x ) / m_windowSize.x,
zoom * ( m_windowSize.y - 2.0 * aNewMousePosition.y ) / m_windowSize.y );
add_quats( spin_quat, m_quat, m_quat );
@ -78,7 +77,7 @@ void CTRACK_BALL::Drag( const wxPoint &aNewMousePosition )
}
void CTRACK_BALL::SetLookAtPos( const SFVEC3F &aLookAtPos )
void CTRACK_BALL::SetLookAtPos( const SFVEC3F& aLookAtPos )
{
if( m_lookat_pos != aLookAtPos )
{
@ -92,13 +91,13 @@ void CTRACK_BALL::SetLookAtPos( const SFVEC3F &aLookAtPos )
}
void CTRACK_BALL::Pan( const wxPoint &aNewMousePosition )
void CTRACK_BALL::Pan( const wxPoint& aNewMousePosition )
{
m_parametersChanged = true;
if( m_projectionType == PROJECTION_TYPE::ORTHO )
{
// With the ortographic projection, there is just a zoom factor
// With the orthographic projection, there is just a zoom factor
const float panFactor = m_zoom / 37.5f; // Magic number from CCAMERA::rebuildProjection
m_camera_pos.x -= panFactor * ( m_lastPosition.x - aNewMousePosition.x );
m_camera_pos.y -= panFactor * ( aNewMousePosition.y - m_lastPosition.y );
@ -107,7 +106,8 @@ void CTRACK_BALL::Pan( const wxPoint &aNewMousePosition )
{
// Unproject the coordinates using the precomputed frustum tangent (zoom level dependent)
const float panFactor = -m_camera_pos.z * m_frustum.tang * 2;
m_camera_pos.x -= panFactor * m_frustum.ratio * ( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x;
m_camera_pos.x -= panFactor * m_frustum.ratio *
( m_lastPosition.x - aNewMousePosition.x ) / m_windowSize.x;
m_camera_pos.y -= panFactor * ( aNewMousePosition.y - m_lastPosition.y ) / m_windowSize.y;
}
@ -116,7 +116,7 @@ void CTRACK_BALL::Pan( const wxPoint &aNewMousePosition )
}
void CTRACK_BALL::Pan( const SFVEC3F &aDeltaOffsetInc )
void CTRACK_BALL::Pan( const SFVEC3F& aDeltaOffsetInc )
{
m_parametersChanged = true;
@ -127,7 +127,7 @@ void CTRACK_BALL::Pan( const SFVEC3F &aDeltaOffsetInc )
}
void CTRACK_BALL::Pan_T1( const SFVEC3F &aDeltaOffsetInc )
void CTRACK_BALL::Pan_T1( const SFVEC3F& aDeltaOffsetInc )
{
m_camera_pos_t1 = m_camera_pos + aDeltaOffsetInc;
}
@ -165,7 +165,7 @@ void CTRACK_BALL::Interpolate( float t )
wxASSERT( t >= 0.0f );
// Limit t o 1.0
t = (t > 1.0f)?1.0f:t;
t = ( t > 1.0f ) ? 1.0f : t;
switch( m_interpolation_mode )
{

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -35,24 +35,22 @@
class CTRACK_BALL : public CCAMERA
{
public:
public:
explicit CTRACK_BALL( float aRangeScale );
virtual ~CTRACK_BALL()
{
}
void Drag( const wxPoint &aNewMousePosition ) override;
void Drag( const wxPoint& aNewMousePosition ) override;
void Pan( const wxPoint &aNewMousePosition ) override;
void Pan( const wxPoint& aNewMousePosition ) override;
void Pan( const SFVEC3F &aDeltaOffsetInc ) override;
void Pan( const SFVEC3F& aDeltaOffsetInc ) override;
void Pan_T1( const SFVEC3F &aDeltaOffsetInc ) override;
void Pan_T1( const SFVEC3F& aDeltaOffsetInc ) override;
void SetLookAtPos( const SFVEC3F &aLookAtPos ) override;
void SetLookAtPos( const SFVEC3F& aLookAtPos ) override;
void Reset() override;
@ -62,8 +60,7 @@ class CTRACK_BALL : public CCAMERA
void Interpolate( float t ) override;
private:
private:
/**
* quarternion of the trackball
*/

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -28,13 +28,13 @@
* @brief it run only once and only in debug build
*/
#include <wx/debug.h>
#include "3d_render_raytracing/shapes3D/cbbox.h"
#include "3d_render_raytracing/cfrustum.h"
#include "3d_render_raytracing/shapes2D/cbbox2d.h"
#include "3d_render_raytracing/shapes2D/cfilledcircle2d.h"
#include "3d_render_raytracing/shapes2D/croundsegment2d.h"
#include "3d_render_raytracing/shapes2D/cpolygon2d.h"
#include "3d_render_raytracing/cfrustum.h"
#include "3d_render_raytracing/shapes2D/croundsegment2d.h"
#include "3d_render_raytracing/shapes3D/cbbox.h"
#include <wx/debug.h>
//#ifdef DEBUG
#if 0
@ -42,13 +42,12 @@ static bool s_Run_Test_Cases = true;
void Run_3d_viewer_test_cases()
{
if( s_Run_Test_Cases == false)
if( s_Run_Test_Cases == false )
return;
s_Run_Test_Cases = true;
// Test CBBOX2D
// /////////////////////////////////////////////////////////////////////////
CBBOX2D bbox2d_A;
CBBOX2D bbox2d_B;
@ -66,7 +65,7 @@ void Run_3d_viewer_test_cases()
wxASSERT( bbox2d_A.MaxDimension() == 0 );
wxASSERT( bbox2d_A.Perimeter() == 0.0f );
*/
bbox2d_A.Set( SFVEC2F(1.0f, -1.0f), SFVEC2F(-1.0f, 1.0f) );
bbox2d_A.Set( SFVEC2F( 1.0f, -1.0f ), SFVEC2F( -1.0f, 1.0f ) );
wxASSERT( bbox2d_A.IsInitialized() == true );
wxASSERT( bbox2d_A.Area() == 4.0f );
@ -120,24 +119,21 @@ void Run_3d_viewer_test_cases()
wxASSERT( bbox2d_A.MaxDimension() == 0 );
wxASSERT( bbox2d_A.Perimeter() == 20.0f );
bbox2d_A.Set( SFVEC2F(-1.0f, -1.0f), SFVEC2F(1.0f, 1.0f) );
bbox2d_B.Set( SFVEC2F(-2.0f, -2.0f), SFVEC2F(2.0f, 2.0f) );
wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == true );
wxASSERT( bbox2d_B.Intersects( bbox2d_A ) == true );
bbox2d_A.Set( SFVEC2F( -1.0f, -1.0f ), SFVEC2F( 1.0f, 1.0f ) );
bbox2d_B.Set( SFVEC2F( -2.0f, -2.0f ), SFVEC2F( 2.0f, 2.0f ) );
wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == true );
wxASSERT( bbox2d_B.Intersects( bbox2d_A ) == true );
bbox2d_B.Set( SFVEC2F( 1.0f, 1.0f), SFVEC2F(1.0f, 1.0f) );
wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == true );
bbox2d_B.Set( SFVEC2F( 1.0f, 1.0f ), SFVEC2F( 1.0f, 1.0f ) );
wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == true );
bbox2d_B.Set( SFVEC2F( 1.1f, 1.1f), SFVEC2F(2.0f, 2.0f) );
bbox2d_B.Set( SFVEC2F( 1.1f, 1.1f ), SFVEC2F( 2.0f, 2.0f ) );
wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == false );
bbox2d_B.Set( SFVEC2F(-0.5f, -0.5f), SFVEC2F(0.5f, 0.5f) );
wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == true );
bbox2d_B.Set( SFVEC2F(-0.5f, -0.5f ), SFVEC2F( 0.5f, 0.5f ) );
wxASSERT( bbox2d_A.Intersects( bbox2d_B ) == true );
// Test CFILLEDCIRCLE2D
// /////////////////////////////////////////////////////////////////////////
CFILLEDCIRCLE2D filledCircle2d( SFVEC2F( 2.0f, 2.0f ), 1.0f );
wxASSERT( filledCircle2d.IsPointInside( SFVEC2F( 2.0f, 2.0f ) ) == true );
@ -151,39 +147,37 @@ void Run_3d_viewer_test_cases()
wxASSERT( filledCircle2d.IsPointInside( SFVEC2F( 2.6f, 2.6f ) ) == true );
wxASSERT( filledCircle2d.IsPointInside( SFVEC2F( 1.2f, 1.2f ) ) == false );
bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f), SFVEC2F( 4.0f, 4.0f) );
bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f ), SFVEC2F( 4.0f, 4.0f ) );
wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true );
bbox2d_B.Set( SFVEC2F( 1.5f, 1.5f), SFVEC2F( 2.5f, 2.5f) );
bbox2d_B.Set( SFVEC2F( 1.5f, 1.5f ), SFVEC2F( 2.5f, 2.5f ) );
wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true );
// A box that does not intersect the sphere but still intersect the bbox of the sphere
bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f), SFVEC2F( 1.2f, 1.2f) );
bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f ), SFVEC2F( 1.2f, 1.2f ) );
wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == false );
bbox2d_B.Set( SFVEC2F(-1.0f, -1.0f), SFVEC2F( 0.5f, 0.5f) );
bbox2d_B.Set( SFVEC2F(-1.0f, -1.0f ), SFVEC2F( 0.5f, 0.5f ) );
wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == false );
bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f), SFVEC2F( 2.0f, 2.0f) );
bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f ), SFVEC2F( 2.0f, 2.0f ) );
wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true );
bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f), SFVEC2F( 2.0f, 4.0f) );
bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f ), SFVEC2F( 2.0f, 4.0f ) );
wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true );
bbox2d_B.Set( SFVEC2F( 2.0f, 0.0f), SFVEC2F( 4.0f, 4.0f) );
bbox2d_B.Set( SFVEC2F( 2.0f, 0.0f ), SFVEC2F( 4.0f, 4.0f ) );
wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true );
bbox2d_B.Set( SFVEC2F( 0.0f, 2.0f), SFVEC2F( 4.0f, 4.0f) );
bbox2d_B.Set( SFVEC2F( 0.0f, 2.0f ), SFVEC2F( 4.0f, 4.0f ) );
wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true );
bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f), SFVEC2F( 4.0f, 2.0f) );
bbox2d_B.Set( SFVEC2F( 0.0f, 0.0f ), SFVEC2F( 4.0f, 2.0f ) );
wxASSERT( filledCircle2d.Intersects( bbox2d_B ) == true );
// Test CROUNDSEGMENT2D
// /////////////////////////////////////////////////////////////////////////
CROUNDSEGMENT2D roundSegment2d( SFVEC2F(-1.0f, 0.0f), SFVEC2F( 1.0f, 0.0f), 2.0f);
CROUNDSEGMENT2D roundSegment2d( SFVEC2F( -1.0f, 0.0f ), SFVEC2F( 1.0f, 0.0f ), 2.0f );
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( 0.0f, 0.0f ) ) == true );
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( 1.0f, 0.0f ) ) == true );
@ -200,52 +194,50 @@ void Run_3d_viewer_test_cases()
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( 1.8f, 0.8f ) ) == false );
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( 1.8f,-0.8f ) ) == false );
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F(-1.8f, 0.8f ) ) == false );
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F(-1.8f,-0.8f ) ) == false );
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( -1.8f, 0.8f ) ) == false );
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( -1.8f,-0.8f ) ) == false );
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( 1.6f, 0.6f ) ) == true );
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( 1.6f,-0.6f ) ) == true );
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F(-1.6f, 0.6f ) ) == true );
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F(-1.6f,-0.6f ) ) == true );
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( -1.6f, 0.6f ) ) == true );
wxASSERT( roundSegment2d.IsPointInside( SFVEC2F( -1.6f,-0.6f ) ) == true );
bbox2d_A.Set( SFVEC2F(-2.0f,-1.0f), SFVEC2F( 2.0f, 1.0f) );
wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == true );
bbox2d_A.Set( SFVEC2F(-2.1f,-1.1f), SFVEC2F( 2.1f, 1.1f) );
bbox2d_A.Set( SFVEC2F(-2.1f,-1.1f ), SFVEC2F( 2.1f, 1.1f ) );
wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == true );
bbox2d_A.Set( SFVEC2F(-1.9f,-0.9f), SFVEC2F( 1.9f, 0.9f) );
bbox2d_A.Set( SFVEC2F( -1.9f,-0.9f ), SFVEC2F( 1.9f, 0.9f ) );
wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == true );
bbox2d_A.Set( SFVEC2F(-1.0f,-1.0f), SFVEC2F( 1.0f, 1.0f) );
bbox2d_A.Set( SFVEC2F( -1.0f,-1.0f ), SFVEC2F( 1.0f, 1.0f ) );
wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == true );
bbox2d_A.Set( SFVEC2F(-1.0f,-0.5f), SFVEC2F( 1.0f, 0.5f) );
bbox2d_A.Set( SFVEC2F( -1.0f,-0.5f ), SFVEC2F( 1.0f, 0.5f ) );
wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == true );
bbox2d_A.Set( SFVEC2F(-4.0f,-0.5f), SFVEC2F(-3.0f, 0.5f) );
bbox2d_A.Set( SFVEC2F( -4.0f,-0.5f ), SFVEC2F( -3.0f, 0.5f ) );
wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == false );
bbox2d_A.Set( SFVEC2F( 1.8f, 0.8f), SFVEC2F( 2.0f, 1.0f) );
bbox2d_A.Set( SFVEC2F( 1.8f, 0.8f ), SFVEC2F( 2.0f, 1.0f ) );
wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == false );
bbox2d_A.Set( SFVEC2F(-2.0f, 0.8f), SFVEC2F(-1.8f, 1.0f) );
bbox2d_A.Set( SFVEC2F( -2.0f, 0.8f ), SFVEC2F( -1.8f, 1.0f ) );
wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == false );
bbox2d_A.Set( SFVEC2F(-2.0f,-1.0f), SFVEC2F(-1.8f,-0.8f) );
bbox2d_A.Set( SFVEC2F( -2.0f, -1.0f ), SFVEC2F( -1.8f, -0.8f ) );
wxASSERT( roundSegment2d.Intersects( bbox2d_A ) == false );
// Test CPOLYGON2D
// /////////////////////////////////////////////////////////////////////////
Polygon2d_TestModule();
#if 0
// Test Frustum
// /////////////////////////////////////////////////////////////////////////
{
CFRUSTUM frustum;
SFVEC3F ori = SFVEC3F(0.0, 0.0, 0.0);
SFVEC3F ori = SFVEC3F( 0.0, 0.0, 0.0 );
float z = 10.0;
/*
@ -296,40 +288,38 @@ void Run_3d_viewer_test_cases()
const RAY bottomLeft( ori, glm::normalize( ori - SFVEC3F(+1.0,-1.0, z) ) );
const RAY bottomRight( ori, glm::normalize( ori - SFVEC3F(-1.0,-1.0, z) ) );
frustum.GenerateFrustum( topLeft, topRight, bottomLeft, bottomRight );
CBBOX bbox3d;
bbox3d.Set( SFVEC3F(-1.0f, -1.0f, z), SFVEC3F(+1.0f,+1.0f, z + 1.0f) );
bbox3d.Set( SFVEC3F( -1.0f, -1.0f, z ), SFVEC3F( +1.0f, +1.0f, z + 1.0f ) );
wxASSERT( frustum.Intersect( bbox3d ) == true );
bbox3d.Set( SFVEC3F(-1.0f, -1.0f, z+z), SFVEC3F(+1.0f,+1.0f, z+z + 1.0f) );
bbox3d.Set( SFVEC3F( -1.0f, -1.0f, z + z ), SFVEC3F( +1.0f, +1.0f, z + z + 1.0f ) );
wxASSERT( frustum.Intersect( bbox3d ) == true );
bbox3d.Set( SFVEC3F(-1.0f, -1.0f, 1.0f), SFVEC3F(0.0f,0.0f, 2.0f) );
bbox3d.Set( SFVEC3F( -1.0f, -1.0f, 1.0f ), SFVEC3F( 0.0f, 0.0f, 2.0f ) );
wxASSERT( frustum.Intersect( bbox3d ) == true );
bbox3d.Set( SFVEC3F(-1.0f, -1.0f, -z-1.0f), SFVEC3F(+1.0f,+1.0f, -z) );
bbox3d.Set( SFVEC3F( -1.0f, -1.0f, -z - 1.0f ), SFVEC3F( +1.0f, +1.0f, -z ) );
wxASSERT( frustum.Intersect( bbox3d ) == false );
bbox3d.Set( SFVEC3F(z-1.0f, z-1.0f, 0.0), SFVEC3F(z+1.0f,z+1.0f, 1.0) );
bbox3d.Set( SFVEC3F( z - 1.0f, z - 1.0f, 0.0 ), SFVEC3F( z + 1.0f, z + 1.0f, 1.0 ) );
wxASSERT( frustum.Intersect( bbox3d ) == false );
bbox3d.Set( SFVEC3F(-z, -z, 0.0), SFVEC3F( -1.0f,-1.0f, 1.0f) );
bbox3d.Set( SFVEC3F( -z, -z, 0.0), SFVEC3F( -1.0f, -1.0f, 1.0f ) );
wxASSERT( frustum.Intersect( bbox3d ) == false );
bbox3d.Set( SFVEC3F(-z, -z, -1.0f), SFVEC3F(+z,+z, 1.0f) );
bbox3d.Set( SFVEC3F( -z, -z, -1.0f ), SFVEC3F( +z, +z, 1.0f ) );
wxASSERT( frustum.Intersect( bbox3d ) == true );
bbox3d.Set( SFVEC3F(-z, -z, z-1), SFVEC3F(+z,+z, z+1.0f) );
bbox3d.Set( SFVEC3F( -z, -z, z-1 ), SFVEC3F( +z, +z, z + 1.0f ) );
wxASSERT( frustum.Intersect( bbox3d ) == true );
bbox3d.Set( SFVEC3F( 0.5, 0.5, 0.0), SFVEC3F( 2.0, 2.0, z) );
bbox3d.Set( SFVEC3F( 0.5, 0.5, 0.0 ), SFVEC3F( 2.0, 2.0, z ) );
wxASSERT( frustum.Intersect( bbox3d ) == true );
bbox3d.Set( SFVEC3F( 1.1, 1.0, 0.0), SFVEC3F( 2.0, 2.0, z) );
bbox3d.Set( SFVEC3F( 1.1, 1.0, 0.0 ), SFVEC3F( 2.0, 2.0, z ) );
wxASSERT( frustum.Intersect( bbox3d ) == false );
}
{
@ -337,46 +327,46 @@ void Run_3d_viewer_test_cases()
float z = 10.0;
SFVEC3F ori = SFVEC3F(0.0, 0.0, z);
SFVEC3F ori = SFVEC3F( 0.0, 0.0, z );
const RAY topLeft( ori, glm::normalize( SFVEC3F(-1.0, 1.0, 0.0) - ori ) );
const RAY topRight( ori, glm::normalize( SFVEC3F(+1.0, 1.0, 0.0) - ori ) );
const RAY bottomLeft( ori, glm::normalize( SFVEC3F(-1.0,-1.0, 0.0) - ori ) );
const RAY bottomRight( ori, glm::normalize( SFVEC3F(+1.0,-1.0, 0.0) - ori ) );
const RAY topLeft( ori, glm::normalize( SFVEC3F( -1.0, 1.0, 0.0 ) - ori ) );
const RAY topRight( ori, glm::normalize( SFVEC3F( +1.0, 1.0, 0.0 ) - ori ) );
const RAY bottomLeft( ori, glm::normalize( SFVEC3F( -1.0, -1.0, 0.0 ) - ori ) );
const RAY bottomRight( ori, glm::normalize( SFVEC3F( +1.0, -1.0, 0.0 ) - ori ) );
frustum.GenerateFrustum( topLeft, topRight, bottomLeft, bottomRight );
CBBOX bbox3d;
bbox3d.Set( SFVEC3F(-1.0f, -1.0f, -z), SFVEC3F(+1.0f,+1.0f, -z + 1.0f) );
bbox3d.Set( SFVEC3F( -1.0f, -1.0f, -z), SFVEC3F( +1.0f, +1.0f, -z + 1.0f ) );
wxASSERT( frustum.Intersect( bbox3d ) == true );
bbox3d.Set( SFVEC3F(-1.0f, -1.0f, -(z+z)), SFVEC3F(+1.0f,+1.0f, -(z+z + 1.0f)) );
bbox3d.Set( SFVEC3F( -1.0f, -1.0f, -( z + z ) ), SFVEC3F( +1.0f, +1.0f, -( z + z + 1.0f ) ) );
wxASSERT( frustum.Intersect( bbox3d ) == true );
bbox3d.Set( SFVEC3F(-1.0f, -1.0f, 1.0f), SFVEC3F(0.0f,0.0f, 2.0f) );
bbox3d.Set( SFVEC3F(- 1.0f, -1.0f, 1.0f ), SFVEC3F( 0.0f, 0.0f, 2.0f ) );
wxASSERT( frustum.Intersect( bbox3d ) == true );
// !TODO: The frustum alg is not excluse all the the situations
//bbox3d.Set( SFVEC3F(-1.0f, -1.0f, z+1.0f), SFVEC3F(+1.0f,+1.0f, +z+2.0f) );
//wxASSERT( frustum.Intersect( bbox3d ) == false );
bbox3d.Set( SFVEC3F(z-1.0f, z-1.0f, 0.0), SFVEC3F(z+1.0f,z+1.0f, 1.0) );
bbox3d.Set( SFVEC3F( z - 1.0f, z - 1.0f, 0.0), SFVEC3F( z + 1.0f, z + 1.0f, 1.0 ) );
wxASSERT( frustum.Intersect( bbox3d ) == false );
bbox3d.Set( SFVEC3F(-z, -z, 0.0), SFVEC3F( -1.0f,-1.0f, 1.0f) );
bbox3d.Set( SFVEC3F( -z, -z, 0.0 ), SFVEC3F( -1.0f,-1.0f, 1.0f ) );
wxASSERT( frustum.Intersect( bbox3d ) == false );
bbox3d.Set( SFVEC3F(-z, -z, -1.0f), SFVEC3F(+z,+z, 1.0f) );
bbox3d.Set( SFVEC3F( -z, -z, -1.0f ), SFVEC3F( +z, +z, 1.0f ) );
wxASSERT( frustum.Intersect( bbox3d ) == true );
bbox3d.Set( SFVEC3F(-z, -z, -(z-1)), SFVEC3F(+z,+z, -(z+1.0f)) );
bbox3d.Set( SFVEC3F( -z, -z, -( z - 1 ) ), SFVEC3F( +z, +z, -( z + 1.0f ) ) );
wxASSERT( frustum.Intersect( bbox3d ) == true );
bbox3d.Set( SFVEC3F( 0.5, 0.5, 0.0), SFVEC3F( 2.0, 2.0, z) );
bbox3d.Set( SFVEC3F( 0.5, 0.5, 0.0 ), SFVEC3F( 2.0, 2.0, z ) );
wxASSERT( frustum.Intersect( bbox3d ) == true );
bbox3d.Set( SFVEC3F( 1.1, 1.0, 0.0), SFVEC3F( 2.0, 2.0, z) );
bbox3d.Set( SFVEC3F( 1.1, 1.0, 0.0 ), SFVEC3F( 2.0, 2.0, z ) );
wxASSERT( frustum.Intersect( bbox3d ) == false );
}
#endif